I am using client credentials flow using Spring OAuth2. The DefaultAuthenticationKeyGenerator stores the access_token in memory for me. However if I run multiple client instances from different hosts and make the /oauth/token client_credentials grant request, I get the SAME access token. So all client instances with the same (client id and client secret) get the same access token. So I must be misunderstanding something fundamentally. Is there a way to have each instance of my client receive its own unique client credentials flow access token with it's own expiration period ? The reason I want this is so I can authenticate the client itself before a user account has been created. After the user account is created I can use the user resource password grant flow to get a user specific access_token.
Related
I need to implement a single sign on of a user, which can get services from several different services.
When there was only a single service, the user could log in from the client side, send the request to a backend, gets a URL back to a JWT token issuer server, from which he can get a token which he sends back to the BE and he is now authenticated.
What is now changing, is that he needs to get more services. Each service has its own frontend and backend, but everyone are using the same issuer. Meaning there are both services with FE and BE, and also there is another general BE for the authentication.
What is the correct flow to authenticate in the scenario? Can the general BE issue a token for the client for each of the required services? Or should the BE respond the client with the services's BE url and let the client itself send an authentication token response from each service? Or something else?
I assume you mean OpenID Connect, since OAuth2.0 is not used for authentication and does not require the use of JWTs. Also, in your scenario there are not multiple resources, but multiple clients / relying parties.
Using the OpendID Connect Implicit flow, the issuer will eventually send an id token (JWT) to the user's browser. This JWT can be used to authenticate to a service. Each JWT will contain an aud (audience) claim to identify the service it should be used for.
Using the Authorization Code flow, the issuer will eventually send an authorization code to the user's browser. The user will send the code to a service, and the service will send the code plus its client id to the issuer in exchange for an id token (JWT) and an access token.
In both cases, the service identifies the end user using the iss (issuer) claim, and verifies the JWT by checking the signature, expiry and audience.
In OAuth2 protocol, Client (RP in terms of OIDC) application obtains an access token, which enables it to use different services (Resource server role) on behalf of a Resource Owner.
On the other hand, in the OpenID Connect protocol, Client obtains 2 tokens (access and id token). Now this Client can use the access token to fetch user claims from the UserInfo endpoint.
Does OP (Authorization server) play role of a Resource Server here (in terms of OAuth2), and Client fetches user data on behalf of a user?
How is ID token used by the Client? Does Client pass this ID token to the Resource Owner's user agent (Browser) and then, user agent stores this token to enable SSO (cookie)?
Does Client (e.g. different one than the one that obtained the ID token) has to verify the token every time user accesses it (call OP to verify it), or Client does this only first time it gets accessed by this token and then creates security context which enables it to eliminate this request for verification at OP every time? In this case, how could this security context be implemented?
What is the access token used for, except for fetching user claims and why is it sent along with ID token, when Client could use ID token to access UserInfo endoint?
First of all you must understand the purpose of tokens. Access token is a token that is good enough to access a protected resource on behalf of the end user. It is defined by OAuth 2.0 authorization framework. Now having an access token does not authenticate the end user. it simply authorize the client application to access a resource. OpenID Connect introduce the ID Token. Now this token is to be consumed by your client application. Protocol define how this to be done and if valid, your client application can authenticate the end user.
Q: Does OP (Authorization server) play role of a Resource Server here (in terms of OAuth2), and Client fetches user data on behalf of a user?
Partially correct. According to the protocol document, userinfo endpoint acts as OAuth 2.0 protected resource.
The UserInfo Endpoint is an OAuth 2.0 Protected Resource that returns Claims about the authenticated End-User. To obtain the requested Claims about the End-User, the Client makes a request to the UserInfo Endpoint using an Access Token obtained through OpenID Connect Authentication.
Q: How is ID token used by the Client? Does Client pass this ID token to the Resource Owner's user agent (Browser) and then, user agent stores this token to enable SSO (cookie)?
As mentioned previously client must validate the id token and based on that it can authenticate the end user. ID token is not connected with SSO.
Q:Does Client (e.g. different one than the one that obtained the ID token) has to verify the token every time user accesses it (call OP to verify it), or Client does this only first time it gets accessed by this token and then creates security context which enables it to eliminate this request for verification at OP every time? In this case, how could this security context be implemented?
If you are using ID token to be consumed from a protected endpoint, then token receiving party should validate it before accepting it. One may choose to create a session after a proper token validation (session must not extend the life time of the token).
Q: What is the access token used for, except for fetching user claims and why is it sent along with access token, when Client could use ID token to access UserInfo endoint?
Access token is the token your should use to access OAuth 2.0 protected resources. Once the endpoint received it, endpoint can validate the access token against token introspection endpoint exposed by the authorization server (Protocol definition of introspection). And with Openid Connect, defining of userinfo endpoint let any party with valid id token to consume it.
I don't see how you can be confused about that if you've read the RFCs.
You want to think of identity as a "resource" service? fine, but the authentication for this service is different than for RPs, so what's your point?
The Client exists in the User Agent (we're talking about SPAs, right?). If the ID token is in the Client, then it's in the UA (the reverse is not true). If you're thinking of server-side clients, then there is no need to forward the ID token to the UA, unless you want the UA to pass it on to another Client (e.g. for SSO). There are SSO schemes that use the ID token for convenience, but that's not the stated purpose of the ID token.
The whole point of JWS is that you don't need to call the OP to verify a token. You just verify the signature. That may be done by any Client, whether they're the original recipient of a token, or they get it later. Furthermore, the ID token is not meant to authenticate the user. Using it for SSO requires some other form of security, such as storing a related secret in an HTTP-only cookie that will not be seen by the Client. Anyway, even if you use the ID token for SSO, then the ID token is sent only in the login request. After that, the Client will get its own access token for authentication and will not use the ID token again.
The access token is typically short-lived (which means the Client has to contact the OP regularly, which allows the OP a chance to revoke access). The access token is sent with every authenticated request, so it should be small (i.e. not contain user information that is not useful for authentication).
I'm building a system with OIDC and OAuth 2.0 (using Auth0), and I'm unsure how to properly use the id_token and access_token. Or rather, I'm confused about which roles to assign to the various services in my setup.
I have a fully static frontend-application (single-page app, HTML + JS, no backend) that ensures that the user is authenticated using the implicit flow against Auth0. The frontend-application then fetches data from an API that I am also building.
Now, which is right?
The frontend SPA is the OAuth client application
My API service is an OAuth resource server
...or:
The frontend and my API service are both the client application
If both my frontend and backend API can be considered to be the client, I see no real harm in using the id_token as the bearer token on requests from my frontend to my backend - this is appealing because then I can simply verify the signed token on the backend, and I have all the information about the user that I need. However, if my API is considered a resource server, I should probably use the access_token, but then I have to connect to Auth0's servers on every API request to both verify the token, and get basic user info, won't I?
I've read this which seems to suggest that the access_token is the only valid token for use with my API. But like I said, I'm not sure about the roles of the individual services. And using the id_token is tempting, because it requires no network connections on the backend, and contains information I need to extract the right data.
What is the right way to go about this?
I like this Medium post about the difference, all cred to this author.
https://medium.com/#nilasini/id-token-vs-access-token-17e7dd622084
If you are using Azure AD B2C like I am you can read more here:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/openid-connect
ID Token
You will get id token if you are using scope as openid. Id token is specific to openid scope. With openid scope you can get both id token and access token.
The primary extension that OpenID Connect makes to OAuth 2.0 to enable End-Users to be Authenticated is the ID Token data structure. The ID Token is a security token that contains Claims(claims are name/value pairs that contain information about a user) about the Authentication of an End-User by an Authorization Server when using a Client, and potentially other requested Claims. The ID Token is represented as a JSON Web Token (JWT)
{
"iss": "https://server.example.com",
"sub": "24400320",
"aud": "s6BhdRkqt3",
"nonce": "n-0S6_WzA2Mj",
"exp": 1311281970,
"iat": 1311280970,
"auth_time": 1311280969,
"acr": "urn:mace:incommon:iap:silver"
}
The above is default JWT claims, in addition to that, if you requested claims from service provider then you will get those as well.
An id_token is a JWT, per the OIDC Specification. This means that:
identity information about the user is encoded right into the token
and
the token can be definitively verified to prove that it hasn't been
tampered with.
There's a set of rules in the specification for validating an id_token. Among the claims encoded in the id_token is an expiration (exp), which must be honored as part of the validation process. Additionally, the signature section of JWT is used in concert with a key to validate that the entire JWT has not been tampered with in any way.
Access Tokens
Access tokens are used as bearer tokens. A bearer token means that the bearer (who hold the access token) can access authorized resources without further identification. Because of this, it's important that bearer tokens are protected. If I can somehow get ahold of and "bear" your access token, I can pretend as you.
These tokens usually have a short lifespan (dictated by its expiration) for improved security. That is, when the access token expires, the user must authenticate again to get a new access token limiting the exposure of the fact that it's a bearer token.
Although not mandated by the OIDC spec, Okta uses JWTs for access tokens as (among other things) the expiration is built right into the token.
OIDC specifies a /userinfo endpoint that returns identity information and must be protected. Presenting the access token makes the endpoint accessible.
http://openid.net/specs/openid-connect-core-1_0.html
https://connect2id.com/learn/openid-connect#cool-id-token-uses
https://developer.okta.com/blog/2017/07/25/oidc-primer-part-1
Your frontent is your OAuth client application, once it stores the token it can take actions on the OAuth flow. And your API service is resource server, because it accepts the access_token issued by your identity server.
Also I would say that your id_token stands for the identification of the logged user and may contain sensitive data for your app. The access_token is standing as your credential to access a resource.
At the end you will use an access_token to request a resource, and then if you need specific data from the logged in user (resource owner), you may request the ID token from the token endpoint.
In my opinion, the first approach is correct. Your SPA is the client application and your APIs are resource servers.
I would suggest you limit the use of id_token till your SPA only. You can use the basic information present in the id token (like username and email) to display user information within your UI. If you can generate access tokens as JWTs too then your API can validate the access tokens without going to the Identity provider. You can include roles (or similar) in your access token to get authorization information in your access token.
I was also wondering if I need to talk to the IdP on every request if I'm using the tokens received from the IdP. I ended up with the following setup:
Only the backend talks to the IdP, the frontend does not.
Upon the IdP callback the backend issues a JWT for the frontend.
User session and frontend-backend communication is managed entirely by my app using the JWT token.
Check this article: OAuth2 in NestJS for Social Login (Google, Facebook, Twitter, etc)
and this repo: https://github.com/thisismydesign/nestjs-starter
and this question: OAuth2 flow in full-stack NestJS application
The id_token is an cryptographically encoded token for authentication. The OP (the auth provider) is the one that generates it and the RP (relying party or the resource) will eventually re-present the token to the OP to counter validate when handed over by the client. In short the id_token is tied to authn workflow.
The access_token enables resource access. It does subsume the userinfo i.e., the id_token or any other principal on whose behalf the access is being requested. So this token includes both user claims plus claims to groups that are authorized. In short the access_token is tied to your authz workflow.
I am currently trying to implement a web service (API) with OAuth2 authentication using Spring Security OAuth. As far as I understood, given a user, a client app and a server, the authentication process is as follows:
User requests resource from server via client
Client retrieves request token from server
Server responds with a temporary request token and a redirect URL
Client loads web page (redirect URL) and lets user enter credentials in order to authenticate the request token. The form inputs are sent to the server, input is unknown to client.
Server replies with an authorization code, which is handed to the client
Client uses authorization code to retrieve an access token (and, optionally, a refresh token if one was requested)
User hands access token to client
Client uses access token to retrieve requested resource
In Spring OAuth, there are three grant types to request an access token:
Authorization Code, which is the method I described above, refresh token, and user credentials. I don't know how retrieval by user credentials works, is it similar to retrieval via refresh token?
A couple of statements you are making above are incorrect. Probably it's a good idea if you have another look into the OAuth2 spec: https://www.rfc-editor.org/rfc/rfc6749
To concentrate on your question I just refer to the last paragraph of your question here after.
OAuth2 supports 4 grant types, namely 'Authorization Code', 'Implicit', 'Resource Owner Password Credentials' and 'Client Credentials'. The one you are refering to as 'user credentials' would be 'Resource Owner Password Credentials'. In this grant type you loose OAuth's benefit of not having to hand over resource owner (aka user) credentials to the client. However it still has the benefit of not having to store the password on the client and sending it for each resource request, since a token is used instead. The process flow is as following:
resource owner sends credentials to client
client sends credentials to authorization server
server returns access token (and optinally a
refresh token)
client uses access token in subsequent request to
ressource server
So yes, you could say that the flow of the Resource Owner Password Credentials grant is similiar to the flow when a client already has a valid refresh token (from which ever grant).
Our Mobile Client App uses https://identityserver:port/oauth2/token service from Identity Server by passing the ClientID and ClientSecret with grant_type as “client_credentials” to generate the access token. The generated access token is used to invoke the API from ESB.
As per the implementation the ClientID and ClientSecret will be stored in the device.
For an example, ClientX requested for an Oauth Token which will have a certain expiry time. Can this token make as a unique for ClientX?
Currently all the upcoming client calls will get the same access token as its already generated from the request of ClientX. If a client is requesting a token very late it will get the same token with almost expiry time.
Is there a way to make this token unique for the Client?
In your case, if you use “client_credentials” as a grant type, resource owner is also the client.
Since this is a mobile application, once your mobile app gets the token it will be used until the expiry date and there will not be a necessity of changing it, because of mobile is belongs to a single user. Therefore the token would be same for same scope till it is expired.
Ex: BBC news mobile application.
If you need different access tokens, you need to use different scopes.
You will need different access token in case if different clients accessing the same API. In that case you may use “PASSWORD” grant type for a unique access token.
Ex: Purchasing a product using ebay.
So you should define your scope properly to identify the use of access token.
Find the following blog that will help you to guide to select your scope. [1]
[1] http://wso2.com/library/articles/2014/02/securing-your-web-service-with-oauth2-using-wso2-identity-server-1/
I will assume that mobile application instance is bound per user.
If you want to get different access tokens for every user bound to a session don't use client_credential grant type.
For example you have client-x and client-y both using client_credentials grant. Identity Server (Authorization Server) will give an access token for client-x and client-y since this is about authorizing client-x and client-y to access resource and not about authorizing a user. This means whatever user you have in client-x or client-y requesting access_token, they can get one (assuming they are authenticated).Vice versa, a user, even if authenticated both client and identity server cannot get an access token if the request comes from client-z (client-z is not registered in identity server)
If your Oauth 2.0 client is browser-based you can use implicit grant, if it is a server you can use either authorization grant or resource owner password credential.