WIF STS, different "kinds" of users, applications and claims - authentication

We are currently looking into implementing our own STS (Microsoft WIF) for authenticating our users, and in that process we have come up with a few questions that we haven’t been able to answer.
We have different kinds of users, using different kinds of applications. Each kind of user needs some special types of claims only relevant for that kind of users and the application belonging.
Note that we do not control all the clients.
Let’s say that all users are authorized using simple https using username and password (.NET MVC3). A user is uniquely identified by its type, username and password (not username and password alone). So I will need to create an endpoint for each user type, to be able to differentiate between them. When a user authorize, I’ll issue a token containing a claim representing the user type. Is there an easier way for doing this? Can I avoid an endpoint for each user type (currently there are three)?
My token service can then examine the authorized users’ token and transform the claims, issuing a token containing all the users’ type specific claims. So far so good, except for the multiple endpoints I think?
If I need to have multiple endpoints, should I expose different metadata documents as well, one for each endpoint? Having one big metadata document containing a description of all claims, doesn’t make any sense since there is no application that needs all claims.
Update
Some clarifications.
Certain applications are only used by certain types of users. Not one application can be used by multiple user types.
Depending on what type of application the request is coming from, username and passwords needs to be compared for that user type. There are user stores for each type of application. That is why I need to know what application type the request is coming from. I can't resolve the type by the username and password alone.

