ASPNETBoilerplate - Custom Claim auto expire after sometime authentication generated claim available - asp.net-core

I'm using the .NET 7.0 Ready aspnetboilerplate Framework.
While login the user I've added a few Claims. but the concern are custom added Claim auto-removed after some time.
Can anyone know the reason?

Do you have cookie authentication set? The problem is most likely an expired cookie. Since the custom claims are not added to the user claims in the database, they are lost on refresh because the claims are not added in the method called. You can add claims in the following ways:
userManager.AddClaim(xxx);
If you don't want to save the claims in the database, there is another method in this link that might help you.

Related

Adding Permissions to Claims - Microsoft.Identity.Web & B2C

I'd like to ask for advice or direction to any article/documentation on how to add custom claims to user identity. Project I am working on is using Azure B2C with Microsoft.Identity.Web.
I am searching for a robust way of adding a custom claim during web request in an web app. The claim would contain permissions obtained from an application database. So I also need a way to store that claim between requests, so I don't trip to database on every request.
The model of roles and permissions stored in the database is quite complex and dynamic (managed by admins), thus simple storing custom claim in B2C via graph API is an option.
I was thinking about stepping in with a middleware doing claims transformation:
Is this ok with Microsoft.Identity.Web or is it something that I shouldn't do?
Still not sure how to persist the claim between requests - is there any robust way while using Microsoft.Identity.Web?
If you want to have permissions in the token, and I presume that would be the optimal way, then I'd go with saving those in the user object as a Base64 encoded JSON for example. You can have quite complex structure which AAD B2C would just return in the token for the user. Then you may do what you want with this value in once it hits your API. It's in the token so it's properly signed and you get the token with every request so you don't think about reaching to any database.

WebAPI how to disable another user from the admin

I have created a simple WebAPI in Visual Studio C# to act as my backend to Angular.
Users can register via the Angular frontend and passed to a controller in the WebAPI to register that user in the backend DB (MSSql). All fine.
I am using token authentication from Angular to my API and using claims and roles to verify the user is logged in and has access to the requested controller.
How, as an Admin, can I disable another user so they are instantly locked out?
An example would be: A rogue user starts abusing the Angular application and I need to lock them down instantly and not to wait until their token expires and they are required to login again.
I could do a check in each and every controller to lookup the user in the DB and check their status and if I have set their status to "locked-out" then return say a 403 forbidden status from the controller but this seems a lot to lookup the user for each DB request they make.
Is there a "dot-net" way of doing it? I would love to be able, as the admin, to instantiate the said user, change their claim value for "status" to "locked-out" and I simply check their claim when making api requests but I can't see a way of changing another users claims.
Any ideas?
Thank you.
Expanding on my comment above, we have a handler in our pipeline that handles Authorization. We do look at that Authorization header and parse it but all of the controllers rely on the already-parsed value that we hang in the Properties collection. That way all AuthZ/AuthN occurs in this handler and whatever the handler sets in the Properties collection is what all of the application sees.
In your case the handler would need to be able to check whatever throttle or lockout you are using and replace the actual claims received with your "user is locked out" claims instead.

Update Claim value in User Claims list whenever it is changed in Database

I am using IdentityServer4 Implicit flow for my Angular application. I have permissions claim added to scope list and also it gets populated properly.
i need to update this claim value whenever i change the value in database.
currently, the claim value is refreshed only when access_token is refreshed/renewed.
I want to check/update claims on every call to api.
Two things:
You are mixing authentication with authorization. The permission claims should not be present in the Access token. Please read here why. And read my answer here for some thoughts about a possible design.
You can't change a JWT.
An access token contains information about the client and the user (if
present). It is a self-contained code that can be decoded by the
server only and has a certain lifetime.
Please note that the refresh token does not really refresh the access token, it creates a new token. The original token remains valid until it expires. An alternative is to use Reference Tokens.

Azure Mobile App refreshing tokens on server

Here's the background:
Need to authenticate with google/facebook/msa
Need to add our own claims to MobileServiceAuthenticationToken for use on client
Want to have refresh token capabilities (I know FB doesn't have that)
I have this working by LoginAsync and getting a MobileServiceAuthenticationToken back. Then I call a custom auth controller which has an [Authorize] attribute on it.
The custom auth controller copies some claims from the principal then adds our claims to those and creates a new token which it returns to the client.
Using the LoginAsync for all of this keeps the tokens flowing for all calls and that's great.
So, the token expires and I call RefreshUserAsync on the client. At this point the MobileServiceAuthenticationToken with our custom claims is replaced by the default one from the MobileAppService without our claims. I expect that.
So now I have to call the custom auth controller again to get our claims added back to the identity token.
This works, but it feels clumsy. And it's two round trips.
What I'm looking for is to refresh the identity provider access token on the server side, and in the same method, update the identity token with our stuff.
I'm aware of the /.auth/refresh call from the client side as an alternative to RefreshUserAsync. Is there a similar call I can make from my controller in the backend without setting up the whole System.Net.Http.HttpClient thing?
For example: I use this.User.GetAppServiceIdentityAsync<GoogleCredentials>( this.Request ) in the backend to get identity provider information without making HTTP calls.
Something like that?
Thanks in advance.
Short version - no.
Longer version - you need to call the /.auth/refresh on the backend on behalf of the user, then add your claims. The /.auth endpoints are on a different service that your backend does not have access to except via Http.
The GetAppServiceIdentityAsync() method still does a HttpClient call, so you aren't saving yourself a round trip.

How DotNetOpenAuth works

I am just getting started using DotNetOpenAuth with an MVC app and I am having it a bit difficult understanding how it actually works.
As far as I understand, DotNetOpenAuth will take care of authenticating a user with Google/Twitter/Facebook (probably after some modification).
What happens afterwards? Is the user authenticated per request? Is the user information saved in a session using IPrincipal, IIdentity? How does it fit together with an MVC application which will store all user information in the application database (custom tables and not the default .NET membership provider ones)?
Also, if you know any good tutorials, documentation on the subject, please share this as well.
Thanks!
DotNetOpenAuth only deals with the authentication step -- how you decide to store and recall that authentication ticket is up to you. It is very common to use FormsAuthentication to log the user in:
FormsAuthentication.RedirectFromLoginPage(authResponse.ClaimedIdentifier);
Using this approach, a cookie is sent to the browser and comes in with every request -- just like if you had used the older username/password approach.
You can download a bunch of samples from SourceForge.