In the Authentication Request, if users previously gave consent to some client (for a specific list of scopes) and because they might be prompted for the same authorization multiple times. ¿Could be acceptable to skip it?. ¿Works on both code and implicit flows?. ¿How much time remember the consent?.
I'm a little bit confused about the way to implement this. The Oauth2 draft say:
... and obtains an authorization decision
(by asking the resource owner or by
establishing approval via other means).
And OpenID draft say:
... this MAY be done through an interactive dialogue with the End-User
that makes it clear what is being consented to or by establishing
consent via conditions for processing the request or other means
(for example, via previous administrative consent).
Am working on an OpenID Provider implementation for Django.
https://github.com/juanifioren/django-openid-provider
Thanks for your time. Greetings.
Consent is a tricky business. There are different rules in different countries and even different interpretations within the same country. But that aside a common way of handling consent in SSO systems is to ask the user for consent the first time she appears from a specific client and then also ask if the choice should be remembered or if it should only be valid this once. Of course if the user says her consent should be remember she still should have the possibility to later redraw the consent but then outside the normal authorization flow.
You should ask for approval for a specific client only the first time that a user logs in to that client and then store it for later usage. In some use cases user consent is not required because it may be implicit, e.g. in an enterprise setting where users use internal clients.
Related
I'm building a service provider application where users are supposed to be able to share their data with a third party application using OAuth2 and OpenID Connect.
The standard OAuth2 consent flow authorize scopes (which attributes / roles to share).
However, since attributes could consist of multiple values, we would also like to allow the user to select which value/s to share.
So my question is, should I replace the whole OAuth2 consent flow with a custom one where OAuth2 scopes are more or less replaced with explicit attribute key/value pairs?
It feels a bit weird to remove such a core component of OAuth2 as scopes, what do you think? Any other suggestions?
I'm currently trying out spring authorization server for customizing the consent flow (since Keycloak that we're currently using doesn't seem to be that flexible with the consent logic).
I think that replacing the standard consent flow in spring authorization server would require rewrites of both OAuth2AuthorizationConsentService, OAuth2AuthorizationConsentAuthenticationProvider as well as all the OAuth2...AuthenticationProvider classes that are used for authentication in order to forward consent to the new consent flow.
Check out the official custom consent sample! This sample demonstrates a custom consent screen without replacing the built-in components for handling submission of the consent screen and saving user consent in the OAuth2AuthorizationConsentService.
In particular, these lines configure the consent page, and this controller endpoint implements the logic for building a custom consent screen, which can be whatever you need for your application.
If you are wanting to customize what is mapped from the consent screen to the saved authorization, you would customize the OAuth2 Authorization Endpoint with an authorizationRequestConverter(). Scopes are simply stored as "authorities", so you can instead (or in addition) store anything you want.
To customize the access token (JWT) that is produced as a result of this consent and authorization, provide a OAuth2TokenCustomizer<JwtEncodingContext> as in the example OAuth2TokenCustomizer from the reference documentation.
What you are describing is the exact purpose of scope: contain user consent on what data (attributes names) a specific client can access on their behalf. Usually, to ease user selection and software maintenance, the attributes granularity in scope selection is not the same as internal data model (for instance a contact scope could represent phone, country, city, zipcode and street columns in database)
As roles, groups, permissions or whatever should be mapped to Spring authorities are not specified by Oauth2 nor OpenID, authorization-servers use private claims to store this data (and usually not scope). If you are used to Keycloak, you should have noticed that roles are put by default in realm_access.roles and resource_access.{client-id}.roles. Other authorization-servers will use other private claim(s).
Simply put, roles (or groups or permissions or whatever you want to call it) define what a specific user can do in the system when scope should contain which resources a specific client is allowed to access on behalf of that user.
Thought I'd add some use-case based notes on the parties involved, and how consent is meant to work.
CLIENT
The client app simply redirects with a scope parameter. It is possible to send a claims parameter but that is rarely used. A scope might be profile and be composed of name and date of birth claims.
AUTHORIZATION SERVER
This presents the requested information in a consent screen. The most flexible way to do this is to present the claims, eg as checkboxes. Some claims, eg name, might be marked as required and use a disabled checkbox. Others, eg date of birth, can be optional. The user might deselect the latter claim and it would then not be included in tokens issued.
CUSTOMIZING CONSENT
Ideally no customization should be needed to achieve the above, which should work out of the box. This may not be the case for Spring though. It is valid to customize consent though. An interesting case where this is done is in Open Banking, where a user can consent to payment of a runtime amount of money:
I consent to pay company X £100 for product Y from account Z
We're building a system that exposes APIs, subsets of which are accessible to different user types:
organization administrator users can access relevant admin APIs that give them full access to their data. They are identified via email and a password that they control.
device registrar users can access certain APIs that should only be accessible to tablets deployed on-site at organizations. They are identified via an email and password that we control. There is a one-time setup process that the organization goes through to register a device, and it involves logging on with the device registrar account and providing some additional metadata. From there, the device caches the OAuth token and automatically renews it using the refresh token.
visitor users can access APIs that are needed by the end consumer (i.e. the general public), but they must first provide - and prove access to - a mobile number. In other words, they provide a phone number and a OTP will prove they have access to that phone.
We are building this on top of IdentityServer4 using ASP.NET Core and Firestore. We already have IS4 integrated with Firestore and can already authenticate/authorize organization administrators. Each such user in our Firestore database looks like this:
Notice that we just store a set of claims for each user, and in this case it's just an organization ID that the user is an administrator for.
What I'm struggling with a bit is understanding how best to model our other use cases: registered devices and visitors. On the one hand it feels like I could simply use claims to distinguish the different cases; something like this:
an orgid claim means that user is an organization administrator
a regordid claim means that user is able to register a device
a phone claim means that user is a visitor
But on the other hand, this feels a little fragile to me. What if, for example, we wanted both organization administrator users and device registrar users to have the orgid claim? After all, that makes sense because device registrar users are still tied to a specific organization.
On the other hand, is it "normal" to solve this by having some kind of "user type" claim?
Can anyone offer any design tips here?
Good question - some notes below on how I've dealt with this in the past:
MODELLING USERS
By all means model users and their attributes in terms of what makes sense to your company. Then manage this data via some kind of User Service. However, not all user attributes should be included in OAuth access tokens. Aim to avoid a setup where adding Claim X to a token for API 1 also affects tokens for API 2.
OAUTH USER DATA v PRODUCT USER DATA
At some point there is a separation between OAuth User Data and each API's Domain Specific User Data. You perhaps should not really be sending 'device + registrar' claims in tokens to the admin API if the claims are meaningless to the recipient?
CLAIMS BASED ARCHITECTURE
OAuth should enable an architecture where each of your APIs can collect the claims it is interested in, both from the token and from other sources. If interested in this approach, see these resources of mine:
Authorization Design Blog Post
Some C# Code that implements this pattern
In your example this would allow you to deal with 'orgid' privileges in a dynamic manner, based on what that means to each API.
PUT EACH API IN CONTROL
I tend to use the Authorization Server as a 'toolbox' with clearly defined boundaries, so that the API architecture can scale without conflicts:
The Authorization Server's role is to deal only with authentication, and issuing tokens to identify the caller
Tokens contain only a User Id and OAuth scopes, and are therefore easily sharable between multiple APIs
The API's role is to collect claims and deal with business authorization, and this tends to involve different domain specific data for each API
You could have two types of claims, admin and user. For admin users, you add the admin claim (if the claim not present the user is not admin).
If the user claim is not there, he is not an user at all. And if none of the admin/user claim is present then he is a guest. This is one approach.
I'm working at a company where we have a standard JWT token given to an end user. This user will get their JWT access token by going through the authorisation code oauth flow. By passing their access token into the Authorization header they can make calls into the microservice api's.
We now have a scenario where we need someone from the customer service centre assume the identity of an end user for the purpose of giving the service centre representative access to the users data for short period of time.
To solve this we have discussed having two access tokens flowing into the Authorization header in the microservice api's. The first would represent the customer service centre representative and the second would be the users access token but i am confused on how to best architect this solution.
Can anyone recommend a good solution staying as close to open id connect standards as possible. Microsoft seem to have an oauth flow named on behalf of which kind of matches what i want but seems more like it caters for a system on behalf of a user where I want a user on behalf of another user.
thanks
LONGER TERM
User Managed Access may provide solutions in this area:
End User sets a policy at the Authorization Server for their personal resources
A Company Administrator applies a policy at the Authorization Server for corporate resources (for multiple users)
A Requesting Party (app) presents claims as proof that they meet the policy
REAL WORLD
Almost no Authorization Servers support this capability, and even those that do may not do what you want. It is more than an OAuth pattern though, since a solution also ties into back end behaviour.
WHAT I WOULD DO
Build a solution around claims:
Service centre user logs in, to establish their own identity
After login, lookup claims, to see if the user has 'super' rights
If so, your UI presents an option to act on behalf of another user
Service center user types in email of who they are acting as
Update claims with the second identity
Authorization needs to take both identities into account
Auditing needs to log both identities
The above list hints at requirements, and of course not all of these can be solved with OAuth, but claims should give you the flexibility you need.
See my claims write up for how you could apply this pattern to collect claims from multiple places - not just access tokens. In your case, the ApiClaims object could include your database user ids for both users.
I have a webapp which asks user several questions and store answers. User logs in via OAuth using external provider, then I get user ID information from external SSO server.
I need my app to be used by several users at the same computer, so every time the form is submitted, I need to log out the user. I can do it easily in my app, but then I redirect user to OAuth server again. OAuth server remembers user, so it gives the code of previously logged user right away. I want users to log in again at OAuth server though, but how can I do it? Is it possible to ask OAuth server not to remember the user that had logged in previously?
From your question the actual flow is a bit unclear, however, there are two options:
The client needs to log out after initial log in. With this, a new session flow will be initiated in the next iteration, forcing the client to have to log in again.
The server needs to not remember consent ("Do you want to allow x on app y."), to ask the client for consent again.
Please be aware of the terms authentication, authorisation and consent have very specific meanings in this context.
You may want to share more details on the situation you are in, e.g. relevant code, the OAuth2 server you want to authorise with, including software, version and possibly url. Also, the client (as in rfc6749) is of importance here, did you implement the oauth flow yourself or did you rely on any library? If yes, which?
This is more of a general question but I hope it is still valid for SO.
So far I have learned, that in general, a mobile app (such as official Pinterest app) use the Password credential flow to let their users login and access the API directly. (let's just assume they use OAuth for this)
So they collect username and password, send it to their server and get a token in return which is used for subsequent requests.
Now a user did not want to register and created an account using e.g. Facebook as the authorization server. So my question is:
How is this flow implemented?
My educated guess:
User chooses "Login with Facebook" in mobile app
Facebook Login Page opens with return_uri = mobile app
Mobile app receives auth token
Mobile app uses client credentials and says the API: Use this token for user X
Is this correct?
First of all, apps should not use the Password Credentials Grant. The specification is rather clear about it:
In the traditional client-server authentication model, the client
requests an access-restricted resource (protected resource) on the
server by authenticating with the server using the resource owner's
credentials. In order to provide third-party applications access to
restricted resources, the resource owner shares its credentials with
the third party. This creates several problems and limitations
The specification then goes on describing those problems.
And about the Resource Owner Password Credentials Grant:
The authorization server should take special care when enabling this grant type and only allow it when other flows are not viable.
The entire purpose of OAuth 2.0, I to not have to use something like the Password Credentials Grant, where the user hands over their password to the application.
About your second question: what happens when a user does not want to register and create an account with your app, but wants to use e.g. Facebook for authentication?
Remember that both the Implicit Grant, as well as the Authorization Code Grant, work by using a browser control to authenticate the user. In that browser session with the Authorization Server, you are free to authenticate your user in any which way you want. Certainly, you can use your own user/password database, but you could also use other mechanisms, such as WS-Federation. In your case, it sounds like the user want to authenticate using Facebook.
Authenticating using Facebook is then not done by your client app, but by your Authorization Server. It typically does that by using the Facebook Authorization Code Grant, followed by a call to read the user's profile to obtain their Facebook user id, name, and so on.
If you do not want to build such an Authorization server yourself, you can use an existing one. Several companies offer login-as-a-service solutions, including the one I work for.
UPDATE: You asked several follow up questions in a comment below. I'll answer them briefly here:
First of all, the fact that some companies that use OAuth to secure their services allow for a Password Credentials Grant, does not imply that you should. In fact, there are probably more examples of companies that don't offer this possibility, than companies that do.
There are real trust issues, and real security risks with sharing your password with a device app. To start with, the app on the device is easier to hack than a server. Furthermore, if you give the app your password, presumably that app also needs to store it somewhere for future use. As a user, I just have to hope that that storage is safe form possible malware running on my machine. For more issues, see the introduction in the OAuth 2.0 specification mentioned above.
Secondly, all good Authorization Servers differentiate between First Party Clients and Third Party Clients. A First Party Client such as yours is controlled by the same company that controls the Authorization Server, and for such an app the Authorization Server does not ask for user permission to share data, since it makes no sense to talk about sharing data with yourself. That is why the web sites of these companies don't ask you whether you allow to share the data they hold on your behalf with them. They already have it, and there is no "sharing" going on.
Of course, you might argue that you have never seen any of these companies talking about this distinction between First Party Clients and Third Party Clients. But the reason they don't should be obvious: when you deal with them, you are always a Third Party App. They don't need to tell you that they treat themselves differently.
The mechanism I would choose in your scenario depends on the nature of the client app, and the nature of the services it accesses. What are your requirements?
Anyway, if the device the application is running on has a secure storage facility, such as Windows Phone 8.1, I would probably consider using the Authorization Code Grant without client credentials. That way, the user never has to log in again. If we're talking about a web site or a SPA, I would consider the Implicit Grant (where the "remember me" feature, if any, is offered by the Authorization Server). Again, the specification gives advantages and disadvantages of each grant type for several scenario's.