I have used IdentityServer3.EntityFramework library to keep all configuration in SQL database. Also I'm using IdentityServer3.AspNetIdentity plugin for identity management. I can't find out how to link / map these 2 database together. I mean base on which concepts.
Do I need to have UserId in Config database or should I match user claims with config claims ?
The claims in the ASP.NET Identity database are claims about that user. This will include a claim type and a claim value (e.g. given_name and scott).
The scope claims within the IdentityServer scopes are what claim types a token can contain if the token has that scope. This is only ever a claim type (e.g. if I request a token with the profile scope, it can contain a users given_name).
The client claims within the IdentityServer client applications are what hardcoded claims that client application will receive in a token. This will include a claim type and a claim value (e.g. client_name and mvcapp).
If your request from client application contains scopes, you store them as role/claims in asp.net identity database. Then compare with scope table in IdentityServer3.EntityFramework database.
Related
Is there a way of using Keycloak only to Authenticate user, but with own mapping to roles with Spring?
I would like to authenticate API Gateway in keycloak first, but then provide internal JWT Token with authorized roles inside my microservice world.
In this article, I do map Spring authorities from roles that Keycloak sets in JWTs. Is that what you are looking for?
If what you want is having a hand on access token claims, two cases:
the claim is already in the token but with a different value than what you expect (missing roles, outdated email, ...). Then, it is very likely that Keycloak admin API exposes what you need to update users data. Check that a "confidential" client with required roles is declared with client-credentials flow enabled (or declare a new one) and have relevent resource-server call admin API for updates (with WebClient, RestTemplate, #FeignClient or whatever is capable of using client-credentials flow).
the claim does not exist yet. Then, define a new Keycloak "mapper" to add a private claim. Here is a sample. You can have a look at security module to figure out how this new private claim is parsed (by ProxiesClaimSet) into an Authentication custom implementation.
In any case, the authorization-server (Keycloak) is the only place to define claims, issue JWT and sign it. JWT validation by JWT decoder on resource-server involves much more than just checking expiration date: issuer, issued-at, token integrity (server signs the payload with a private key and exposes a public one to ensure the token content was not modified), and more are verified too.
You want to make access control inside resource-servers? Great! Ensure that authorization header with Bearer access-token is forwarded by the gateway from client(s) to resource-server(s) and configure your resource-server(s) as described in the article above.
P.S.
In the article you'll also find a way to test security rules (both unit and integration) with mocked authentication. This is what, in my opnion, makes resource-server(s) a better place to implement access-control: security rules are of primary business importance and fine grained unit-testing is essential.
Other note, if you go for additional private claim(s) with Keycloak mapper(s), pay attention to pom.xml file, java/main/resources and implemented interfaces of ProxiesMapper into proxies-keycloak-mapper module.
Last, you should also follow the first 3 of those tutorials (for real: write the code and run the tests), it will take you less than an hour and will save you many more hours struggling with your resource-server(s) security implementation.
I am in the process of expanding our login options on our product to support MS Identity Platform, to be able to use Azure AD login (and gain SSO/MFA with that)
Currently we are using .Net Core + JWT (JwtBearerDefaults.AuthenticationScheme)
The environment is angular clients, .Net Core APA, and a back-end database.
I have the setup working.
My challenge is that in our business model and backend database we have ~2.000 userrights and our own User/Role model granting access.
I am currently getting the IdToken from MSAL and in my proof of concept using the oid to couple the Azure ID with our User model.
But, in our existing JWT solution, our access token holds claims about the User Id, but also the role, and another property (Unit/Vessel) determining access. From these three properties we can verify against the 2.000 userights on API side whether or not a request is allowed or not.
I would like to keep this information (User, Role, Unit) in the token - but have doubts on how.
Constraints:
We cant create/use Azure claims. We have too many, and customers will manage the Azure application - while we create, add, remove rights for each version of our software.
Azure don't know about role/unit data - and these are different for each customer - so that information can't be in Azure either.
My best idea is outlined below - would this approach be correct, and live up to the way ID/Access is separated?
I hope someone can give me some feedback on this.
My idea is, that the Angular client gets the Azure IDToken. I then use the Azure IDToken, call our API, which on server side, validates ID Token, and then grants me an access token, which contains the user, role and unit. This token is not Azure'd at all, just a token generated by our API - which again will be the only one validating it). Pro's on this approach is also I can keep one type of Access Token, no matter which IDToken is supplied by Azure or our own API.
Tried to outline the flow below in this DrawIO diagram.
I hope someone with more experience in the Token field can validate if this would be a viable approach?
Best regards
/Anders
This is a viable approach except for one thing.
Do not use Id token for authorization.
Your front-end should acquire an access token from AAD for your back-end.
This access token contains the user objectId, allowing you to map the user to a user in your database.
An Id token is only meant for the application that requested authentication and tells it metadata on the user like their display name etc., but it is not meant for authorizing anything.
In any B2B Web application users has to be provisioned against an entity. For example, Acme company users shall be provisioned for Acme entity only.
I am trying to test my user provisioning APIs with OneLogin "SCIM Provisioner with SAML" connector. But I am not sure how to identify the user's organization entity.
Is there any way to identify user's organization entity other than bearer token?
The most 'user-friendly' (integration admin friendly?) way is to use the bearer token. This way the SCIM URLs that a client talks to will always be the same. Additionally, you're enforcing which entity is being affected.
The other (less common) way I've seen an application implement this is by using a unique URL per entity. i.e. https:// entity_name .ServiceProvider.com/SCIMUrl/
But even if you go with this unique URL mechanism, you're going to have to make sure the bearer token was created for that specific tenant (otherwise I can use my token to access another tenant's data)
So you might as well implement it the first way, in my opinion.
I'm almost figuring out how the different pieces of an Authentication and Authorization server architecture work. I really think that IdentityServer is a great piece of software.
I'm trying to summarize my discoveries, to settle a base for my questions.
IdentityServer issues tokens using OpenID Connect. Issued tokens are ID Tokens and Access Tokens.
Tokens are requested - as stated by OpenID Connect protocol - to clients by using OAuth 2.0 flows. One flow for each client.
During the flow beginning, client requests a collection of scopes (at least "openid", that's because he has to state that an OpenID Connect flow has been activated)
A client may ask all the scopes that he is authorized to ask. Using the Entity Framework plugin for IdentityServer, this information is contained in the ClientScope table. If the client requests a scope that he isn't authorized to request, the flow is interrupted.
Scopes may "contain" claims. This means that if a scope contains a group of claims, whenever the client is issued a token, this token contains also all the corresponding user's claims. For example: let call "roles" a scope that contains "role" claim. As soon as the client is authorized, the received token will contain all the user's roles (as claims).
Each requested scope, if authorized, is "translated" in a claim with the name "scope". This means that if a client requests, for example, a defined "api" scope, the generated identity will have at least a claim called "scope" with value "api".
If all of what I've written is more and less correct, here are my questions:
how are claims defined on asp.net identity tables (i.e. AspNetUserClaims) connected to the IdentityServer ones. For what I've seen the matching is made on the name. Is this conclusion correct? In other words, if my client has to receive a "role" claims (because he has asked for the "roles" scope), will the "Asp.Net Identity" plugin for IdentityServer just release the "role" claims defined for the authenticated user?
referencing the "EntityFramework" plugin tables, what's the meaning of the "ClientClaims" table? I cannot get how claims can be directly connected to client... What am I missing?
let's suppose that in my resource server I've an action protected with a ResourceAuthorize attribute like this:
[ResourceAuthorize("Read", "Orders")]
In my AuthorizationManager I check for the presence of a claim "order_read" or a claim "api". Those are two different scopes defined in my AuthorizationServer, one just for "order reading" and the last for a complete API access. The first may be asked by third-party clients, while the latter no. Is that a good practice?
I cannot understand what my client should do with the id_token. Should I ignore the problem, as I'm using the js library OIDC Token Manager? Are the security controls performed by this library?
Last question: when my application presents the Access Token, how is the ClaimsIdentity generated? Is right to say that it's generated after validating the token on the Identity Server? Does this means that IdentityServer will get the access token and translate it in a set of claims?
Thanks for your clarifications!
Marco
Yep, you got the gist of it. As for your questions:
how are claims defined on asp.net identity tables
That's up to you. IdentityServer doesn't mandate an identity management library. The IUserService extensibility point is where you bridge that gap. We have a starter version of IUserService, but it's a code-based NuGet so you can change it to really do what you need.
I cannot understand what my client should do with the id_token
It is mainly used to pass back to IdentityServer at signout time (to authenticate the signout request).
when my application presents the Access Token, how is the ClaimsIdentity generated
There is middleware (AccessTokenValidation) to validate the access token. The result is the claims form the token, which are then turned into a ClaimsIdentity and then made available to any processing downstream (such as your Web API code).
what's the meaning of the "ClientClaims" table
The Client configuration has a Claims property if you'd like to issue claims on behalf of the client. Check the docs: https://identityserver.github.io/Documentation/docsv2/configuration/clients.html
let's suppose that in my resource server I've an action protected with a ResourceAuthorize attribute like this
This is unrelated to IdentityServer, and is part of the IdentityModel library. ResourceAuthorize is a framework for using the user, the resource, and the action being performed into account when trying to decide the authorization outcome.
I am implementing a user service that is storing user info in Azure Table storage. I would like to use a value for tenant ID as part of my partition key, but, the claims available in GetProfileDataAsync and IsActiveAsync are just 5 built in claims (sub, name, amr, idp, auth_time).
I get tenant ID from my identity provider and it's included as a claim in both my access token & identity token. How can I make it available to those methods?
When the AuthenticateLocal is invoke, you return an AuthenticateResult to indicate the authentication outcome. If it's successful you use the ctor overload that accepts the subject and name values. There's also an optional claims collection. If you pass values for claims then you are adding your own custom claims to the authentication cookie at IdentityServer. Those claims are then part of the Subject for the GetProfile API (assuming the requests into those APIs are being done via the browser such as from the authorization request). You can then inspect those claims and use them in any way you want.
If the request is not via the browser, then the only claim you have on the Subject is the user's unique id (which is the sub claims).