How to Dynamically (Runtime by AdminUser) add Role and it's Object Permission in Asp.net Core 2.x using built in Authorization? - asp.net-core

Last year I started using asp.net core MVC.
I used to make a security system using role and permissions based like:
When the application is first deployed into production, the application creates a default admin
role and admin user. This user has full application access.
This user can create a new roles and give access permission to a new role (including creating new role and user permissions) and assign it to the new user.
reference for this type of security system:
I read Microsoft documentation
And there everything is in hardcoded string .
How can I implement this in asp.net core2.x with EF Core for DB access?
(If possible provide some detail explanation links)
For an Example: Admin user Create Role 'PurchaseManager' and give access to this URL example.com/Product [Get/POST/PUT/DELETE] etc. all. after Admin user Create another Role 'StoreManager' and give access to this URL example.com/Product [Get Only]
this process will be done in production.

Related

How to use the Authorize attribute for RBAC with Azure AD?

I have an ASP.NET Core 5 MVC hosted in an Azure AppService.
I've use Azure AD to limit access to the app to specific set of users.
This has been working fine without any Authentication code or configuration in the app.
Now I'm trying to use Azure AD App Roles to limit functionality per roles. I defined App Roles in Azure AD, and assigned them to different users.
Running the App, and going to ./auth/me, I get the user access token the roles are showing as expected.
Now I thought I can only use the [Authorize(Roles = "SomeRole")] on top of ASP.NET controller actions to control access.
First trial, I get the following error when invoking the controller action with the [Authorize] attribute:
InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found.
I can solve this error by adding the following call in the ConfigureServices method:
services.AddMicrosoftIdentityWebApiAuthentication(Configuration);
But now trying to invoke the controller action I get the following error:
Access Denied, you are not Authorized.
So apparently I'm missing something to link the [Authorize] attribute with the access token received, which has the correct roles.
Please advise.
This has been working fine without any Authentication code or
configuration in the app
Then I'm afraid you are using azure APP service easy auth. You only need to register an Azure AD application and set it in your azure web app instance. And then all the users in your tenant can sign in with their account.
Your requirement now is that you also want to allow specific users to access your app, so you come up with an idea that you can assign roles to some of the users and let your application to validate the role. So you add services.AddMicrosoftIdentityWebApiAuthentication and [Authorize] in your code. But to be honest, that's not the easiest way to do it because you already enabled easy auth and it's better to not adding any code as well. So I'm afraid you can take a look at this document. It allows you to set a list of users who can sign in your app which configure to use the Azure ad app. If users aren't assigned to the Aad app try to sign in, they will get error information.
The steps to do it can be summarized as:
Going to Azure Active Directory -> Enterprise applications -> choose
the app you used in your app -> Properties -> Assignment required? set
to yes then save
Switch from Properties blade to Users and groups blade -> click add
user/group -> select users which you allow them to sign in your app ->
click assign
What you have done is implement by codes. You integrated Azure AD authentication into your MVC project. It can't validate user roles, and the user roles are used for api authorization. Here's a blog introducing it. The roles defined in Azure AD app is different from the asp.net core identity roles.
=====================================================
Ok I got your point, you want to set attributes like [Authorize(Policy = "mypolicy")] for different Controller method in your MVC project to restrict specific users to specific method. You want to use roles to differ the users.
Here's the solution:
you have to create azure ad app roles and assign app roles to users. The app roles is different from default Azure ad user roles, app roles are used for your scenario.
modify your MVC application following this sample or do what I shared below:
var builder = WebApplication.CreateBuilder(args);
// This is required to be instantiated before the OpenIdConnectOptions starts getting configured.
// By default, the claims mapping will map claim names in the old format to accommodate older SAML applications.
// 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role' instead of 'roles'
// This flag ensures that the ClaimsIdentity claims collection will be built from the claims in the token
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration);
builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme,options =>
{
// The claim in the Jwt token where App roles are available.
options.TokenValidationParameters.RoleClaimType = "roles";
});
// Adding authorization policies that enforce authorization using Azure AD roles.
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("mypolicy", policy => policy.RequireRole("Tiny.AccessEndpoint"));
});
builder.Services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
Then in the Controller, adding [Authorize] and adding [Authorize(Policy = "mypolicy")] action method. The test with a user who doesn't assign the app role will show error below.

How to connect your ASP.NET Core 3.1 MVC web application to Active Directory?

