I'm going to make a REST web service with many resource servers (implemented in different programming languages) and one authorization server.
My question is about token validation in the resource servers. Let's say that a resource server cannot connect to the database and check the token info there.
I have read this thread: OAuth v2 communication between authentication and resource server
And I like the idea to make an API in the authorization server, which will be responsible to "resolve" tokens. For example: https://oauth.example.tdl/tokeninfo?token=tokentovalidate
So my question: Should the /tokeninfo resource be "public"? I mean everyone who knows this endpoint will be able to validate tokens..
Wouldn't it be better to make this "private"? I mean https://oauth.example.tdl/tokeninfo?access_token=valid_token&token=tokentovalidate
But then my resource server will have to authorize itself before validating tokens.. too many requests, I think..
If you know more strategies to validate tokens between resource server and authorization server - tell me, because I'm pretty new to OAuth.
Should the token verification API be public?
In terms of authentication, if should of course be an authenticated API, and the access token that you use to call it is the access token you want to verify. RFC 6750 explains how to do that. Typically, the token is sent in the Authorization header, or as a Uri query parameter.
Alternatively, for more security, you require the client id and client secret to secure the call, either by passing them as parameters, either by obtaining an access token for the client using the Client Credentials Grant.
Be careful what information you return from the API. You should only return information that does not require a specific scope that has to be authorized by the resource owner.
For a real life example, see the Google implementation or the implementation from The Identity Hub. For the Facebook implementation, see the section "Confirming identity" on Manually Build a Login Flow.
Related
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.
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 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.
I have an internal-facing RESTful web service. There are various client applications using the service, and the client apps themselves have end users. The web service needs to authorize requests based on the end user identities.
The question: What are the typical options for authenticating the end user here? That is, I want to authenticate the user, not the client application. (I don't mind if authenticating the client application is part of the scheme, but ultimately I need to know that the end user is who I think he or she is.)
One possible scheme, for example, would be to have per-client system accounts, and then have the client simply assert the user's identity (e.g. in an HTTP request header, say). So we authenticate the client application and delegate user authentication to the client. I don't think this is a very strong scheme, though, because it depends too much on keeping the system account credentials secret. I have seen too many examples of people e-mailing system account credentials around to put much faith in this sort of approach.
Another approach might be to have the client app, upon user login, use the user's credentials to get a token from the API, and then use that token for subsequent API requests. That way the authentication is user-specific without requiring the client app to hang onto the username/password credentials.
Anyway I'd like to have a better sense for the range of options I should be considering here.
The problem that you describe with "delegated authentication" is a real one. It means that a "client application" using it's credentials has access to the whole breadth of user data. This access can be used maliciously (for example a "semi-trusted" app harvesting api data) or negligently (for example an app accidentally exposing a Direct Object Reference Vulnerability - https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References)
Probably the most prevalent "token based" scheme is OAuth2 (http://oauth.net/2/), and the precursor, OAuth, which many sites choose to continue to use.
OAuth2 has a number of roles:
resource owner (the user in your case)
resource server (your api)
client (the apps you talk about)
authorization server (not clear who or what would fulfil this role in your case)
The basic scheme is that the resource owner authenticates using their credentials directly with the authorization server. They are then asked if they want to grant some information (which may just be a persistent identifier, or a description of the information exposed by your api) to some client. When they accept an 'auth code' is sent to the client and they use that (combined with their own credentials) to receive an 'access token'. This access token can then be used to authenticate against the resource server (which can check it's authenticity back against the authorization server).
Normally the way this is used is that the authorization server and the resource server are owned and managed by the same entity (for example google and facebook would fulfil this role) and then clients are independently managed.
The scheme can also be used internally within an organisation without the "explicit grant" which can still at least confirm that a specific end-user is present before releasing any data from an api.
We are implementing generic REST client where in we want to support O' Auth 2.0. For now we are thinking off to allow users to define Access Token (no matter from where they bought it) while configuring client, which REST client will use while making requests.
is it possible ? I have couple of questions
Is the way a client get access token from authorization server a standard ?
Is client registered with the auth server while requesting access_token and can't same access token be used by other clients?
Is SSL or TSL mandate ?
Is the way client send access token to Resource server (while making resource req)a standard, does all Resource provider (facebook, linkedin, salesforce, google) support access_token sent in HTTP header or in Query parameter.
Is sending access token to resource server standardized, i.e. we need not to encrypt or use any third party lib for this.
I would suggest you read the spec here.
Every Library implementation uses this standard, you can use whatever method to generate your keys and authorizations etc, but if you conform to those interfaces then you should be fine.