Modify identityserver4 authorize - asp.net-core

I'm using IdentityServer4 and EF Core in my Blazor WASM project with ASP.NET Core hosted option and in that project I use multiple databases.(dynamic string connection - duplicates of databases)
In the login page you choose what database to use and I store the database name in the cookies.
The system should work like that when you login using one database you can't use the other databases.
Every thing is working fine except that that I can change the database name in the cookies and then use the other databases.
My question is how can I modify the IdentityServer4 authroize so when you login using one database you can't access the another databases(return 403 error code when send http request if you changed database name in cookies) - database depended.
I thought maybe I could check each request if token is stored in AspNetUserTokens table ,but I noticed that the table is empty even after logged in successfully.

It sounds like the current database value should be set as a Claim on the user's identity, rather than in a raw cookie. Adding custom claims to the identity will protect them in an encrypted token.
Here's some documentation around this scenario, in particular look at implementing an IProfileService that adds your claim.

Related

How to correctly delete a user (and get the user to autmatically logoff) in ASP.NET using Identity Server

I'm using IdentityServer 4 but I think this question applies to ASP.Net identity in general.
We are considering to adapt an external (WinForms) tool to automatically delete (and later also create and manage) users. This tool has direct access to the IdentityServer database.
Is it as simple as deleting the record in the AspNetUsers table (and any additional records in profile/preferences/settings/roles tables) or is it more involved? Would we have to cycle the IdentityServer application pool as well?
In addition, if the user is logged in and actively busy on the Identity Server website, will the cookies be invalid as soon as the user tries to load a page with the [Authorize] attribute (after the record is deleted)?
We'll also have to notify all sites that make use of the tokens coming from the IdentityServer, but it looks like there is an existing solution for that (Backchannel Logout) which looks quite clumsy at first glance... It looks like a request is sent to the client to clear the cookies... I hope I'm seriously misunderstanding something here...

Blazor server side role or claim based authorization when using windows login

I am new to working with Blazor and Authorization. Background is desktop apps in Vb.Net, so I have been reading everything I can on it, but it still is very confusing when I only want a specific subset of the options out there.
I have a very simple intranet Razor Server based app that is getting the windows user name correctly with default authentication. (I use the name in calls to stored procedures for logging, so I know that is working correctly.)
What I need is to implement authorization (role based would be fine) based on information I have already in the database tied to the user name).
Where and how does one add roles to an existing authstatetask or other object instantiated by the default processes?
Everything I have seen deals with the EF version of Identity or wants to override the authorization task.
I have Simple DB calls being made in Dapper which will return an identifier from which I can set roles.
I just need pointers to the proper method and where in the app I should put it. I have just a single .razor page being loaded, Navbar is disabled.
You can either :
Implement Identity stores for Dapper following instruction in this blog : ASP.NET CORE IDENTITY WITHOUT ENTITY FRAMEWORK
Use Policy-based authorization and create authorization handlers meeting your requirements

IdentityServer4 + Asp.Net Core Identity - Map Identity to application database user

I am trying to implement an IdentityServer4 with Asp.Net Core Identity.
I want to use IdentityServer4 as centralized authentication/authorization point for APIs using always the same identity.
So the idea is to store the Asp.Net Core Identity stuff in an SQL Database which serves as the identity store.
The question now is how to map the centralized identity to application specific data.
I want to use same identity user in several applications, but in each application the user has other related entities, roles etc.
I read through the documentation of IdentityServer4 but could not find anything related to a proposed structure.
As I understood, you somehow map the identity id to your local application user.
Basic data like firstname etc are stored in the centralized identity store and application specific data is stored in the application specific database. So you would not save firstname etc in the application specific db right?
In the every request where you need user specific data will query the identity server to get information/claims?
What about registration process?
Does anybody have a clear structure setup which could be used to understand the whole setup?
(Separation like Asp.Net Identity Provider, IdentityServer4, Protected Api.)
So you would not save firstname etc in the application specific db
right?
Yes, User specific properties should go into the user profile and should be saved in the user store(database) of IdentityServer. Application specific user data should be stored in the application store.
In the every request where you need user specific data will query the
identity server to get information/claims?
Not necessarily, The user specific data can be included in identity token as claims. The claims will then be stored in a cookie as authentication ticket. For each request, those claims(stored in cookie/s) are available via User property of the controller
var identity = (ClaimsIdentity)User.Identity;
IEnumerable<Claim> claims = identity.Claims;
You can store and query application related user data stored against a user Id(sub claim can be used as a user Id).
If you need a lot of user-specific data in an application it is not optimal to include everything in identity-token and it is unlikely that you will need those for each request. So when you need extra information you can query UserInfo endpoint of identity server. Just include basic information you need to identify a user in your identity token.
What about the registration process?
Registration is a completely separate workflow that there is no involvement with identity server. You just need to save the user to identity store(probably using asp.net identity). Of course, you can host the registration controllers along with identity server, so that identity-related stuff is physically on the same server. You can also just write to IdentityServer user store from anyplace you host your registration process(e.g. A separate admin UI, or From a workflow involving email verification, manual approval etc...)
To customize what you store in Asp.net Core Identity, you need to use
services.AddIdentity<ApplicationUser, ApplicationRole>. ApplicationUser and ApplicationRole are extending IdentityUser and IdentityRole. This way you can make it store any extra info you want.
Then to return the extra info you need to create a ProfileService that implements IProfileService. With this service, you can add any extra information to claim tokens.
You need to register this service as
services.AddSingleton<IProfileService, ProfileService>();
builder.AddAspNetIdentity<ApplicationUser>().AddProfileService<ProfileService>();
You can register the user with extra info like below:
var user = new ApplicationUser
{
UserName = Username,
Email = email,
ExtraInfo1 = "Hello",
ExtraInfo2 = "World"
};
await _userManager.CreateAsync(user, "SomePassword");
With OpenId you have default set of claims associated with user. So any client application can access those claims. Make sure each client has openid and profile scopes assigned to them. Otherwise client application not able to access the users basic details.
In Asp.Net Core application you can access those claims in controller using User property.