I am building a web application for a client, where I will have to set it up on their Windows Server via IIS. I will have to integrate their base of users into my application via Active Directory (not Azure Active Directory). I have already included Windows authentication into my application and it seems to work on my local computer.
What I want to know is:
How to change the login prompt into my custom login page?
How to change the username of the authenticated user (right now when I sign in, I have to write down the name of the device and the name of the user. for example: _device/_user). What I want is for the user to simply be able to only write their username, not device name.
How to manage the access of the users, and how to add roles to them inside the application. Since the user is signed In. I now want to know how do I assign this user a certain role, so I can restrict access to certain pages based on that.
I have been looking through some documentation but not much is mentioned about Active Directory integration or the questions that I have listed above.
Steps;
You need to have System.DirectoryServices and System.DirectoryServices.AccountManagement references in your project, if you want to access AD.
Configure AD name and AD Organizational Units in appsettings.js ActiveDirectory": { "ActiveDirectoryDomainName": "Your Domain", "ActiveDirectoryOrganizationalUnits": "Your AD units" }
In your class method:
Fill your user object with AD values like userPrincipal.EmailAddress,userPrincipal.GivenName,userPrincipal.Guid.Value and etc.
If you want to manage users with roles, then take the GUID from AD (userPrincipal.Guid.Value) and store it another table and map that GIUD with required roles.
Note: If you can share some images and codes

How to persist user consent information in database Identity Server

I'm using IdentityServer4 and whenever the user login for the first time the application shows consent screen for the scopes of an application to the user which is expected. If the user clicks "yes" and click on remember option the application is not showing the consent screen when the user login for second time onwards which is also expected. Here the problem I'm facing is whenever I restart the IdentityServer (or when I do the deployment) the user consent information is not persisting and it is showing the consent screen again for the user. Can anyone help me to know Is there any way to store the user consent information into DataBase or how can we know where the information is being stored when the application is in running. I did some debugging but couldn't find it. Thanks in advance.
Add reference IdentityServer4.EntityFramework.Storage nuget package to identity server 4 project, Then in startup.cs
service.AddIdentityServer((options) => {})
.AddPersistedGrantStore<PersistedGrantStore>()
// Add other services.
The PersistedGrantStore requires PersistedGrantDbContext uses EntityFramework and requires the DbContext to be configured (same way you configure other EntityFramework DbContext). For example to use SQL Server
services.AddDbContext<PersistedGrantDbContext>(options =>
options.UseSqlServer(connectionString));
You can use dotnet-ef command tool to create and initialize the tables in the database.
You can also have your own implementation of IPersistedGrantStore service.

Connecting within ArcGIS application with resource

I have following dillema:
Using ArcGIS Enterprise 10.8, I have added a new item – Application – to a users content.
This generates an Application item, with an App ID and APP Secret, along with App type and redirect URIs defined.
These can be used to generate an access token via the OAUTH2 token endpoint:
https:///sharing/rest/oauth2/token
using the parameters :
client_id=APPID&
client_secret=APPSECRET&
grant_type=client_credentials
ESRI States in their documentation:
“Successful authentication directly returns a JSON response containing the access token that allows the application to work with resources that are accessible to the application (that is, have been shared with the application). Use of the client_secret as previously described is mandatory.”
Question is: how do we share resources with the application?
The overall goal is to grant an external application (unknown user) access to portal ressources (ie.a layer item) via OAUTH2 app login.
Do you have any suggestions?
This is certainly confusing documentation, but I have found it useful to review this page: Limitations of App Login.
Specifically:
Applications cannot create, update, share, modify, or delete items
(layers, files, services, maps) in ArcGIS Online or ArcGIS Enterprise.
... If you want to access private content within an organization or
content that has been shared with a user, you must use the named user
login pattern for authentication.
For what you want to do, you'll most likely want to create a non-expiring refresh token based on a specific user, and store that in with your external application.

Subscription-scope authorization for Azure Resource Manager API user

Trying to put together an Azure ARM integration, where my code uses the Azure API to retrieve the full list of VMs in the entire subscription.
Went successfully through all the (many!) steps here to get an API user ready with all relevant IDs needed for authentication.
Using the same set of instructions, we were also able to grant this user the Reader role, for listing VMs in specific groups (we did this through the Azure UI). However, we have been unsuccessful in implementing the instructions here for setting up Reader role for this user to the entire subscription (through the CLI).
Running this:
azure role assignment create --objectId app-oid --roleName Reader --scope /subscriptions/subscription-id
Or this:
azure role assignment create --objectId app-oid --roleName Reader --subscription subscription-id --scope /subscriptions/subscription-id
Yields this:
Principals of type Application cannot validly be used in role assignments.
So currently we have no way of programmatically browsing the full set of VMs without adding a specific authorization for each Resource Group.
Does anybody know of a way that actually works to assign this permission at the subscription level?
Found the answer in the comment area of the link in the question body:
In the new portal, edit the subscription and add the role, just like you would do with a resource group. Still curious as to why the CLI doesn't support this.
The steps to use the Azure CLI to create and authorize a service principal are documents here: https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal-cli/
Instead of using --objectId app-oid try using -ServicePrincipalName <appId>
https://github.com/Azure/azure-powershell/issues/4776
Had the same error for role assignment with terraform
Principals of type Application cannot validly be used in role assignments.
But as described here, using the Object Id that is displayed on the overview page of the app registration in the Azure portal resulting the above error.
The solution is to get the Object Id from azure cli:
az ad sp show --id [Application (client) Id] -o json | grep objectId
# and then using this objectId assign your role
az role assignment create --role contributor —-assignee-object-id [object id] —-resource-group [MyResourceGroup]