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

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

Related

Blazor Asp.Net Core Identity with custom user database

I'm writing a Blazor server application.
In this I would like to use my own user database and not that of Asp.Net Core Identity.
Does anyone have an example of this?
Or can I write a CustomUserManager?
I simply want a login with username and password that is validated in my own database.
The ASP.NET Core Identity is an API that supports user interface (UI) login functionality and helps to manage users, passwords, profile data, roles, claims, tokens, email confirmation, and more. And it is using the EF core to access data from database. If you want to use your own database, you could change the connection string to yours.
If you don't want to use Asp.net core Identity, you could create the Account or Role controller by yourself, and add the login page. Then refer the EF core tutorial to connect the database, and then manage users and roles or validate users.

Protecting an ASP.Net Core WebApi using individual account and AzureAd account

I have a requirement to secure an Asp.net core Web Api Application using ASP.NET Core Identity platform.
So users can login to the application using a individual account which is stored in the database.
The authorization logic and access control logic will be handled using the local user information.
Also the requirement to link the above mentioned individual account with an AzureAd account to give single sign on experience for the end users. Username or email(UPN) can be paired for this purpose.
Goal:
Users should be able to log-in to a Blazor Client SPA application where they have two options to login either using
A Username & Password (Individual Account)
An AzureAd account (SSO)
I can see there are lot of resources which explains both mechanism but I couldn't find any hybrid solution.
A real world example:
You can use your email and password or a Google account to log in to the StackOverflow site.
How can I achieve this? Is there any technical term to explain the scenario?
I'm looking for some tutorial and some examples.

Angular SPA authentication with Azure AD

Hi I am working on Angular SPA and web API core. I am trying to implement authentication and authorization. I have done as below for now.
Registered one application for my front end application and added required redirect uri and modified manifest file to enable implicit flow. Also assigned some of the roles to it.
Registered one more application for my back end. I added scope in the form api/clientid. Then added client application id which is created in step 1.
User is successfully able to login to application.
Now my JWT token has roles in claim. In my API I have added [Authorize(Roles = "Engineers,Admins")]
So If user has any role Engineers or Admins in the JWT token as claims then they are allowed to access my API's
So far my authorization works fine. But coming to authentication part, currently all users of my azure AD tenant able to do login(User can hit my front end url and add user name and password then It will ask MFA and they will be landed in application home page).
If user is part of any of the roles above then only they can see data in home page because in home page I am calling some of the API's and I have added [Authorize(Roles = "Engineers,Admins")].
If suppose user is not part of above role they are still able to login (login means they are able to add user name and password and MFA) they will be landed in home page but they cannot see any data because api will be accessed only if they are part of Engineers,Admins roles.
My question is If user is not part of Engineers,Admins roles why they are able to login and come to home page. They should be restricted in Login step itself.
I am not really sure I am asking right thing here or I only confused my self between authentication vs authorization.
Currently I am doing authorization based on roles. Same thing I can accomplish using Groups also. In claims I can return groups and create policies and do the authorization. If user is part of the group then I can authorize. I am trying to understand what advantage I will get using roles over the groups.
Currently I have dev, prod and non prod environments. But Azure AD is universal and for there is no environment for azure AD. So Is it a good idea to have separate application registered in azure ad between the environments or can I use same app registered in azure AD between the environments. If I create separate application for each environments what advantage I will get?
I am really trying to understand above concepts and can someone give me some insights on the above things? It will be really helpful to me If someone help me to understand this concepts. Any help would be greatly appreciated. Thank you

How to manage users in ASP.NET core with AD / LDAP? Do I store the users in a database?

I am writing an internal app where all the users are part of AD. I have the following steps to implement this. Is this correct?
Create Action filter to get all HTTP request to website and check in they are in the specific AD role needed (var isUserInRole = User.IsInRole("M2-ITU-PWApplicationDevelopers"))
If user is not in any of the application roles send user to error page
If user is in application role then Add users to SQL DB and link to Role table in DB so now I have the user/role data ready to use in DB along with other data
When user revisits check the database first before LDAP?
How do I set a cookie or something so that every request does not need through process once authenticated ?
Trying to understand the basics.. Maybe I am going about this all wrong ?
Use Windows Authentication. Your application need to be behind IIS to do it in ASP.NET Core 2.2 and lower, but starting ASP.NET Core 3.0 you can do it with Kestrel alone.
If you do that, you can skip steps 3 and 4. When a person is authenticated via Windows Authentication, the application gets a login token that contains all the security groups that the account is a member of. So User.IsInRole is pretty quick. There is no need to store that information in your own database.
You also don't need to worry about cookies.
The added benefit of Windows Authentication is that it can support seamless login: if your site is in the Trusted Sites in Internet Options, then IE and Chrome will automatically send the credentials of the user currently logged into Windows. The user doesn't have to type in their credentials.
Firefox uses its own network.negotiate-auth.delegation-uris setting for the same purpose.

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.