My app get the oauth2.0 token to access the protected resource, but how can I distinguish between users, example if there is userA and userB. UserA can access the url /accout/info.jso?uid=2 to get his data,but my question is if userA get the token, but he access the userB's data by the url /accout/info.jso?uid=userBId
How oauth2.0 system avoid this kind of problem?
In OAuth 2.0, the resource owner and the client who is requesting access are two different entities. In your question, it sounds like they are one and the same. OAuth exists to provide limited access to a third party, the client application.
But leaving that aside... if you are using bearer tokens, they do not provide any identification. The nature of a bearer token is that whoever presents it is granted the access associated with the token. Other token types, SAML 2.0 for example, carry more semantic information about the identity of the client.
In your case, you want to verify that the user identified in the URI is the user who sent the request. A bearer token alone will not do this. If using bearer tokens, your resource server will need to ask the authorization server if the presented token was issued to the user whose data the client is requesting. The authorization server will have to remember the access tokens it issued and who it issued them to. It should also remember the scope they were issued for and when they expire so the resource server can check that the token is still active and the requested resource is in scope for the presented token.
Related
I'm researching to use OIDC for SSO (Single Sign On).
I know OIDC flow always return id_token and access_token but I don't know why we need id_token?
As I know id_token used only by client application to get authenticated user information. Client application will decode and verify JWT then extract user information from it.
But because I have access_token, I can use it to get user information from endpoint /userinfo. So I dont't need id_token?
Please help me understand the right way to use id_token.
You are correct that you can get the user details using the access token from the /userinfo endpoint.
The ID-token represents details about the user and more important how the user authenticated (password, 2FA...). The lifetime of the Id-token is often very short (like a few minutes).
Just like how the specification describes it:
The ID Token is a security token that contains Claims about the Authentication of an End-User by an Authorization Server when using a Client, and potentially other requested Claims.
While starting to integrate auth0, I came across this article
So its clear that to secure apis, all we need is the access_token and that is sent with each http request in the request Authorization header(Bearer scheme).
But then auth0(and possibly other providers) also send an Id_token that contains information about the user. My confusion is that how do I use this id_token to pass user information to my api. ( I have a spa running front end that authenticates to auth0 and gets these 2 tokens).
I can ofc call the userInfo end point in my api to get user info. But then wouldn't this defeat the purpose of the Id tokens?
The ID Token is consumed by the application and the claims included,
are typically used for UI display. It was added to the OIDC
specification as an optimization so the application can know the
identity of the user, without having to make an additional network
requests.
So my question is how do I access user profile in my api using id tokens?
"My confusion is that how do I use this id_token to pass user information to my api"
for that confusion, you just pass your JWT token. while generating JWT token, you need to add user information in payload part in JWT token. When your api get the JWT token, just check your JWT token is correct or not by the use of secret key and if correct, you can get data. How to get is just go from that JWT Authentication for Asp.Net Web Api
ID token is sent from the authorization server as a part of OIDC protocol. The purpose of this is to authenticate the user to your client application (SPA in this case). i.e. to let your API or the application know which particular user authorized the client to access a certain resource on its behalf.
Best way to use the ID token is by decoding and verifying it using a library. This will allow you to verify the signature of the token and any other claim that is included in the token (you can add custom claims to the tokens). Validation of those claims can be used to determine identity of the user and match with the user profile in your API. You will have to check the documentation related to your IdP(auth0) to figure out how to add new claims that are used by the user profile in your API.
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.
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.