I am asking a question conceptually here as I am trying to understand the relationship between scopes and user roles in an OAuth2 based system.
As I am implementing an API, I want to restrict access to specific resources by using scopes on the resources. I understand the use of access tokens to request resources, and I believe my understanding to be correct in that you specify your scope(s) when requesting the access token.
What I am not entirely sure of is how restriction of scopes would work based on specific roles that an authenticated user is in. Let's assume Bob is an admin and Sue is a regular user. We have some resources protected by an is_admin scope. What stops Sue from requesting (and receiving) is_admin scope in her access token?
I am thinking that what should happen is the following:
Bob authenticates.
Bob's roles are looked up after his authentication is complete. His "admin" role has the "is_admin" scope attached.
Bob asks for an access token with all the scopes collected from his various roles
Bob is automatically given those scopes for his access token
Is it up to my calling app to enforce only sending asking for the scope Bobs needs? Or is there something I am missing with regards to scopes?
Can someone please enlighten me with some simple examples?
In OAuth2, there are the following roles:
Resource owner - usually some person
Auth provider - the OAuth2 server
Resource server - an API that requires an access token and validates its scopes
Client application - application requesting an access token with some scopes.
To understand OAuth2, it's necessary to think about it as a protocol for access rights delegation from a Resource owner to a Client application. So the main use case is: the Client application wants to access the Resource server. In order to do that, the Client application needs an access token issued by the Auth provider and authorized by the Resource owner (which gets authenticated by the Auth provider).
In your description, the Client application is missing. Let's assume it's a frontend application for your API. It needs an access token with scopes admin-user-scope or regular-user-scope. So it redirect a user (Resource owner) to the Auth provider, requesting both scopes.
The Auth provider authenticates the user and asks him/her for a consent on granting some of the requested scopes to the Client application. The Auth provider may remove some scopes - for example the admin-user-scope for non-admins. The Auth provider may give the user a possibility to remove some scopes too.
The Client application receives an access token (or a grant) with scopes in a redirect URI. If the granted scopes differ from the requested scopes, the Auth provider sends a list of granted scopes (the scope URL parameter) along with the access token, so the Client application knows what actions it can perform with the access token.
Then the client application may access the Resource server and the Resource server makes sure that the provided access token contains required scopes. The Resource server uses the OAuth2 introspection endpoint to validate the token and to get a list of its scopes.
Related
I have:
Spring boot client application with some public endpoints and private endpoints which require #PreAuthorize("#oauth2.hasScope('resource.read')") for example
I have a external authorization server: Cloudfoundry UAA
I have a external OIDC provider linked to UAA I can use that to authenticate a person, I receive a Person_ID from the ID_Token from that external OIDC provider
Now I need to change UAA core code to implement my logic of using that Person_ID and searching for equivalent user from LDAP which shares the same Person_ID and then I will need to add it's usergroups to the token for the client. (I have done it currently in the /userinfo endpoint)
So I have done this logic in the /userinfo endpoint, when client receives a access token (From client, redirected to UAA, from UAA to OIDC for AUTH, then back again for the token and then this token is sent to client, now client can take the token and ask for the /userinfo which will then have it's user roles)
Is this bad logic? Should I add the LDAP implementation(step4) inside the access token already somehow?
Really, as is often the case with design questions, it depends.
The key to remember is that OIDC and its associated id_token are for authentication. It's common for the /userinfo response to state claims about who the user is. Part of the user's identity might be their role.
OAuth and its associated access_token, on the other hand, are for authorization. It's common for the access token to state claims about what the client is authorized to do. What a client might be able to do may be different than the user's role.
Think about what decisions this client will need to make. It may be able to make choices like which of its pages it can show, based on the roles that it inferred from the /userinfo response.
Think about what this client will communicate with. Maybe it will communicate with a resource server. If the client passes the access_token obtained during login, then that token should indicate what the client is authorized to do.
I use WSO2IS as an OIDC provider for authentication and authorization. Using Authentication Code grant, I got the access-token. I need to authorize the users to access specific services based on their roles.
I tried to use XACML to solve this, but I found that I need to pass base64 encoding of username:password in the header of REST API XACML request. Instead is there any way I can authorize the user to access services based on their roles, using access-token ?
This part of authorization happens in the resource server. I thought I could use the introspection endpoint to authorize the user based on the access token using scopes. But I don't understand how scopes can be used to provide access control to the users ?
To get an access token with all scopes available to a user, the OAuth2 client must request all scopes it cares about and the token will contain only those that the user has access to. See this question.
Yes, it's cumbersome, but OAuth2 is primarily an authorization delegation protocol - it allows users to delegate some of their rights (scopes) to a client.
Alternatively, if you could decide permissions based on roles, you could probably get a list of user roles from an ID token.
I understand the OAuth 2.0 spec. allows third-party applications to grant limited access to the application, either on behalf of a resource owner or by allowing the third-party application to obtain access on its own behalf.
I have a scenario, where I have an application and I need the user to get authenticated with some IAM provider. The roles and privileges are configured in the authorization server for each user. I can query the introspection point of the authorization server and based on the scope details, my application can decide the access to any resource for the user.
In this case, the user is not the resource owner. The types of resources the user can access is decided by my application, instead of the user allowing/denying the application to access resources.
Since the user is not the resource owner, can OAuth/OpenId Connect be used in this scenario ? Is it possible with WSO2 IAM?
I tried the playground sample which is available in WSO2. Once the user logs in, there is a window which asks "playground requests access to your profile information" and requesting the user to allow/deny. Can this be avoided, since in my case the user is not allowed to make any decisions ?
If not, what are the other options to authorize/limit access to resources which is decided by the authorization server/resource server, instead of user granting access ?
Thanks,
Albie Morken
In this case, the user is not the resource owner. The types of resources the user can access is decided by my application, instead of the user allowing/denying the application to access resources.
In your scenario, you are relying on tokens issued by authorisation server to access a protected resource. The protected resource is your application. And this application must have internal mechanisms to verify the tokens it receives to grant access.
Short answer to your question is - YES
You can use openID connect for this scenario. And you have two options to adopt,
1. Use access tokens with introspection end point
You can use access tokens to grant access to your application. The client should send the access token as a bearer token as described in RFC6750. When the application end point receives a request, this access token can be validated against introspection endpoint RFC7662
2. Use ID token
ID tokens too can be used as bearer tokens.ID token is a JWT (RFC7519) and is self contained. It contains validation mechanisms as described by OpenID connect spec which are self sufficient to allow grant. And also to you can check claims it contains to authorise the end user. More can be found from this link.
I tried the playground sample which is available in WSO2. Once the user logs in, there is a window which asks "playground requests access to your profile information" and requesting the user to allow/deny. Can this be avoided, since in my case the user is not allowed to make any decisions ?
Consent page can be disabled. According to spec. it can be done by configuring identity.xml as follow,
<SkipUserConsent>true</SkipUserConsent>
It is described in their documentation too.
Hope this helped.
p.s - WSO2IS contains inbuilt XACML engine. XACML is the standard for access control. You can fine more information from this link.
Our team is starting to build out a SMART on FHIR (SoF) application. SoF uses OAuth2 access_tokens to represent authorizations. Our app is using the code grant to get a token (https://oauth2.thephpleague.com/authorization-server/auth-code-grant/).
I'm pretty new to OAuth2 (used to SAML) and have been reading up on the standard. I think we may be conflating what the access_token is intended to represent.
Is the intent in OAuth2 that the access_token represents the permissions the resource owner (end user) has granted to the client (web application) to perform on their behalf?
Or is the intent to rely that the resource owner (end user) is allowed to preform certain operations?
For example say the auth token request has a scope called 'contacts-update'. If we get an access_token back with this scope, does that mean the user has allowed the application to attempt to update contacts (on their behalf) or does it mean that the user has the underlying requirements (they are in the update contacts role) to be able to update contacts?
As you wrote, the OAuth2 access token represents a permission delegation from a resource owner to a client (application), so the client can perform operations on behalf of the resource owner. That's also why there is a consent page - the user agrees on giving the application permissions (scopes) it requested.
Sometimes, people want to use OAuth2 as a central authentication server and a permission configuration for their applications. They want each application to see all permissions the user has configured for it. Then it doesn't make sense for application to ask for specific scopes, but to configure the OAuth2 server to return all relevant for that application (identified by a client_id). But I don't think this is the intended way of usage and the OAuth2 specification doesn't cover this scenario.
OAuth2 can also be used for authentication only, if it supports OpenID Connect extension. Then applications can ask for ID tokens. ID token proves identity of a user and the permissions are handled in each application separately.
I am using Identity Server 4 for authenticate user from a single application page. For the need of the project, I have to use the resource owner password flow.
Identity Server and my application work fine together. Identity Server give an Access Token and I can use this token to access some API that we own.
However, I was asking myself about the Access Token, users and socpes. For now my setup is this one.
I have an API that require the scope API-1.
I have a client (my SPA) where I defined the scope API-1
And I have a user.
In this configuration, it is the client who own the right to access the API, not the user. And I'm wondering how to give this scope to the user and not anymore to the client.
Stupidly, I'm wondering if user can own the scope and not the client. Maybe I've miss or misunderstood something, so please teach me.
In the Resource Owner Password Flow your client will always need to have permission to the scope that your resource is protected by. This does not mean that you cannot protect your API based on claims related to the user however.
If in your API for example you need different permissions based on the user accessing the API look to use the claims information as part of your authorization. In the Resource Owner Password Flow example at http://docs.identityserver.io/en/release/quickstarts/2_resource_owner_passwords.html you will see that it mentions this at the foot of the page, see the two paragraphs as follows:
When you send the token to the identity API endpoint, you will notice one small but important difference compared to the client credentials grant. The access token will now contain a sub claim which uniquely identifies the user. This “sub” claim can be seen by examining the content variable after the call to the API and also will be displayed on the screen by the console application.
The presence (or absence) of the sub claim let’s the API distinguish between calls on behalf of clients and calls on behalf of users.