Based on your problem description, it sounds like you have three indepent user "repositories" (one for each user type).
So imho this would be a valid scenario for three STS or a STS with multiple endpoints.
Another way to solve this could be to distinguish the user type by the indentifier of the replying party redirecting the user to the sts. This identifier is submitted in the wtrealm parameter.
The processing sequence could look like the following:
Get configuration for relying party (wtrealm) from configuration store (I'd suggest a database for your rather complex case)
Validate user with username, password and user type (from relying party configuration)
Add claims depending on user type or relying party specific configuration.
The datasbase/class structure for this could look similiar to this:

Need some more information to answer:
Are certain applications only used by certain types of users? Or can any user type access any application? If the former, you can configure the STS for that application to pass that user type as a claim. Each application can be configured to have its own subset of claims.
Where is the user type derived from? If from a repository, could you not simply construct a claim for it?
Update:
#Peter's solution should work.
Wrt. the 3 STS vs. 3 endpoints,
Many STS - can use same standard endpoint with different "code-behind". Would still work if you migrated to an out-the box solution . Extra work for certificate renewals.
One STS - custom endpoints won't be able to be migrated. Only one STS to update for certificate renewals.
Metadata - given that it can be generated dynamically, doesn't really matter. Refer Generating Federation Metadata Dynamically.

Related

How to manage user updates and deletions in OIDC and SPA architecture

i am making a set of applications that share a common oidc provider (in my control), where the users will be created.
One of my applications is a stateless SPA "meeting" app where you can schedule meetings with other users, and you login purely by an OIDC token.
I am having a hard time thinking a strategy about the following
Should the "user" details be stored in the meeting app after a login? So let's say user A exists in the provider, then enters the meeting app. Should i save user A in the meeting app DB?
How to handle change of user details? Let's say user A changes name to User B in the provider. Until he logs in again, all the other users see him as User A still in the "contacts" list. What is the usual practice for solving this?
How to handle deletions in the provider. I need someway to signal that "deleted in provider -> deleted in app". Should i constantly poll the provider and get any missing users, create a push system, or is this just unneeded?
Thanks a lot in advance
That's actually a very good question and rarely explained well in online articles. Hopefully the below detailed notes help you with your solution. I have answered your questions at the end.
OAUTH USER DATA
Typically the core user data such as name, email etc belongs in the Authorization Server. It contains Personally Identifiable Information (PII) and changes are audited there. This is explored in further detail in the Privacy and GDPR article.
DOMAIN SPECIFIC USER DATA
This might include fields like a user's application preferences, and you may end up with data similar to this in your APIs:
Field
Description
id
A database surrogate key for the user
subject
The subject claim from an OAuth access token, which is typically a GUID or something similar
archived
A boolean flag set to true when a user is active in the app
field 1
A domain specific value
field 2
A domain specific value
To get OAuth user data within your applications your APIs can call the Authorization Server's SCIM 2.0 endpoint as described in this User Management article.
AUTHORIZATION AND ROLES
Interestingly, roles and application specific rights could be stored in either of the above data sources. You may want to start by putting roles in the OAuth data, but for cases where they are very domain specific and change often, I have found that storing them in my own API data works best.
DOMAIN SPECIFIC USER DATA AND ACCESS TOKENS
Sometimes you need to include domain specific user data (which might include roles) in access tokens. This Claims Article explains how claims can be looked up from external APIs during token issuance. This typically involves a REST call from the Authorization Server to one or more APIs, providing the subject value for which tokens will be issued.
CONSISTENT USER IDENTITY IN YOUR APPS
A user can potentially authenticate in multiple ways, such as default password / corporate login / social login. You may need to use some custom Account Linking logic to ensure that the subject field in the access token gets the same value in all cases. This prevents you ever creating duplicate users within your application.
USER INFO CHANGES
These are typically made by end users within an application screen, and your APIs then call SCIM endpoints to update the core OAuth data. A common case is when a user changes their name and / or email, eg if the user gets married. Note that the subject value remains the same after this edit.
USER ADMINISTRATION
In scenarios where corporate assets are used, an administrator typically provisions users, either individually or in bulk. This can be done via the SCIM endpoint. In some cases administrator actions may need to save data to both data sources - eg to create a user and set roles + application preferences.
USER INFO EVENTS
Sometimes your application needs to know about a user info event, such as new, deleted or changed users. This can be managed via Event Listeners, where an extension to the Authorization Server calls back your domain specific APIs when a user edit occurs. When a user is deleted in the OAuth user data you might then update the user's application state to archived.
DATA MIGRATIONS
Finally it is worth mentioning that the above also supports migrating to an OAuth architecture or between providers:
Get a combined view of the user data before migration
Insert all existing users into the new OAuth system via SCIM
Update the combined view of the user data with new subject values
Update your domain specific data with new subject values
SUMMARY
So to answer your questions:
Aim to avoid this because it adds complexity, though in some cases you may need to denormalise for performance reasons. The OAuth user data should remain the source of truth and the only place where edits occur to PII data.
Your meeting app would need to join on the OAuth user data and domain specific user data and present a list. This would probably involve caching a combined view of the user data.
See Administrator Events above. Your API should be informed of OAuth user data changes via an event, then your SPA would get current data on the next refresh.
When implemented like this you end up with simple code and a well defined architecture. Some providers may not provide all of these features though, in which case you may need an alternative approach to some areas.

How can I define policies for my API for two types of access tokens, one with an identity (sub) and one without?

I am using IdentityServer4 via ASPNET Core, and I want users to access my API both by the web browser via their identity (Implicit and Hybrid), and by clients programatically (Client Credentials). I realize all I have to do is add AddIdentityServerAuthentication and I am done. However, that only solves the authentication aspect of this problem, not the authorization.
Authorization:
With ASPNET Core, you can just use Role based auth (or PolicyServer permissions which is similar) but only if you have an identity with role claims, that does not work for client credentials. So that brings us to needing to secure by role, or policies AND by scopes. How can I do this?
You cant have multiple policies, if you do, they both must pass.
You can't have multiple auth schemes, because my call to AddIdentityServerAuthentication will have to use the same authority, so how would IdentityServer4.AccessTokenValidation/JwtBearer know which you scheme challenge you are trying to pass?
Multiple requirements could work, but you need to add extra requirements on the condition that you are dealing with a non-identity access token. How can you detect what type of token you are dealing with? Is it safe to just say "If no sub, this is client creds."
Should I scrap this design and force device code flow on my users? Look at az cli it magically opens a browser, and then you can start scripting away to your hearts content. IS4 supports this with ease, especially with verficationUrlComplete
I think I have a working POC, but I am far from happy with it. https://gist.github.com/VictorioBerra/8c333a228c55d86a7c15f7f300284634
It involves basically re-implementing the default scope claim requirement handler and policyservers permission requirement handler. But thats the only way to conditionally apply the requirement handlers based on the token type.
There are at least a couple of ways of how to go around your problem of implementing role based authentication:
You might have misunderstood the fact that a client can have role claims in the client_credentials flow.
You could even have sub claim if you implemented client_credentials_custom flow and essentially bind a client to a particular user account (think of this as a service account)

IdentityServer 4 and scope specific user settings

I plan to use IdentityServer 4 on ASP.NET Core with ASP.NET Identity as the data store. This is the first time I use a central authentication/authorization and I am wondering how to solve the following question:
Assume I have users with claims like name, role etc. and a Web API (scope) that allows these users access to measured values from hardware devices. IdentityServer will allow me to authenticate known users but now I need an access control that knows which users may access which device data.
Where do I store this information? Since it is specific to the scope I guess it should not be stored in the IdentityServers store. On the other hand, if I store it in the scopes own database I somehow need to connect it to the users defined in the IdentityServers store. Should I define user IDs that are unique to all scopes and IdentityServer?
You will need to correlate the User Ids that IdentiyServer returns with users defined in the scope's database.
I believe that there is a User table and a UserLogin table where you could track the different logins for each of your users.
Then, in the scope's database, you can then specify which users have access to what device data.
This is a bad idea and will probably lead you down a road that you should not.
This means that your client application requesting the scopes will need to know which user has access to which scopes even before requesting a token from your IDP (otherwise your token request will not work). Rather model these as user claims. Then on your WebApi you can do normal claim based authorization.

Getting detailed user membership information from Thinktecture Identity Server

I'm using Thinktecture Identity Server for SSO with some apps. The idea is that account information will be stored on the server in the claims information. So groups user membership and other hierarchies can exist on the SSO server. Then when some one authenticates they would get their membership and rights passed down through claims.
My question is how can my authentication subscriber perform a user.memberOf(x) kind of lookup? I can't imagine that the whole permission hierarchy gets passed down in a users claims. I imagine that additional queries would be performed against the sign on server like LDAP. How does this work for Thinktecture? Would it be the same generally for other SSO servers? If so what's the patterns name?
A general pattern is that, yes, you pass all roles in claims. This causes issues if there is too many groups but if this is so then it could be that the role model should be revisited.
Switching to oauth2-style authorization solves the issue: you don't pass claims in roles but then the relying party queries roles with an extra call. The drawback is that if the STS is further feredated with yet another STS, such extra calls become tricky as the call would require another internal call which would possibly require yet another call etc. Passing roles in claims means that there is no need for this extra call.
Yet another idea is switching to a custom STS that would issue claim roles filtered depending on the relying party or other user attributes. This could work as usually a single RP is not interested in all roles but rather a subset that makes sense there. Your filter is then implemented at the custom STS side.
Well - IdSrv is a custom STS. You can issue claims per RP - check this article (especially the part about IClaimsRepository):
http://leastprivilege.com/2013/05/17/customizing-identityserver/

SAML assertion with username/password - what do the messages really look like?

I need to create a some SAML 2.0 assertions, and I'm having trouble finding what the XML should really look like. Most of the documentation seems to be about using particular tools, not about the messages. I've got the schemas, with a plethora of possibilities, but I can't find an example of what the relevant messages actually look like in practice.
The business rule says: in order to create a shared identity, the user tells system A their username and password on system B. System A needs to communicate this info (along with some demographics) to system B. System B validates the information and passes back a unique identifier which can then be used to refer to this user.
Could someone give me an example of what SAML 2.0 assertions would look like to carry this information?
FWIW, I'm using C#, and need to pass the XML around in ways which preclude using a 3rd-party tool.
I'm not sure your use case is quite what SAML 2.0 does.
What you describe as your business rules actually looks like a use case for identity provisioning, not access management.
Standard SAML 2.0 use cases focus on one party asserting identity (the identity provider) and the other party (or parties) relying on those assertions (the service provider). Assertions carry what's called a name identifier, use of which is agreed ahead of time between the identity provider and the service provider.
These name identifiers can be pretty much anything, but they broadly fall into two categories: transient and persistent. A transient name identifier is only useful in the context of the current session (and essentially only says, "I know who this person is") and tends to be used to protect the identity of the principal while allowing privileged access of some type. A persistent identifier can either be opaque (in a similar way to how OpenID is used to access SO) where the asserting party can repeatedly verify a principle's identity without disclosing their identity while maintaining a dynamic but stable shared identifier between the asserting and relying parties or more substantial, such as an Active Directory UPN (which can be pre-agreed ahead of time).
When it comes to passwords, as you mention in your question, the service provider (relying party) never sees the users password. The service provider hands the user over to the identity provider with an authentication request. The identity provider sends the user back to the service provider with a response, which in the case of successful authentication contains an assertion about the identity of the user in the context of the relationship between the identity provider and the service provider.
In context of your question, the big thing is that SAML 2.0 does not provide a way to either create the local "application" user account or link that local user account to a federated identity. This is simply not the problem SAML 2.0 tries to solve.
Now, back to your business rules...
It looks to me like what you're trying to do is either account linking or registration - I would approach it like this:
User visits application, clicks a button to use identity from the identity provider
The application produces an authentication request and directs the user to the identity provider, carrying that authentication request
The identity provider either logs in the user or reuses an existing identity session if the user has one. The IdP produces a response message containing an assertion about the user. In your case this assertion should at minimum carry a persistent name identifier. The identity provider directs the user back to the application, carrying the response message.
The application processes the response message. If a mapping entry exists for the persistent identifier passed the user is recognised from that mapping and logged in as that local application user. If no mapping entry exists the user can be asked to locally log in, and on successful local login the mapping entry can be produced, or a user account could be automatically created and the user could be asked to enter additional information (names, email addresses, etc.) The "corporate" use case would be that no automatic account linking or creation is allowed and that the mapping must exist ahead of time.
As for the content of the messages...
The OASIS Security Services Technical Committee has a zip file download available with extensive documentation of the parts of the XML schema, including examples. It's also well worthwhile reading the protocol and profile documentation, as these describe the flow of messages between the parties involved in the identity conversation.
There are a large number of presentations floating around that I found very useful. Specifically, SAML v2.0 Basics by Eve Maler helped me start realising what problems SAML v2.0 was trying to solve. This presentation includes examples of that assertions look like. There is an updated presentation and links to additional resources on saml.xml.org.
I'm not sure if any of this is going to help though, as your use case does not seem to be what SAML 2.0 is trying to do. You can add attributes and extensions as needed to requests and responses, but I can't see many identity providers doing anything with those attributes and responses.