OAUTH2 flow for authentication across clients - web-services

I seem to be royally confused, somehow OAUTH2 or it's newer more stringent subset OpenID Connect just don't click in my head...
My application is a RESTFUL service that has no Web UI whatsoever.
Several clients are using it ( from both web and mobile apps )
My service should store per user data.
Now we want to allow the clients to authenticate via common providers that support OAUTH2 ( e.g facebook,google etc.. )
They should be able to handle the authentication in their application and just give my service an identity token that i can verify as in "Ok this is a valid user token that was signed by a valid authority" and can use to associate the users data on my side with it. ( and return to the clients of course at a later time )
How to achieve this with OAUTH2 ? Which flow to use ?

Identity Token is OIDC (OpenID Connect) thing, OAuth2 is about Authorization. verifying (authenticating) End user Identity is the main objective of OIDC.
In your use case: usually after the end user authenticated by OP (mostly using Implicit flow), client/RP (relaying Party) will receive Identity Token, and Access Token, Identity Token is meant for the client, Access token is the token to be used for requesting your protected REST API.
Example: setRequestHeader("Authorization", "Bearer " + token);
Now your REST API, send the received Bearer/access token (usually JWT format) to OP, if its valid then you apply your permissions/filtration logic.
Maybe this gist will help you understand the use cases of each flow.
Hope its answer your question.

Related

Token exchange flow - how to register and login user

Here is my understanding of the token exchange flow:
First i should follow this section of the docs: https://developers.tapkey.io/api/authentication/identity_providers/
After I created identity provider, I want to register my test user using this endpoint https://developers.tapkey.io/openapi/tapkey_access_management_web_api_v1/#/Identity%20Provider%20Users/OwnerIdentityProviderUsers_Put
First question related to the endpoint above is, how do i authorize this request? On swagger documentation there is only clientCredential and AuthorizationCodeAuth options. Does this mean i need one of this types of authorization, so that i can authorize request from my server (from application point of view, lets say).
For endpoints like:
List all owners
Register user
etc.
Now let's say i registered a user, using client credentials to authorize a request.
I am trying to login, following Token Exchange section in docs.
There it says I need to use this POST https://login.tapkey.com/connect/token, i am formatting the jwt as said in the docs, and sending to this endpoint. I am using client_id from my token exchange oAuth client. I got an error with the following message, which is pretty clear to me, but i can't find the solution for it.
{ error: 'unauthorized_client', error_description: 'Client not authorized' }
Mostly, the listet authentication types in the swagger documents are to be able to test the endpoints within the swagger ui. So it is possible to create a oAuth client, pass it to the swagger ui and test the endpoints.
The endpoints itself do not differ between authentication type.
Depending on the purposes the authentication method should be used.
Authorization Code Flow
If you have a service, which works on behalf of a Tapkey user, the authorization code flow should be used.
E.g. you have a booking platform, and your customer should be able to grant access to locks owned by them.
It is not possible to use the authorization code flow to login into the Tapkey Mobile SDK and unlock locks. An authorization client can not request the therefore required scopes.
Client Credential Flow
For server 2 server communication to manage your services, e.g. for adding identity provider users or managing locks which are owned by your services, then the client credential flow would be a good choice.
For that, the client credential client must be authorized as an administrator to the specific locking system.
Token Exchange Flow
To login your users into your app and using the Tapkey Mobile SDK to unlock locks, you have to sign your own JWT tokens on your server and exchange then on the client with the token exchange flow.
Please be aware: It is not possible to use the authorization code flow to sign in as a Tapkey user and then exchange it via token exchange.

How to implement OAuth when the resource and auth servers are same

