MVC4 - claims based authorization with standard authorization attribute - asp.net-mvc-4

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

Related

Authorizing by updating Claim with data from database (Blazor WebAssembly ASP.NET Core hosted)

I have a question regarding authentication in my web-app using Blazor WebAssembly ASP.NET Core hosted. The database used is Azure SQL.
I want to avoid storing passwords in the database and the users are therefore restricted to having a Microsoft-account (relevant to the project).
As of now, the user logs in with Azure AD as the third-party authentication provider. When redirected back to the web-app, a user is created with a claim which only consists of the Email from Azure. The user is directed to a registration page where the Email-input is set to the current user-claim email. When the user clicks the register button, the information provided is now stored in the database.
The problem is that I now have a user in the db, but the claim is still just the Email. I want to be able to use the AuthorizeView role tag on the different pages, and therefore wondered if its possible to update the claim with a role that the user specified in the registration-page? This data is at this point only stored in the database.
If this is a bad practice, is there any other similar way I could make this work?
To use the AuthorizeView role, roles claims should be return by your Identity provider (Azure AD in your case). Your application should ask those claims by asking the corresponding scope.
According to the doc : Permissions and consent in the Microsoft identity platform endpoint, the profile scope should return roles claims.
The doc Secure an ASP.NET Core Blazor WebAssembly standalone app with Azure Active Directory explains how to request scopes from Azure AD

Best practice for Active Directory user management with IdentityServer

What is the recommended approach for user management with IdentityServer4 and Active Directory?
I have started with the IdentityServer4 ASP.NET Core interactive quick start and all is working well. However, the sample code uses the TestUserStore, TestUserProfileService etc., and it seems prudent to replace usage of these.
The 'real-world' alternative seems to be using ASP.NET Core Identity, however this persists user details to the IdentityServer database. Given that IdentityServer isn't the source of truth for this data, this is an odd fit.
Apart from the "test" nature of the quick start classes, these are serving our needs well. Our IdentityServer instance is for internal staff in a small organisation, so the in-memory nature of these stores isn't a problem.
This seems to be a fairly common use-case, so I must be missing something. Can one just delegate all user profile calls to Active Directory? Is there any out of the box code for this?
Identity Server is an implementation of OAuth 2.0 and OpenIDConnect(Built upon OAuth2.0). The key point of OAuth 2.0 is to pretect resource such as WebApi based on Access Token. So what does OAuth 2.0 provided is Authorization.
Identity Server can provide Authenticate service provided by ASP.NET Core Identity, as specified in This Document
In your case, you'd like to delegate the authenticate part to AD, and authorization part to Identity Server. You can refer to This document to enable windows authenticate in your asp.net core application
I resolved this by implementing and registering an IProfileService for Active Directory. It still seems oddly hand-rolled, but seems to do the trick.

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?

Where to implement the user profile page using IdentityServer4?

I have a solution with 3 projects in ASP.NET Core:
MVC --- no DB (calls the API)
Web API --- MySQL 5.7 own DB
IdentityServer4 + ASP.NET Identity --- MySQL 5.7 own DB
I've managed to get authorization and authentication working between all three apps using in memory clients, users, resources following the great documentation found on https://identityserver4.readthedocs.io/.
Currently I'm using the HybridAndClientCredentials flow which works well with existing users as well as registered users. Newly registered users are saved in IdentityServer DB, using ASP.NET Identity tables.
The problems:
One of my client requirements states that the user should have a profile page inside the MVC app to which the user should be redirected after he is authorized & authenticated successfully.
What I'm doing right now is calling the API in the MVC app, OnTickedReceived event, with the initial claims to create the user in the API DB, but I have doubts that this is the correct implementation.
Since the registration is done and persisted at IdentityServer level and some data about the user is stored there, should I make the profile page there too or should I make a call to the API somewhere in the registration flow to create the user in the API DB too, then redirect the user to the MVC app to input the rest of the details required for a complete profile?
Another requirement states that a user should be able to grant read/write access to another user's details (as in linked accounts or something).
Unfortunately, "it depends".
Let's start by asking "what is the profile page?". What information is on the profile page and is that information specific to your application (MVC/WebApi) or the identity management system.
IdentityServer supports the OIDC UserInfo Endpoint and Profile scope with ASP.NET Identity so that could work well. (http://openid.net/specs/openid-connect-core-1_0.html#UserInfo). You can insert IdentityClaims into the AspNetUserClaims table and get those back when you call the UserInfo endpoint.
But maybe this profile page mentioned in the requirements is information belonging to just the application's domain and therefore has no business being in the identity management system. Then, your current approach is ok- though maybe you could use a Filter Attribute instead of an authentication event (that's just a thought, might not be better).
To me, the decision is about who owns this so-called "profile" information. Is it the identity management system or your business application.
If the profile information can be shared across any client of the identity management system, then put it in the identity management system.

Angular2 OpenIddict and Authorizing Roles in AspNetCore WebApi

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