This question already has an answer here:
Change from Roles authorization to Claims authorization
(1 answer)
Closed 6 years ago.
In our system we have a way to setup users with permissions. They create a group name, for example, Admin and then assign all the permissions for the tasks they would like to do.
For example, they can add AddCompany, ViewCompany, DeleteCompany, EditCompany
This makes it very easy to make different permissions groups and we can control security very easily.
Am i right in thinking that in this instance the group name = Role and each permission is a claim?
Roles-based authorization is used to group users into groups (roles) and then set permissions on the role rather than on individual users.
E.g: In your case you can create Admin role and provide permission to do "AddCompany, ViewCompany, DeleteCompany, EditCompany" tasks.
In this case easier to manage large set of users through small set of roles. This is the most commonly used model for authentication.
Claims-based authorization provides additional layers of abstraction on your authorization strategy. Further, claims are a method of providing information about an user rather than group of users. You create authorization policies that are used to generate a claim-set based on the authentication evidence presented by the user. Then the user presents claims to the application in order to access resources.
A claim is a statement that one subject makes about itself or another
subject. The statement can be about a name, identity, key, group,
privilege, or capability, for example. Claims are issued by a
provider, and they are given one or more values and then packaged in
security tokens that are issued by an issuer, commonly known as a
security token service (STS)
Resources : http://msdn.microsoft.com/en-gb/library/ff649821.aspx
http://msdn.microsoft.com/en-gb/library/ff649821.aspx
http://msdn.microsoft.com/en-gb/library/ff359101.aspx
Hope this helps.
Roles are claims, but not all claims are roles.
In a claims-based authorization system, you may use roles as permissions, but you may use something else as well. On my current project, we have a many to many mapping from roles to permissions.
Related
I'm having some issues with getting the currently signed-in user's username from Azure b2c to my Blazor web app. Essentially, I want to make a username account where a username is the User Principal Name. I was originally using an email sign-up policy with a display name as the username. However, b2c doesn't enforce display names to be unique, so there's an inherent issue with that. No claim comes back with a username in it, so I have no way in my Blazor app to keep tabs on who is signed in or display their username. There are a few options I can do, and I'm curious which one is the easiest to implement/how to implement it, cause I've been ripping my hair out with this the past few hours.
On b2c account creation, take User Principal Name and also make it the display name
Have the user principal name be sent via claims (Not sure how to do this)
Do Email sign up with Display Names, but somehow enforce b2c to ensure display names are unique
Some other way to have a unique display name for users from b2c
Thanks in advance!
You need to use custom policies: https://aka.ms/ief. Username is not returned in the token with User Flows.
Using custom policies, you can sign up the user using username, and return their username (signInNames.username attribute, shown as userPrincipalName in the Azure Portal) into the token.
You can quick deploy custom policies using my tool here. And quick deploy the username sample using this page with the sample folder name username-signup-or-signin.
If you need any additional claim you need to enter in your Azure AD BC tenant and configure the Application Claims from your User Flow, in the following example the User flow is called B2C_1_signupsignin:
The above example, as you can see, lists all the other available claims, because dome claims are always returned, as the User Name.
You can configure the claim (mode) used to login in the Identity Provider:
Than the claims you receive are the following:
But as you can see there isn't any userPrincipalName or signinNames.
This is a known issue in Azure AD B2C and including this claims from the user flow manifest doesn't work.
The only solution I've found is to upload your custom policy and add a:
<OutputClaim ClaimTypeReferenceId = "signInName" />
but this works only for local accounts.
If you want to add signin names also for external (social) accounts you need to map them, like:
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="upn" />
look at the base source XML here:
https://github.com/azure-ad-b2c/samples/tree/master/policies/sign-up-with-social-and-local-account
I am designing a new ASP.Net CORE 2.1 WebAPI and I am trying to figure out the best way to implement an authorization system that will fit our needs. Our roles and permissions are database driven and can mix and match both role-based and individual resource permissions. So for a given endpoint, the default access may be role based (say Admin only), but the administrator may also assign individual users access to that endpoint (or the opposite; and revoke access to a specific resource otherwise granted by the role). As a result, each endpoint authorization requires a DB query to determine valid access to that resource. It seems to me that a custom authorization filter is needed here, but a lot of MS docs and other resources push Policy-based auth and recommend against "rolling your own." I don't see how a policy based solution would work here, since it's based on static policy claims. Can our needs be met with policies or is a custom auth filter the way to go?
Policy auth is the way to go. Yes, it might be based on a somewhat "static" policy, i.e. multiple actions/controllers may end up using something like [Authorize(Policy = "MyPolicy")], but policies themselves are not static. You can define any number of conditions inside a policy handler. You may also mix and match. So, if say something is only available to a "Foo" role, but you also need object level permissions defined by a "Bar" policy, you may certainly do something like [Authorize(Roles = "Foo", Policy = "Bar")].
I'm currently designing a system using asp.net core and I'd like to implement claims based authorization, but one particular part is confusing me.
When a claim is made the claim will include the type and the value and optionally an issuer. In a handler this claim and the issuer may be checked before access is confirmed.
However this issuer is not stored in the Identity db, so how does the handler then check the issuer?
Am I misunderstanding how this all works? My understanding was that a user makes a claim of some type, that their claim is of a certain value and the issuer is the validator of the claim type actually having that value for that user.
The handler will check the value and may check the issuer but it can't when the db does not store it. I don't understand the point of the issuer then.
I'd like the user to have a collection of claims, including who/what verifies those claims and for the application to at any time be able to verify those claims.
Please help me understand.
I have tested this as so:
Using a asp.net core app with Identity.
Register a user.
Add a claim to a user that includes a type, a value and an issuer. (for example, EmployeeNumber, 312, Microsoft.
Add an [Authorize(Policy="MicrosoftEmployeesOnly")] on a controller/action to restrict access.
Add the policy into services in StartUp.cs with a requirement.
Add requirement code that has a handler that checks the user has a claim of type EmployeeNumber, has a value and it is issued by Microsoft.
Login and the users claims will have been loaded in from the db into the identity.
The handler will fail to validate the user because the issuer (Microsoft) has been lost and now just says Local Authority.
The only thing I can think of here, is once the claim is added in to the db, it is considered validated by Microsoft and now held by the app (Local Authority) on behalf of Microsoft.
If that's true then:
Why check the issuer at all in any handler?
How do you revoke a claim?
I would prefer to be able to optionally go to that issuer and check the claim whenever I want, meaning the issuer could revoke/invalidate the claim. The employee makes the claim they have an employee number at Microsoft and initially Microsoft validate that. Some time later, Microsoft kick the employee out and on their system remove him. The app should be able to check with Microsoft each time the user logs in to see if the claim is valid. In this case it would not be valid any more.
Am I going slightly mad?
Posting this here as you linked to this question from my blog, and it may be useful to someone
I think you have misunderstood slightly about the nature of a claim,
which I can understand given the terminology. You seem to be taking
'Claim' as meaning the user is 'professing' that they have a certain
attribute, and you want to check that this is true.
That is not the way claims work here. Claims are essentially
'attributes' of the user. In the old way of working with roles, a user
would belong to a certain number of roles. These are just 'attributes'
the user has now, so are more generic. A user may have a number of
claims corresponding to the roles they are in.
The identity of the user is checked during authentication, and at that
point you assign the set of Claims that the user has to the
ClaimsIdentity object. This is the point you fetch the claims from
the database, and make sure they only get the ones they should have.
If you need to have someone verifying claims, then you would need to
have that whole process happening outside of this. Only the claims
which have been confirmed should be added to the ClaimsIdentity.
Now, there is an event you can handle on the
CookieAuthenticationMiddleware to validate a security ticket when it
is loaded on subsequent requests called ValidatePrincipal, but I'm not
sure if this is actually what you need.
And your subsequent response:
Thank you for your response. I understand now that these claims are
effectively verified claims once they get into the db. I guess they
could be removed from the db as a way of revoking the claim.
However, I think, as you suggest, the best way is to have this system
outside and it just provides claims as and when required. The design
is that the application will have accounts for different types of
entity and accounts will be able to make claims, for example that "I
am a parent". The parent would seek an authorizing account to validate
this. This might require the authorizing account holder to actually
see some real documentation before validating. Other claims, could
change. For example a parent with Parental Responsibility would need a
bit more verification, but may also lose that Parental Responsibility
in the real world and so a facility for revoking the claim needs to be
available.
So, I think the design should be to use the claims system with the
Authorize attribute following your excellent articles, but have a
separate system that allows for validation and revoking that feeds
that claims system.
I am trying to understand the security model behind .NET based on claims for the application (Relying Party).
I know there are 2 major classes:
ClaimsPrincipal - security context for the running process
ClaimsIdentity - stores information about the user - authentication status and claims
The thing is, ClaimsPrincipal contains just a collection of identities and points to the currently used one but as far as I know, the principal usually never contains more than 1 identity and even if it would - the user is never logged in with 2 or more identities.
To me, the ClaimsPrincipal, other than using it to get the current identity, excuse my ignorance, it's useless.
What am I missing other than what I stated and let's say backwards compatiblity in regard to the ClaimsPrincipal class?
The thing is, ClaimsPrincipal contains just a collection of identities and points to the currently used one but as far as I know, the principal usually never contains more than 1 identity and even if it would - the user is never logged in with 2 or more identities.
This is a wrong assumption. In fact the ClaimsPrincipal in context will always have more than 1 identity if your application requires n factor authentication (n > 1).
Try looking at it this way.
Principal = User
Identity = Driver's License, Passport, Credit Card, Google Account, Facebook Account, RSA SecurID, Finger print, Facial recognition, etc.
If you're pulled over by the police, they don't verify you're who you claim to be, based on your driver's license alone. They also need to see your face. Otherwise you could show anyones driver's license.
Hence it makes sense, why authentication can and sometimes should be based on multiple identities. That's why 1 ClaimsPrincipal can have any number of ClaimsIdentity.
As stated above a user is of type claimsprincipal which is made up of claimsidentity
I made a diagram to easier explain it:
I would highly suggest you read this if youre struggling with claims
https://andrewlock.net/introduction-to-authentication-with-asp-net-core/
One important security principle is "who says" i.e. do we trust the party that is asserting the claims against the identity, so for a particular ClaimsPrincipal we might have different identities each of which is asserting a different set of claims, which allow us to determine the overrall access control in the application,
Let's take the example of an enterprise application which is being authenticated via Windows Authentication where we also want to assert some access control based on teams or departments which are in the application database.
Using the ClaimsTransformationManager we can unify these two sets, i.e. after authenticating the user we can look up the user's team/department in the database and create a set of claims issued by the application.
So now we have the roles (which are claims under the hood) being asserted by Windows and an application identity asserting the custom claims of teams or department.
I m using Angularjs project and using Asp.net identity custom storage provider with Enterprise library for token authentication.
Implemented custom userstore to create an account.
[Authorize] attribute works well after logged in. i want to restrict the method for particular user.
So tried to implement [Authorize(Roles="Admin,User")].
Here one user can have two roles in practical. But as per the system, when user login, we restrict the user to select the particular role.
So, after validated by asp.net identity, user should select any one of the role.
Here my need is,
I want to maintain the role which he selected (we consider this concept like impersonate user, but not exactly).
Or,
Need to implement in the Authorize attribute itself.
I've seen some of the examples like we can add claim to identity.
But I can add custom claims only inside the method,
GenerateUserIdentityAsync
in my case I need to add claim after log in validated. I've gone through some example and implemented like following.
ClaimsIdentity identity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie);
identity.AddClaim(new Claim(ClaimTypes.Role, "Test"));
After added claim, when I try to get the claim to check the logged in user role,
List<Claim> claim = claims.Where(c => c.Type == ClaimTypes.Role).ToList();
I didn't get the Role "Test".
Here my bad luck is, in claims, I've all the roles of the user except role = test
How to authorize the user role or maintain logged in here..
I see at least three solutions for your problem:
Use a claim transformation to filter the role claims, to match a role the user choose. You can use a claim transformation middleware or you can filter the claims during login (be aware, that you do not know the user roles BEFORE login, and afterwards filtering might be too late). PRO Does not necessarily need session state; CON User can not choose during runtime.
Store the role in the session and authenticate against that role. Make sure, that you check against the role claims, when the user chooses his role. PRO User might change role without re-sign-in. CON Needs session state (Might be an issue in farm environments).
Don't do it at all and I'm totally serious about that. Provide your user a clean interface, that makes him know, what role he has and use areas and other technics to separate the concerns.