Role-based and policy based authentication on same controller action - asp.net-core

From MS docs i can see that I can define multiple roles.
[Authorize(Roles = "HRManager,Finance")]
Which means that user has to be in HRManager OR Finance role.
I also have resource based policy defined for this action, named "ResPolicy1".
I want to accomplish that user can be in role HRManager OR in role Finance OR ResPolicy1 is satisfied, any of the three.
Can I use AuthorizeAttribute like this [Authorize(Roles="HRManager,Finance", Policy="ResPolicy1"]?
Is it possible to have both policy and role based authorization on the same controller action?

Can I use AuthorizeAttribute like this [Authorize(Roles="HRManager,Finance", Policy="ResPolicy1"]?
Is it possible to have both policy and role based authorization on the same controller action?
We could have both policy and role based authorization on the same controller action. Like below:
[Authorize(Policy = "UserResource", Roles = "Users")]
public IActionResult Index()
{
return View();
}
If we add Policy and Roles for the same controller, that means the user should match both role Authorize and policy Authorize.
If the user is just in role but not pass the policy authorize, he will receive the 403 forbidden.
If the user is just pass the policy authorize but not in role, he will also receive the 403 forbidden.
If you want to accomplish that user can be in role HRManager OR in role Finance OR ResPolicy1 is satisfied, any of the three, you could write your own logic in the custom
Authorization handlers. More details about how to achieve it, you could refer to this article.

Related

Handle Authorization and Authentication in DDD

currently i am trying to deal with authorization and authentication on .net core API
There is a company, and that company can create custom roles.
Those roles, will have permissions inside it, such as:
Read
Write
Delete
The company, can apply a role to the users that he creates
With that said, how would i handle the authorization part?
Because, i believe this is considered business logic.
How should i approach this?
Thanks in advance
You can create the role and add claims to that specific role and policy for authorization
AddAuthorization((options) =>{
options.AddPolicy("UserCreation", policy =>
policy.RequireRole("Admin").RequireClaim("Admin", "Edit"));
by using the role manager in.net core identity you can add the claim to the role
RoleManager<Role> _roleManager;
_roleManager.AddClaimAsync(role, claim);
last you can check whether the user have the role and claim to access the resource using authorize attribute
[Authorize(Roles = "Admin", AuthenticationSchemes = "Bearer", Policy = "UserCreation")]
You can probably handle this in multiple different ways. I'd suggest, since you are referring to an API, to decorate the Controllers, Routes or both with the [Authorize] attribute, where you want the rules to apply.
And you would use this attribute as such (where foo, bar, baz - are the roles on the authenticated user).
[Authorize(Roles = "foo,bar,baz")]
You can also define the challange scheme like
[Authorize(Roles = "foo,bar,baz", AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
Docs: https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-6.0

How to get the [Authorize(Roles = "RoleName")] into variable?

i am trying to save the role from the AuthorizeAttribute in a variable but i cant seem to figure out how. i want something like this. Note: the User/Roles is created from Azure Active Directory
private string CalculateRole()
{
var role = authorize.role;
return role;
}
i searched all over and "closest" i got is this question asp.net identity get all roles of logged in user
but all i get back is a list of Claims I cant find any "roles".
[Authorize(Roles = "RoleName")] is used for access. We can specify the roles that have access to the requested resource using the Roles property of Authorize attribute. For example, [Authorize(Roles = "Admin")] allows us to access the action method to users who are member of "Admin" role.
For the currently signed in user for an application, you can always find the Application Roles assigned to them from the Role claims available as part of the access token from Azure Active Directory.
For more information, here's a sample that uses OpenID Connect to sign-in users and use Azure AD Application Roles (app roles) for authorization. Also, you could use Microsoft Graph API to get the roles.
You can get roles from db by current user id.
You can have a bool validation within the Controller (where HttpContext.User e
bool isAdminUser = User.IsInRole("Admin");
This is fine if you want to validate for specific -or a few- Roles defined. If you have many roles this may not be the best option and you might want to consider to call GraphApi instead for membership validation.

AuthorizeAttribute: How to try with all available Authentication Schemas?

I have a ASP.NET Core 3.1 Web Application which have ASP.NET Identity authentication and Role based authorization for interactive users (Pages)
Now I implemented some API Controller too within the same ASP.NET Core 3.1 application
[ApiController]
public class ConnectController : ControllerBase {...
I realized, that bearer token endpoint is not out of the box, so I successfully implemented it using OpenIddict, and it is working perfectly.
I would like to use Authorize attribute with Roles.
This is working:
[HttpGet]
[Authorize(Roles = "test01",
AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)]
//[Authorize(Roles = "test01")] // This is not working, why?
public ActionResult<string> Ping01(string message)
{ ...
The pure [Authorize(Roles = "test01")] is not working, and I do not understand why?
For diagnostic purpose I examined all available Authentication Schemas, there are six, and the explicitly named "OpenIdDict.Validation.AspNetCore" is in the six (the last one, see debugger screenshot below). With other words I would like remain free change API Authentication methods and implementation in the future without touching the Controllers.
Question
How can I achieve that not specifying explicitly the Authentication Schemas in the AuthorizeAttribute constructor the authorization will try to Authorize with all available Authentication schemas?
Why I would like to do that?
...because I would not like to be specific to any Authentication Schema in my controllers. I would like to have a simple Role based authorization, and would not like the controller authorization code depend on anything else than the Role names.
How can I achieve that not specifying explicitly the Authentication
Schemas in the AuthorizeAttribute constructor the authorization will
try to Authorize with all available Authentication schemas?
If you don't want to specify the schemas explicitly, you have to create a Default Policy in the ConfigureServices method, like this:
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)
.Build();
});
So now when you use [Authorize] the default policy will be included automatically.
By using this attribute now, you will have the user authorized by the role:
[Authorize, Authorize(Roles="admin")]
You may ask, why should Authorize attribute be used twice?
The answer to this can be found here: https://github.com/dotnet/aspnetcore/issues/18954

How to get Role Claims in IdentityServer

I have users that're part of Roles which have Claims specified for them. I authenticate my users using IdentityServer (version 3 at the moment) with IncludeAllClaimsForUser set to true. I expected IdentityServer to automatically retrieve Role Claims but it doesn't.
Is there a way to make IdentityServer care about Role Claims or is customizing through ProfileServer is the only way to go?
if you need user information you have to use userinfo endpoint or while making a request for token add the scope that is related to user claim.

Authorize Claim in every Web Api Request using ASP.NET Identity Token Based Authenticaton

How can I authorize claims for each web api request using Token Based Authentication. I have a controller on which I applied Authorize attribute that will look for token on each request and return response if it's a valid token. But I have a controller called AdminController which I would like to be accessible for user having admin claim. How can I implement this? Any suggestion please?
Quick way to do this is to add claim of type "Role" and assign it value of "Admin", this should be done before generating the token for this user in method GrantResourceOwnerCredentials, it will be as the code below:
identity.AddClaim(new Claim(ClaimTypes.Role, "Admin"));
Now in your AdminController you attribute it with
[Authorize(Roles="Admin")]
This is called Roles based authentication but at the end the Roles are considered as claims.
You can check this complete code sample too