I'm not sure if the permission validation in the resource server routes should be on the claims or the scope of the access token. For example:
a scope can be set to 'can-view-pictures' but a claim can be 'role: admin'. So In my resource server should I base the check on the scopes of the claims or a combination of both? Is there a rule of thumb?
Best,
Tal
I would use scopes as high level privileges - can I call tbis service? Because scopes have to be configured in the Authorization Server, which is very central. Meanwhile claims are very product specific. Hope this post helps you to understand the separation: https://authguidance.com/2017/10/03/api-tokens-claims/
Related
I want to authenticate users with Azure Active Directory (AD) in a mobile app that calls its own REST API and possibly, make it simple.
Looks like the documented way (here or here) to do so is to
register the API app with AD, expose some scope(s) as delegated permissions
register the mobile app, add these scopes as API permissions to this app
do authorization decisions in the API app based on these scopes
Question:
Now, since I feel the front-end and back-end parts of my app should belong into the same "black box" plus there are no fine-granular user roles within the app that would justify usage of multiple scopes or require the user to consent to using them, I'm wondering whether there is a recommended (and secure) way to go with just one app registration instead of two?
What I tried:
When using Okta in a similar scenario, I only had one app (clientId) and the back-end configuration pretty much validated the JWT token issuer, domain and a default audience string (in my understanding). I tried inspecting tokens from AD acquired via the authorization code flow for usual scopes (openid profile) to see what their audience was and if this could be reproduced - this is what I've got:
the well known GUID of Microsoft Graph (for the access token) - this one doesn't feel "correct" to validate, as pretty much any AD user could present an access token for MS Graph and only assigned users should be able to use my app
client ID of the app (for the ID token) - but the docs says these should not be used for authorization, so not sure if it's a great idea to pass them as Bearer tokens to the API
The standard thing in OAuth technologies is to only register a client for your mobile app. Azure has some vendor specific behaviour when it comes to APIs, related to the resource indicators spec. When there is no API registration, your mobile app will receive JWT access tokens with a nonce field in the JWT header. These are intended to be sent to Graph, and will fail validation if you ever try to validate them in your own APIs.
If like me you want to stay close to standards, one option is to add a single logical app registration, to represent your set of APIs. You might design an audience of api.mycompany.com, though Azure will give you a technical value like cb398b43-96e8-48e6-8e8e-b168d5816c0e. You can then expose scopes, and use them in client apps. This is fairly easy to manage. Some info in my blog post from a couple of years back might help clarify this.
Now, since I feel the front-end and back-end parts of my app should belong into the same "black box" plus there are no fine-granular user roles within the app that would justify usage of multiple scopes or require the user to consent to using them, I'm wondering whether there is a recommended (and secure) way to go with just one app registration instead of two?
You can create just one app registration; in fact the newer app registration model was designed to do that.
In the case where an API is used only by the app itself, I would register a single scope, something like MobileApp.Access.
Your API should verify the presence of this scope to prevent unauthorized applications from calling it.
In addition to verifying the scope, you will need to verify user permissions.
And filter the data based on their identity, depending on your use case.
Your question seems to suggest that you might be mixing scopes and user roles.
Scopes are permissions given to an application.
Also called delegated permissions; they allow an app to do some actions on behalf of the signed in user.
I try to understand if there is a way to ask all 'Scopes' of the user in Azure B2C and not specific ones?
Another question, what happens if we request for scope = x y z but the user has only x, it returns only x?
For example, if an app does not recognize all the user scopes and wants to use the user token to access other resource protected with scope x
Short answer - no. This would be in conflict with OpenID Connect specification. As described in the Authorization request scope is required parameter. With some additional explicitly listed values. The OAuth RFC is even more vague when it comes to defining the scope in the authorization request.
One thing worth noting is that you can, anyway only request scopes belonging to single resources in one request. That is in addition to the OIDC standard scopes. So you can only request scopes for one API (i.e. "https://my.api/api/read") but not for more than one ("https://my.api/api/read https://my.other.api2/api/read").
Bottom-line - no, you have to explicitly call out all the scopes that you require, and there is no way to ask the end-user "give me access to everything you have access to"..
Oh, and something more, when you configure your applications in a B2C tenant, you define the required scopes at the application level. For example:
Now all the users who sign-in to the SmartCollabClients application will be granted access to the 3 scopes defined and publish by the SmartCollabApi application.
I try to understand if there is a way to ask all 'Scopes' of the user in Azure B2C and not specific ones?
No, currently it is not possible. All the scopes you should explicitly request.
Another question, what happens if we request for scope = x y z but the user has only x, it returns only x?
No, if you request of scopes x,y,z (which are already associated for requested clientid), B2C will return same scopes irrespective of user privileges
Following SO post gives you few more details
What use are 'Scopes' in Azure B2C Authentication?
I have Azure AD B2C, and am I using it to secure an Azure Function. Users authenticate with the Azure Function by providing a JWT Bearer Token for authorization in the header.
This all works correctly.
I have now tried to apply the Allow Token Audience in the Authentication / Authorization configuration panel.
I had thought Allow Token Audience would validate the audience (aud) claim of my JWT token - which for my JWT token matches my Client Id.
This does not appear to be the case. All the values I supplied for Allow Token Audience are incorrect, but users are still successfully authenticated.
How is Allow Token Audience supposed to be used?
Per the comments, the issue seems to be that the client ID is accepted as an audience. This is expected behavior. App Service always allows the client ID and the base site URL (yoursite.azurewebsites.net) as valid audiences. The "Allowed token audiences" option is meant to provide additional audiences, such as if you were using a custom domain, etc.
This is certainly confusing. There are probably UX improvements that could communicate this better (info balloon, list entries that can't be removed, etc.).
Going over the OAuth2 specification, I couldn't figure out the relation between a scope and a resource :(
Looking at Google's oauth2 scopes, is the term scope refer to the API the Client app wants to access and the user may grant access to?
If so, what is the resource? The actual data?
What if the user wants to allow access to only part of the data (resources)? For example, allowing client apps see only part of my google plus circles?
Am I in the right direction at all?
I'm trying to understand conceptually and practically how to perform an oauth2 with openID-connect flow in my web-api application, utilising Azure AD.
Importantly, when a request is made to the API I want to know who made the request.
My current understanding is :-
My client would detect that the user isn't logged in and redirect to a sign-in.
The user would provide their credentials, and be redirected back to the client, along with an oauth2 token.
This token would be supplied to web-api endpoints for any requests.
This is where it gets murky for me.
How exactly do I use this token to authorize access to a particular resource, determine who is accessing the resource, and what is the mechanism that does so?
I'm sort of assuming that I would need to reuse the token to make a call to the Azure AD user endpoint - if the token was indeed valid, the AD endpoint would return the users details - thereby providing some means of determining that the token is valid and providing details on the users identity. Authorizing access to a resource could be done through membership of groups in Azure AD.
BUT ...
I can only assume this a solved problem, and have noticed use of OWIN middleware as per this example
https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet
But I'm still rather unsure as to what is exactly going on.
The service makes mention of scopes and claims, but I don't understand where these are derived from (I assume from a token supplied by the client, but not sure). The service must be receiving identity information in the call.
Which brings me to two points, for this to be secure -
The token provided in call to the service would need to be secured in transmission (hence the use of HTTPS) - to prevent MITM.
The token would need to be signed some how - I guess by using client secret or something - to prevent information in the token being spoofed.
Can someone help me clear up this muddled mess?
In particular -
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
How to limit access to some endpoints of the API based on a user role?
What do I do to practically achieve this by building on existing middleware and libraries available to me?
Disclaimer: This will not be a comprehensive answer. It is off the top of my head.
OpenID Connect provides an identity layer on top of OAuth. In your case, Active Directory provides the authentication and sends back an access_token. The access token represents a user that AD has authenticated. If your doing OpenID Connect, then AD will also send an id_token, which may contain additional identity information (such as birthday, avatar, and whatever else AD exposes.)
Neither OpenID Connect nor Active Directory have anything to do with the the roles that your app assigns to a user; roles are entirely the bailiwick of your app. You assign user roles just like you normally would; you assign them to the nameid though instead of to an email address or username. Your app no longer has to authenticate the user but it does need to assign roles to the nameid.
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
The identity is embedded in the access_token that AD includes in its response. This token will have a nameid in it that your app can associate with a user and role. The nameid is like an email address, username, or other uniqueID that your app uses to recognize the user.
How to limit access to some endpoints of the API based on a user role?
You choose. When your app receives a request with a particular access_token, that token will be associated with a particular user via its nameid, and you can assign whatever roles and rights to that user. Basically, associate roles with a nameid.
What do I do to practically achieve this by building on existing middleware and libraries available to me?
There is an unfinished demo here, though it doesn't use Active Directory as the provider, instead, it uses an internal provider. For the demo, the username is shaun and password is Testing123!. The source code is here.
Here is the link to the source of another demo, though again, it doesn't use Active Directory as the provider, instead, it uses Twitter.
The nice thing about OAuth and OpenID Connect is that we can use whatever identity provider we want, so you can adapt the demos to use Active Directory.
Apart from question #1 (the identity is verified on the service side) all your question are very open ended and would require a super long answer.
I would recommend reading https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/ - it is a good introduction to the flows underlying many of the modern authentication cenarios, including the web API one you are focusing on.
Once you have read that, you will find a complete set of samples in https://azure.microsoft.com/en-us/documentation/articles/active-directory-code-samples/ - in particular, I suggest studying the web API and thru authorization one to find guidance on the 3 questions you listed. HTH!