I am using the Resource Owner Password grant flow and requesting id token as well (the scope includes openid). I am sending the following to the endpoint:
client_id
client_secret
grant_type=password
username
password
scope
In the response I get the access token and the id token. The value for the sub claim is different between the two tokens. Why is this the case?
Update
It seems that the user id is actually an oid claim. This is described in Azure AD ID token reference.
Text describing the oid claim:
The immutable identifier for an object in the Microsoft identity system, in this case, a user account. This ID uniquely identifies the user across applications - two different applications signing in the same user will receive the same value in the oid claim. The Microsoft Graph will return this ID as the id property for a given user account. Because the oid allows multiple apps to correlate users, the profile scope is required in order to receive this claim. Note that if a single user exists in multiple tenants, the user will contain a different object ID in each tenant - they are considered different accounts, even though the user logs into each account with the same credentials.
Text describing the sub claim:
The principal about which the token asserts information, such as the user of an app. This value is immutable and cannot be reassigned or reused. The subject is a pairwise identifier - it is unique to a particular application ID. Therefore, if a single user signs into two different apps using two different client IDs, those apps will receive two different values for the subject claim. This may or may not be desired depending on your architecture and privacy requirements.
However, I am still not clear why the sub claim is different between the access and id tokens.
The subject (sub) claim is unique for the user and the service for which the token is intended (identified by the audience (aud) claim).
Usually, the ID Token and Access Token audiences will be different: the ID Token audience is the client app where the user is signing in, and the Access Token audience is the resource server the client app will attempt to access (on behalf of the signed-in user).
The Resource Owner Password Credentials grant type is not supposed to be used for user authentication as per the OpenID specification, only flow with that interact with the user through the authorization endpoint are allowed to do so (i.e. Implicit, Authorization Code, Hybrid and None grant type flows at the time of writing).
If you receive an ID token using the ROPC flow, then the Identity Provider proposes specific means that are out of scope of the OpenID Connect spec and may have specific and non-standard features that should be documented.
In any case, on Client side you should only rely on the sub claim in the ID Token. The Client is not supposed to parse the access token as it is only meant to be used by the resource server.
The sub claim depends on the IdP policy and the client configuration. The sub claim may be unique to the application (or application group). Please refer to Subject Identifier Types section of the specification.
Related
I am building a website that uses OAuth2.0 and OpenId-Connect (of some third party vendor) to authenticate user.
Before redirecting the user to the vendor's OAuth page, I am not asking the user to enter a unique UserID on my website, I was thinking of using the user's emailid that I receive as a part of IDToken after the Authorization process is done, as the user's User Name(unique identity) for my Website.
But the OpenID specification here
https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
says that emailid is optional and may not be returned.
So the questions is, is it a standard practice to ask the User to provide with a unique name (that I can use as user's identity on my website), before I initiate the OAUTH/OpenID-Connect process?
The sub claim must be unique per issuer. Required Claims will always be present. You can use the iss + sub to uniquely identify users.
To add more information, every OpenID connect provider need to provide a /userinfo endpoint to fetch the users information using access token.
here is the specification
https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
I'm considering to use id token instead of id token for authorization, so that resource servers can validate its sign and extract user id out of it. Is there any dowside to this method which I'm not aware of?
I guess I cannot use verify endpoint if I throw away access token. For us, it doesn't matter which scope the user granted access to since both client app and OIDC's identity provider is owned by us.
I'm using this library to implement an OAuth2 and OpenID server.
https://github.com/bshaffer/oauth2-server-php
Usage of ID Token is intended for the client application. Client uses it to authenticate the end user. All this is made possible through claims ID Token transfer. And these claims are built into an JWT. In simple terms, ID Token is a self-contained token.
Now, sharing of ID Token outside of client is okay if you control all intended parties. Think about a scenario in which you leak sensitive user information through ID Token. For example if ID Token contain a claim about gender which only intended for client to use. But when you share ID Token with a third party, you expose those sensitive information. It could be a crime if there are legal barriers.
Another point is on ID Token validation. Hence ID Token targets the client, important claims such as aud is set accordingly. When you pass ID Token to a backend to be used, such validation could fail.
There are two solutions. First is to use self contained access tokens. These days it is common to use JWT based access tokens. With them, you get the same solution. It will contain end user identity, scope values as well as token validation information. Azure AD use such approach - check this link.
Second one is to use ID Token. Given that you control both front end and backend, my opinion is you are okay to use it. But be mindful about future extensions. Specially not to expose it to other parties.
I am working with a couple of applications which are created in apps.dev.microsoft.com. The auth URL I am using is
https: //login.microsoftonline.com/common/oauth2/v2.0/authorize?
client_id={client_id}
&redirect_uri={redirect_uri}
&response_type=code id_token
&state=state
&nonce=c7a966a3-d63d-4348-8ab8-bd445b0e9bb1
&response_mode=form_post
&scope=openid email profile https://graph.microsoft.com/user.readBasic.all
In my use case, I am capturing tid, oid, iss, sub... claims from id_token claims.
For one of my application, with some users the oid claim is missing in the id_token. But I am able to get for other apps and I don't see any difference in creating apps.
What reasons might cause the oid claim to be missing?
Scopes I am using: openid email user.read
The oid claim will only be returned if the scope profile was requested.
From the documentation:
Because the oid allows multiple apps to correlate users, the profile scope is required in order to receive this claim.
For users where you don't receive the oid claim, check the token to make sure the profile scope is there. If it isn't there (and you've confirmed it was requested) then you can force the scopes for that token to be refreshed by adding &prompt=consent to the end of your authentication URI. This will force the user to re-consent to the scopes and ensure you're not getting a cached token.
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.
I am implementing OAuth 2.0 with JWT in my application and am having trouble deciding what to set as my aud claim as. A user will "login" to my client via my authentication server to gain access to my API (resource) server. I want my tokens to only be valid for use with a specific client and specific API.
When logging in from my client, I include it't client_id in the request, but in most implementations I've found, the aud is set to that client_id. I'm leaning towards including a customer audience_id field in my login request and then setting the aud in the token to an array of the client_id and the audience_id, but that feels like it just means that that token is valid for both those audiences, which makes me think I should just add a custom claim called client to specifically state that this token was created for a specific client.
I have not come across any implementations online that include both a client_id and audience_id(s) in an OAuth login request, nor do I see a reserved claim for client in the spec.
Am I missing something here?
What is best practice for specifically stating a different client_id and audience_id in a JWT?
The audience of the JWT is the Resource Server as that is where the token will be processed, i.e. verified, inspected and acted upon. From RFC 7519, https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3:
The "aud" (audience) claim identifies the recipients that the JWT is
intended for. Each principal intended to process the JWT MUST
identify itself with a value in the audience claim.
[...]
The interpretation of audience values is generally application specific.
[...]
So best practice is that aud should identify the Resource Server.
The Client is only the presenter of the token and it is best practice (i.e. in OpenID Connect and some emerging OAuth 2.0 exension drafts) to use the azp (Authorized Presenter) for that claim. From http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken :
azp
OPTIONAL. Authorized party - the party to which the ID Token was
issued. If present, it MUST contain the OAuth 2.0 Client ID of this
party. This Claim is only needed when the ID Token has a single
audience value and that audience is different than the authorized
party.
[...]
So best practice is that azp identifies the Client.