I have a Django Rest API with JWT authentication which is the backend for a Angular frontend. There are many clients who use the service with our frontend. Now some enterprise clients wanted to integrate the APIs from their system's backend. I don't want to remove JWT from current APIs. I am planning to create new APIs in the same backend with OAuth token for those users.
I wonder what is the best way to implement OAuth for this scenario.
I am thinking Client Credentials grant type is the best way.
Question1: Am I right that client credentials is the right approach ?
For those enterprise users, it is sufficient they get just access token through the UI interface so that they can access all our APIs.
But here the problem is one additional step of getting the Client ID and Client Secret first and using that to get Access Token.
Question 2: What is the use of client ID and client secret ?
Question3: Should my backend hide the process of generating Client ID and Client secret and just give Access token (or) give them Client ID and Client Secret and ask then to generate access token ?
Question 4: If I am giving them Access Token without client id and secret, is that fine to have infinite expiry time? and
TLDR; How to implement OAuth when the resource server and auth servers are same ?
There are 4 grant types in oAuth2 which is meant for different scenarios.
client credential : the consumer (app) make calls to back-end using the bearer token created using apikey(or clientId) and secret only. Mostly used for anonymous calls where generic information is retrieved.
Resource owner password credential (ROPC) : the consumer (app) make calls using the bearer token created using apikey, secret, username and password. Mostly used when you(your authorization server) already know the users(user database is handled in your own system).
Authorization code : the consumer (app) make calls using the bearer token created using an authorization code. The authorization code is provided by a 3rd party (which actually has/manages the logged in user data) and the created authorization code linked to the logged in user. Google and Facebook log in for various sites is a typical example. Facebook/Google gives an authorization code for those websites and they exchange that code for a token.
Implicit grant : Mix of password credential and authorization code. Instead of authorization code, you get a bearer token from the 3rd party authorization server.
Question1: Am I right that client credentials is the right approach ?
I think you can use CC if there is no user level logics in your backend. If userlevel involved, may be ROPC is a better choice
Question 2: What is the use of client ID and client secret ?
Client ID and Client Secret is very similar to username and password in an application level, which is used to obtain bearer token.
Question3: Should my backend hide the process of generating Client ID and Client secret and just give Access token (or) give them Client ID and Client Secret and ask then to generate access token ?
If you are implementing oAuth2, your consumer should create the access token. But looking at your use case, may be even a simple hash of userId+timestamp is sufficient. ;)
Question1: Am I right that client credentials is the right approach ?
Yes. Providing the new APIs do not need to be called in the context of an end user.
Question 2: What is the use of client ID and client secret ?
The client ID allows the auth server to identify the application
requesting the token (it's often carried through to the access token
too, allowing the API to identify the calling application).
The client Secret means the auth server can trust that the client is
genuinely who he says he is as only he should have the private client
secret for his public client ID.
It's effectively a username and password in this scenario.
Question3: Should my backend hide the process of generating Client ID
and Client secret and just give Access token (or) give them Client ID
and Client Secret and ask then to generate access token ?
Your Auth server should issue the client credentials to the application once and the application should provide those credentials every time they wish to obtain a token via the client credentials grant type.
authorization code grant, or implicit grant might be more suitable for this scenario. The first one allows you to add an authentication step before the tokens are returned to the users (might be useful if you want to integrate your JWT authentication to this as well) and the second one is mainly used for single-page applications, and does not include an intermediate authentication step. This one would be useful if you want to improve efficiency.
client_id and client_secret are given to you when you register a client application in your identity provider(authorization server). This client application does not mean an application or an API belonging to your clients, but your own application to which you plan to incorporate OAuth(and OIDC). These two parameters are useful when making the requests to authorization in order to obtain tokens. The server uses those values to determine whether the request is made by a valid application. Only you have access to those values as you will be the one who's registering the application with the server.
I think this question is answered in the previous section.
I think it would be better if you go through this before doing any implementation. It provides most of the basic knowledge you should have before implementing an OAuth system. I hope this answer was useful to you.

Django Oauth Toolkit Application Settings