Trying to pass session variables from ASP to ASP.NET

We are doing a slow rollout of pages. basically the Login page is in ASP.NET and the old pages are in ASP Classic which are placed in an Iframe below the menu. They have two different servers that process the menu/pages. What is the best way to pass the users session from .NET to ASP Classic.
I had thought maybe it would be possible to modify the .NET login to send the user credentials to ASP page at the same time when they post their login. Is there any issues with this or is there a cleaner way of doing this?
Your ASP.NET code can read all the cookies in the domain, including the classic ASP session cookie, even though it doesn't use it. You can take advantage of that.
Handle signon on the ASP.NET side. The framework should create both an ASP and an ASP.NET session for you, passively, in addition to whatever other cookies are created by your authentication process.
Write ASP.NET code that reads the classic ASP session cookie and creates a JointSession record in the database indicating which user is currently signed on. Store both the ASP session cookie value and the current ASP.NET session ID (each in their own column), along with the user ID, roles, and whatever else needs to be shared between the two sites.
Write ASP code that reads its own session cookie and looks up any corresponding JointSession database record. If one is found, the ASP side of the site can infer that a user has signed on to ASP.NET, and can create its own matching session, initializing it from the fields in the JointSession record.
If you need to pass data between ASP and ASP.NET, add columns to JointSession, or perhaps use EAV schema. If it were me, I'd just add a VarChar column and throw some JSON in there.

ASP .NET WebAPI default OWIN authentication - help clear things up

I have some general/how-does-it-work-inside questions about WebAPI and OWIN (specifically, the default configuration which is set up when you create new WebAPI project in VS2013 and select Individual user account authentication). I did that, then I registered (using jQuery post) and even logged in (received token which I included in Authorization header, receiving access to protected resource. I just have some more questions about it:
Are my data stored inside authentication token? I know my password isn't, but is token containing encrypted data, or is just a random string? These are the only 2 options that I can think of: either token contains encrypted data (userId, expiration date, etc.) and server app deciphers it and grants me access to resources, or token is a random string and all user data are stored on server (token is used as a key to obtain correct user data entry). If the second theory is right, the token <-> userData lookup must be stored somewhere - is it session, cache or database maybe?
If i wanted to make a RESTful API, what about Roles, etc. (in general - data beyond simple who-are-you identification that I need for every request)? Again: first thing that comes to mind is to store them inside token. But if the data grows large isn't that too much overhead to send with each request (plus headers themselves probably are limited in size)? Second thing is using external OAuth service (like Facebook or Twitter) - if the user authenticates using external token, I can't control what information does it contain. Alternative is to get the data I need from the database each time, but isn't it bad practice? Every single request would need an extra database call to collect user's role and check if he even has access to this particular part of application. I could store it in session, but RESTful API is supposed to be stateless.
Thanks for any help as I'm just starting to dig into OAuth and WebAPI authentication. I know that I can customize everything to work as I want (so use session to store user data, etc.), but I wanted to know what the good practices are and which of them are provided out of the box with default WebAPI project in VS2013 and which need to be implemented manually.
(1) the latter is correct. The server verify token by machine key and can decipher and validate its contents.
(2) You got that correct. Its best to keep the token size min. tbh I am looking to see what others are doing about this. (+1 for the question.)