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.
Related
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.
In our project, we are using oauth (implementation - apifest) for token generation and validation. I am unable to understand the scope concept.
As per my understanding, oauth scope is used for authorization, which consists of some permission.
We have capability and role concept in our project, where:
Capability - permissions
Role - group of capabilities.
A role will be assigned to a user, based on which he functionality across application will be defined.
Role creation is dynamic.
Is this role concept the same in oauth? or is the scope defined at application level, where the users in that application will have the same scope?
I tend to think of Scopes as a permission (or entitlement) to perform some action.
A role is typically a collection of permissions required to perform a "Job" or work within a "Project"
OAuth has no concept of a "Role"
Scopes are Requested by the client but are only Granted by the Authorization Server.
Scopes requested may not be granted and additional scopes may be granted that were not requested.
Scopes are used to delimit which applications can act on the behalf of the resource owner.
If you have an application, say a voting service, at voting.example.com. You have two roles: voters, which can see a poll, and vote, and admins, which can see the full results. The voting application enforces permissions based on these roles. A local user is assigned a local role. The application is protected using OAuth, so a user can be identified by a token.
You also have a social network app, social.example.com. This app provides a page where users can vote on the voting service. It is also connected to the same OAuth authorization server.
Finally, someone else has a reporting app, reports.example.com. This app would like to allow users to see the vote tally by requesting it from the voting service. It is connected to the same authorization server.
The authorization server, say iam.example.com. The authorization server has three clients, one for each app described above. There are two scopes defined in the authorization server, voting, and reporting.
The reporting app, when you login will request the reporting scope. The actual login happens on iam.example.com which will grant the token to reports.example.com. The login form will ask you, the user, whether you grant the client (reports.example.com) the right to act on your behalf and obtain reports from the voting service (provided by the reports scope). The scope will be recorded and associated with the token it sends to reports.example.com.
Now the reporting app can make a request to voting.example.com which says, "I would like to see the voting tally" The voting.example.com app will check the token, and provided it has the reports scope, it will send back the tally.
If it tries to make a request to the voting service to vote, it should be refused by voting.example.com, because the bearer token does not have the scope allowing you to vote. This must be enforced by the voting app. The authorization server manages which client is granted which scope. Only to see the reports. This is not related to your role in the voting application itself.
OAuth itself doesn't provide a mechanism for identity validation, so you do not have a mechanism for validating who you are from the token, and what roles you have. OpendID connect (OIDC) provides extra functionality for this by providing a scoped based identity endpoint protected by the authorization endpoint which allows it to reveal your identity to the app. So if we assume you have OIDC too, then it will check, from the token, who you are. It can then check it's database to see whether you have the right role, and whether you are allowed to see the tally before sending it.
What the scope enforces, is that the reports app, using it's client, can obtain a token to act on your behalf and ask for the information. When you grant the client the scope, you are allowing it to communicate with the voting service to obtain the information.
Roles are managed by your application and with a permission system, determine who can vote, who can read the votes.
Using something like OIDC, you can extend OAuth so the token identifies who you are. voting.example.com can then check that you are a) authorized to vote (by the local logic), b) that the application doing it on your behalf is allowed to act on your behalf (through the scope attached to the token).
I am working on a REST API that will be used by a number of clients in different organizations. To be more specific, a client application in an organization will connect to the REST API to exchange information. Multiple users can use this client application. Authentication should be handled by the client application in a way that there is not interaction with the user.
How can this be achieved with Azure Active Directory taking into account that:
I only would like to create one AD user account per organization and not per user in that organization.
A user of the client application should not be aware he is talking to my API, hence he should not authenticate.
The client application should authenticate with the AD account that was provided to the organization.
When an incoming call is received through the REST API, I should be able to identify the calling party.
The examples that are outlined here: https://azure.microsoft.com/nl-nl/documentation/articles/active-directory-code-samples/ never completely cover this scenario:
In the daemon example there is no user interaction, but then I should create a key (secret) for every organization. This seems quite complicated to handle.
In the other scenarios there is always user interaction.
Authenticating with a username and password without user interaction is only supported in .NET: http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/
Any guidance in pointing me to the right direction would be highly appreciated!
I think the question misunderstands the daemon model. In AAD, you create a single application with a single key and then a service principal is created per organization. You only need one key - and you can identify the calling organization by looking at the tid claim in the access token.
I recently learned how OIDC provides user identity on top of OAuth 2, and also managed to create an OIDC login to my webapp. However, when it comes to the authorization part, it is unclear how the application should know what scopes to request for the API?
For example, certain endpoints should be protected with the 'admin' scope, as well as respective UI elements should be hidden from non-admin users. The enforcement part I can implement easily, but when the user logs in, the app needs to know if the user is an admin or not - i.e whether or not to request the 'admin' scope / show the admin-related UI parts.
Is there any standard way of representing app-specific details in the user profile that comes from the IDP? What disturbs me most is that such information - to my knowledge - cannot be added to user profiles that come from e.g Google/Twitter/Facebook, so one needs either a) an extra layer (IdentityServer/OpenAM/etc), or b) extra user profile data in the webapp's DB.
My first thought was to add custom claims by doing a) - but when it comes to integrating with existing IDPs, it might not be possible to adjust all the user profiles (e.g large corporate databases), so I am assuming the app itself should be flexible enough to translate existing user profile data to 'admin/not-admin'.
Is there a better solution?
In my opinion it's not a good practice to base your authorization on the claims returned by your identity providers.
This responsibility should be delegated to the UMA server. It's up to him to decide or not to grant a request access to a protected resource.
For example, image that we have the following scenario :
Context : An e-commerce enterprise has internally developed a tool used by his marketing team, to retrieve information about his most loyal clients.
The application has been developed in WPF and interact with a RESTFUL API to retrieve the clients.
Only this application and users that belong to the marketing group are authorized to retrieve the list.
Problem : How the application can access to the protected operation ?
workflow
Solution : the workflow is made of three big steps :
Identity token : retrieve an identity token with implicit grant-type. The token is returned to the client in a callback parameter
RPT token : the identity and access token (valid for the scopes uma_authorization & uma_protection) are passed in the request to retrieve the RPT one.
When it is received by the WPF application, the token is passed in the Authorization header to retrieve the loyal clients. Both parameters are required by the authorization policy.
Check RPT token : the token is checked against the introspection endpoint, this endpoint is offered by the UMA server.
As you can see internal policies are used by the UMA server to grant / or not access to the resource.
Authorization policy is out of scope of the UMA specification, you have to define it yourself :'(.
I have developed a product (open-source) to easily manage authorization policies. If you are interested you can test the demo here :
http://lokit.westus.cloudapp.azure.com/Demo
Note : If you are not satisfied about claims returned by external identity providers, you can always enrich them (read the use case : "assign role to resource owner" in the documentation)
The term "resource owner" is defined in the OAuth v2.0 Specification, as "An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user."
My question is, when is a resource owner not an end-user? I would appreciate explanation through examples that could be real use cases. For example, if the protected resource is a Facebook user's photo, is the resource owner Facebook or the Facebook user who uploaded the photo? Also, why is the resource owner (that is also a person) be considered an end-user if that person is not even a user of the application that is implementing OAuth? And, if the Facebook user is the resource owner, then what role does Facebook play in this exchange?
Resource owner can be a machine, not just people. There are many cases where no humans are involved in the entire OAuth flow, especially in enterprise setups. At least, that's what I meant when I introduced the term in RFC 5849 (and later in OAuth 2.0).
Consider the situation where a resource owner is a corporation, perhaps one with policy that enables / disables access to a resource.
Consider an example of art; let's say you want to make your domicile look better with a piece of art; there are several places you can go to (Costco, for example) where you can choose a piece of art, to have that printed on the medium of your choice in the size of your choice, and delivered to your home.
Here's the thing; Costco isn't the owner of the licensing rights for that piece of art; that's outside of the realm of their business. They sell stuff, they don't collect art. What they do is they negotiate with the content owner (owner of the license for the art) for the rights to use that art in a print, which they then create and deliver to you. You pay Costco for the artwork; Costco then pays the licensor a portion of their payment from you for the right to use the artwork.
This works as well in the situation where you already have a relationship with the resource owner; let's say you've negotiated and purchased the rights to some music, for example. You're not the owner of the music, in that you don't have the right to resell the music; but you do have the rights to listen to it (this is a standard DRM situation). Now let's say that you want to play that music through a website; you can make a request to the website for that music; the website can contact the content owner (licensor, really, but it's effectively the same) with your identification; the content owner can then decide whether or not to grant the website access on your part to the content, based upon your terms.
Hope that clears some things up.
Consider you have a Facebook app.
Now you want to get statistics (in other words, "Insights") on all your users' activity.
In this case, the resource ("App Insights") is owned by your app, not each user.
So your app gets a client access token (called 2-legged OAuth) and access its insights.
Facebook also provide "Page Insights" as a resource which is a page's fan activity. In this case, the resource is owned by a page not by the page's fans, so your app gets the page's access token.
However I can understand your confusion.
Previously Facebook allowed page insights access using either page owner's access token or page's access token.(It means Facebook handled it as a resource both of the page and the page owner; now only page's access token is allowed)
At last, in all case, Facebook acts as "Authorization Server" and "Resource Server". It authenticate users and get approval of the client access to their resources. (Authorization Server). It serves resources too.(Resource Server)
My company collaborates with a screen sharing video conferencing provider. Our users can use their solution as part of our offering. The communication between us and the third party tool takes place through calls to an API, using 2-legged OAuth.
We are not a person, a better wording is perhaps an external system, but we are definitely a resource owner - since we pay for the resources that we use and we are the entity that authorizes the calls to the APIs.
Furthermore, in the Facebook example you mention. The resource owner is the person who uploaded the photo. That person is also the end user. The one for whos benefit a third party application issues API calls.
I would like to emphasize #Paul Sonier's solid response with a more concrete example related to OAuth 2.0.
In an enterprise setting, employees of a company may want to access content on a file storage service (e.g. Google Drive, Box.com, DropBox, etc.) under the aegis of the company's enterprise account.
Such services may already have Single Sign-On arrangements where users' accounts with the service provider are dynamically provisioned or provisioned in bulk.
Importantly, employees typically sign over all rights to any documents or other work they produce to the company. In a legal sense, the company and not the end user is the resource owner.
In such a situation, the OAuth2 authorization step is superfluous. The company, in it's contract with the service provider, might reasonably say, "consider any user session authenticated from our IDP as pre-authorized for all our applications". A service provider could simply skip the authorization step for these apps and, btw, save thousands of employees a confusing step and lots of calls to the support desk, etc.
At the end of the day, an authorization grant just an entry in a data store and subject to policies that are outside the OAuth 2.0 specifications. There is nothing in the OAuth 2.0 specifications that prevents or discourages such "bulk authorization". It's just a matter of agreement between the service provider and the true resource owner.
Note, this application level authorization is distinct from file and directory permissions, which is usually managed out of band as well. I.e. storage services provide a UI for managing user and group level access to files and directories. OAuth 2.0 clients, then, acquire user level tokens (most support only the consumer oriented "authorization code" grant type).
From the spec:
Resource Owner - An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user
From this definition, I read that many entities may be capable of granting access to a protected resource.
As you've noted, human examples are easy to grok - When you request access to my protected photo, only one entity is capable of granting access. That entity is me. I must perform some action to grant your request. Depending on the application this might involve clicking a button, sending a text message, speaking, clapping, whatever. The mechanism by which my action is captured & processed is not relevant to this definition.
Continuing with this example, lets say another entity could grant access to my protected photo. Imagine you are a trusted business partner of the photo hosting service. Or perhaps you're another team at the photo hosting company, and your servers operate within the same datacenter. In this scenario, it might be desirable to automatically grant you permission to the protected photo. If the resource server decided to automatically grant you access (because of who you are), this would represent a second entity. Here, this non-human entity has decided (in all its wisdom) that your access request should be automatically accepted.
The Resource Owner is usually the Foreign Key used to retrieve records from the protected Resource Server.
If a user owns photos in Resource Server, and the photos can be retrieved from the Resource Server with user_id.
The Authentication Server retrieves a user_id in the the authentication process (Username/Password/OTP).
A tamper-proof (signed) JWT token ensures the same user_id is used to retrieve records from the Resource Server.
Authorization Server generates a JWT token (Access/ID) with the Foreign Key: user_id
Resource Server receives the JWT token to authorize the retrieval of records (Resources) owned by Resource Owner (user_id).
SELECT * FROM photos WHERE user_id = '[jwt.payload.user_id]';
Now, replace user_id with any (non end-user) Foreign Key, e.g. transaction_id
SELECT * FROM files WHERE transaction = '[jwt.payload.transaction_id]';
To determine Resource Owner, ask yourself:
What Resource (Foreign) Key is required to retrieve Resource Owner's records from Resource Server?
What Authentication (proof) is required to retrieve Resource Key from Authentication Server?