Django Oauth Toolkit docs don't describe the redirect uris, authorization grant type, or client type fields when registering your application.
The tutorial says to set client type to confidential, grant type to password, and leave uris blank.
What do the other options do?
e.g. What is client type public vs confidential? What do the grant type password, credentials, authorization, implicit do? And what are the redirect uris for?
I have found sparse information about them but no actual explanations as they pertain to django rest framework and django oauth toolkit.
You'll get answer to all your questions once you read about Oauth2 Protocol from here
But I'll try to answer your questions in brief:
I'll be using the words client and Resource Server frequently. In Oauth2 protocol, client means the system which accesses resources, data or service. (It could be your mobile app or javascript app consuming REST API's of your API Backend (or Resource Server) . If you have implemented Facebook login in your mobile/JS apps, chances are, your API backend requests Facebook for user's information. In that case your API backend is being a client and Facebook is Resource Server)
Client Types:
Client type is either confidential or public depending on whether that client can keep it's client_secret a secret. (For example, an AngularJS app cannot keep it's client_secret hidden, since anyone can do "Inspect Element" in a browser and search for it, so such a client has to be registered as public.)
Authorization Grant Types:
There are four kinds of Authorization Grant Types in Oauth2 protocol.
Authorization Code:
In this grant type, the client requests for an authorization code first, then exchanges that authorization code for an access token. It's a two step procedure. Use this if the client is an outsider (more on it in Resource-owner password based).
Implicit:
Usually used along with public client_type. Instead of a two-step procedure above, the client gets access token in one go.
Resource-owner password based:
This is used when there is a high degree of trust between client and Resource Server. This is the case between your API backend and your Mobile app. (There is high degree of trust between your API backend and Javascript app too, but since it cannot keep it's client_secret a secret, you have to use Implicit Grant type with it). Facebook or Google etc. will never give you this kind of Authorization Grant because, for them, your API backend is an outsider.
Client Credentials:
It is least commonly used. Please read about it in above mentioned document.
Redirect URI's:
Now, as far as Redirect URI's are concerned, they are needed only in Authorization Code or Implicit grant types (Not sure about Client Credentials one, somebody please enlighten me on this in comments).
Redirect URI is given so that the Resource Server knows where to send the access token. Imagine if you are implementing Facebook login. In that case you will go to developers.facebook.com and register your application (like you did with django-oauth-toolkit), while registering your application, you will specify a Redirect URI.
Specifying a Redirect URI is a way of saying. "Hey Facebook, send the access token on this URI". So if you set Redirect URI something like https://your_domain_name.com/token/facebook/, Facebook will redirect to your specified Redirect URI at the end of Oauth2 process and give Access Token in the form of GET parameter, like https://your_domain_name.com/token/facebook/?token=some_long_string&some=other_parameters.

Securing Restful Web Services with OAuth2 with JWT

Hi i am new to Apache cxf rest API security side.I want to rest API which have good security with authorization.I found Apache cxf gives Ouath2 security features(http://cxf.apache.org/docs/jax-rs-oauth2.html).So And i need to use json web token(http://jwt.io/) to send to API for authorization.Simply i need to use secured line for send request to rest API.So far i have simple design.
And my REST api have CRUD Operations to database.I thought send JWT as Access token in request header.And API side verify the user and send data back to user.I have two questions.First one is Is this the best design for this kind of application.And second one is if this is best way how to generate Tokens and is that we need to keep those tokens in server side.
Yes it's a good design
I can explain it with github web api's
Authorize
First u validate urself for using API by sending client id and callback url in request (here u specify access level ie.scope) and u receive a code
Access_token
Then u exchange this code for access token (this time with client secret included in req parameter)
This access token received is used for all future calls made by u on behalf of user
Nd ya u store this token and refresh token at server
https://developer.github.com/v3/oauth/#web-application-flow
Although this is specific to github , similar flow follows for twitter , linked in and slightly different for facebook web api's

Generate an OAuth2 token in a view

Let's say I have an AngularJS application that consumes the REST API of a Django application.
The Django application has got a built-in OAuth2 provider that can be called to retrieve an access token and use the protected endpoints of the API. This provider is using django-oauth-toolkit.
Let's assume there is a registered client with "password" grant type, so that the end users only need to provide their credentials in the front-end in order to get an access token from the back-end.
At some point we want to add some support for social networks login and we decide to use python-social-auth (PSA) to that end. Here is the workflow I want to achieve:
The user logs in on Facebook from the front-end (via the Facebook SDK) and we get an access token back from the OAuth2 provider of Facebook.
We send the Facebook token to an endpoint of our REST API. This endpoint uses the Facebook token and django-social-auth to authenticate the user in our Django application (basically matching a Facebook account to a standard account within the app).
If the authentication succeeds, the API endpoint requests an access token from the OAuth2 provider for this newly authenticated user.
The Django access token is sent back to the front-end and can be used to access the REST API in exactly the same way that a regular user (i.e. logged in with his credentials) would do.
Now my problem is: how do I achieve step 3? I first thought I would register a separate OAuth2 client with Client Credentials Grant but then the generated token is not user-specific so it does not make sense. Another option is to use the TokenAuthentication from DRF but that would add too much complexity to my project. I already have an OAuth server and I don't want to set up a second token provider to circumvent my problem, unless this is the only solution.
I think my understanding of PSA and django-oauth-toolkit is not deep enough to find the best way of reaching my goal, but there must be a way. Help!
I managed to get something working using urllib2. I can't speak towards whether or not this is good practice, but I can successfully generate an OAuth2 token within a view.
Normally when I'd generate an access token with cURL, it'd look like this:
curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://localhost:8000/o/token/
So we're tasked with making urllib2 accomplish this. After playing around for some bit, it is fairly straightforward.
import urllib, urlib2, base64, json
# Housekeeping
token_url = 'http://localhost:8000/auth/token/'
data = urllib.urlencode({'grant_type':'password', 'username':<username>, 'password':<password>})
authentication = base64.b64encode('%s:%s' % (<client_id>, <client_secret>))
# Down to Business
request = urllib2.Request(token_url, data)
request.add_header("Authorization", "Basic %s" % authentication)
access_credentials = urllib2.urlopen(request)
json_credentials = json.load(access_credentials)
I reiterate, I do not know if this is in bad practice and I have not looked into whether or not this causes any issues with Django. AFAIK this will do this trick (as it did for me).