Angular2 OpenIddict and Authorizing Roles in AspNetCore WebApi - asp.net-core

I am currently attempting to add Roles to my Angular2 AspNetCore WebApi sample application, which may be found here: https://github.com/tonywr71/Snazzle
Unfortunately, I'm a bit stuck. I have successfully implemented ASOS authentication. The token is returned from the connect/token method, and I can call my custom method with the bearer token in the header, and it will successfully authorize.
Now there are two issues remaining. One is that even though it authorizes, the Name field in the User.Identity object is not set. I got around this by adding username to Claims. And secondly, I want the Roles to be populated so I can use Roles in the Authorize attribute. I have enabled Asp.Net Core Identity in the Startup.cs file, and have configured database. So I would really like to be able to put an Authorize attribute on the webapi method and set the Roles allowed in that attribute.
Any idea how to get it to populate the Name and Roles?

Any idea how to get it to populate the Name and Roles?
To get the username, you must request the standard profile scope. For the roles, add roles.
E.g:
grant_type=password&username=johndoe&password=A3ddj3w&scope=openid%20profile%20roles

Related

How to create integration tests for auth0 private scoped endpoints in ASP.Net Core

I have an ASP Net Core Web API which uses auth0 for authorization and authentication. Moreover, every endpoint is protected with different scopes. For example, to access the endpoint to read all reservations, one would need to have the read:reservations scope.
In auth0, I have roles that contain multiple permissions. Currently, I have an admin role that has access to all endpoints and a receptionist who can only view and edit reservations.
I want to create some integration tests to verify that the authorization works. I am using the Client Credentials Flow as explained here. The problem is that the access tokens I get have no scopes and, therefore, cannot access the endpoints.
At the end of the linked article, it is mentioned that the tokens can be customized using actions. However, I am confused because, as far as I understood, I would have to add every permission manually.
My question therefore is, how could I create multiple access tokens for the different roles that I have to test the endpoints as if I were a person with a said role?

Add user claims after authentication against IdentityServer 4

I have the following projects:
Identity Server 4, with ASP.NET Identity as a user store for all users of all my apps.
.NET Core 5 Web API
Xamarin app
The flow goes like this:
User logins from the Xamarin app (3) and is authenticated against IdentityServer (1)
User receives an access token from Identity Server, that contains the sub claim
User makes a request to the Web API (2) using the access token
The Web API (2) checks its own database for user permissions
----QUESTION/PROBLEM IS HERE-----
Should the Web API add these user claims (permissions) to the access token, OR should the Web API always check the database for the user permissions on every request made from the client?
Maybe I could add the claims before authenticating with IdentityServer, but this would mean that IdentityServer would have access to the Web API's database. I believe this is not a good practice because of separation of concerns.
Another solution would be to introduce a caching mechanism when the Web API validates the token, so that it doesn't always check the database.
Using claims transformation, it is my understanding that I can add the claims to this 1 request only, meaning that the next time a client makes a request, claims transformation should happen again, since it doesn't return a new access token to the user.
Ideally, I would like the Web API to add the claims to the access token so that the Web API can trust these claims on all subsequent requests. I cannot find a way to do so, though. I've searched for Claims Transformation, IssueJwtAsync (IdentityServerTools), IProfileService, but I think none of these are solutions to this problem.
Is this good architecture? Please do share your opinions on this subject and potential solutions.
Thank you very much!
You need to add these permissions in web api, because users need to access the corresponding resources according to these granted permissions. And permissions are granted when the user logs in for the first time, without the need to access the database in every request.
In this case, you can use Claims Transformation. This link has more detailed steps which can solve this problem.

Asp.Net Core Identity - Authorize attribute with roles and caching?

I have a simple web application in ASP.Net Core with ASP.Net core Identity. I'm using role based authorization on various controllers and it seems to me that the Authorize attribute is not picking up changes to role membership right way.
Let's say I decorate a controller with the authorize attribute and specify a role, like this:
[Authorize(Roles = "TestRole")]
Then I log in as a user which is not in that role. I try to access the controller and the Authorize attribute correctly prevents me to access the controller - gives me an access denied error.
Then I add the user to the TestRole programmatically (I have built a simple user management GUI in the web app where I can manage users and roles). According to the GetRolesAsync() method, the user has successfully been added to the role and everything looks good if I check the records in the Identity tables in the DB. However, I still cannot access the controller - the Authorize attribute does not seem to be aware that the user is now in this role. The role information seems to be cached. If I wait long enough before trying again (a few hours maybe) then this appears to work correctly. If I kill the IIS express process and restart the website, this works immediately, suggesting that the role information is somehow being cached.
I have not been able to find anything which explicitly states that the Role information is indeed cached or how to disable it for that matter. When I change the role membership of users in my system I need the changes to be reflected right away.
Any ideas?
OK - how typical. I've been trying to wrap my head around this for a few days now and as soon as I finally post a question to SO, I find the answer :)
By default, ASP.Net Identity stores user's authorized roles inside
Role Claim after user successful login. Those claims are stored inside
cookie until user logout or close the browser.
Is it possible to cache authorizations in ASP.NET MVC & Identity 2.0?

Restricting an api resource on user level in IdentityServer4

We want to set up a general authentication service, making use of IdentityServer4, where we define a set of users that can have access to one or more api's.
Users will be globally defined, but can only have access to specific api's.
Maybe I'm missing something, but this doesn't seem to be supported. If a user is authenticated and receives an access token, he can access all api's.
I've read the blog post https://leastprivilege.com/2016/12/16/identity-vs-permissions/ and I fully understand and agree that authorization should be handled in the client application itself, but this first level of checking if a user can access an api seems trivial to me.
I worked with Azure AD and ADAL before, and in Azure AD it is possible to define for an application (=resource in IdentityServer4 terminology) which users can access it. When requesting a token you specify the resource you want to access and if the user has no access to it, no access token is returned.
Can anyone tell me what is the proper way to set this up? Most of our applications are Angular SPA applications so we use the implicit flow.
I would suggest some high level idea you do it this way,
Authenticate users and make sure it returns with access_token and certian claim information
Define the authorization rules in your data store or somewhere you can read that can map the claims to permissions/attributes.
Now write a authorization logic or service where you can map the valid permissions from step 2 and seek for permissions.
This you keep your identity and authorization clean and separate and only update the rules on application as needed to map the general permissions
You scan set up different clients with access to different APIs the users just authenticate the client and they have access to that API. This isnt going to prevent user1 from authenticating to an api you dont want them accessing.
You can also set up user claims and policy to prevent different users from accessing different apis. Something like this would ensure that only users who are at least 21 years old would be able to access this api.
[Authorize(Policy = "AtLeast21")]
public class AlcoholPurchaseController : Controller
{
public IActionResult Login() => View();
public IActionResult Logout() => View();
}
More info can be found here Custom policy-based authorization
The proper way is to either use Policy-based or Role-based authorization.
Identity server is doing the authentication (checking if the client is registered, if it is allowed to access the requested scopes, authenticates the user, and gives him claims) but it is up to your application (the client) to authorize the user (based on the roles in the claims, either allow or don't access to a certain method).
You have an option when authenticating against IDS to check the clientID and the user, and write some custom Profile Service where you can apply some rules and reject the user.

MVC4 - claims based authorization with standard authorization attribute

I have an MVC4 app configured to use Claims Based authentication using the Identity and Access VS extension, which creates system.identityModel and system.identityModel.services section in the web.config.
For authorization I'm using standard attributes e.g.
[Authorize(Roles = "Admin")]
The role should be taken from the Role claim (http://schemas.microsoft.com/ws/2008/06/identity/claims/role) and not from the membership database.
This solution actually worked fine at the beginning. However, when I copied it to other machine I'm getting SQL connection error when the Authorize attribute is hit.
My understanding is that it tries to connect first to the local membership db to check the role. Can I tell MVC to check the role first in the claim?
Since there were no answers I decided to implement my solution as described here:
http://fczaja.blogspot.com/2013/12/claims-based-authorization-in-mvc4.html