Refresh ClaimsPrincipal after HttpContext.SignInAsync (without identity) - asp.net-core

I'm building a ASP.NET Core 2.1 web app. I am not using Identity. I am using CookieAuthentication.
Instead, I sign-in the user using HttContext.SignInAsync:
_httpContextAccessor.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, myGeneratedClaimsPrincipal)
When something in the principal changes, I have to sign-out and sign-in to refresh the principal.
In there a way I can refresh the principal without sign-out/sign-in?

Related

Authentication for hybrid flow for ASP.NET MVC client

I'm learning identityserver4 and can't understand some stuff.
Shortly: I want to authorize end-users with email and password on ASP.NET MVC client side (it will send user credentials to the token server to get tokens), and I don't want third-party clients to retrieve data from my API resources.
As I understood from the documentation:
implicit flow is used for SPA (js clients) and uses id_token to authorize users. I can store id_token in my browser.
client credentials flow is used for trusted apps (like ASP.NET MVC client) to authorize clients and uses access_code. I can store access_code inside my app.
So looks like I need a hybrid flow.
In the documentation I read that I need to use AddOpenIdConnect() method and
Technically the tokens are stored inside the properties section of the cookie.
So my questions:
If the id_token can be stored in the browser, why is it not safe to store the access_token there too ?
As the docs state, the tokens are stored inside the properties section of the cookie. It's confusing, because some guides says, that it's not safe to store access_token there. So where I should store access token in my ASP.NET MVC client?
Am I right, that AddOpenIdConnect() configures my ASP.NET MVC app to retrieve access_token automatically from the token server? And if yes - in which moment should I authorize users with email/password and how to combine all tokens inside one JWT on my ASP.NET MVC client's backend when I will send requests to api resources ?
Today you should not use the Implicit Flow and it has been deprecated as of Oauth 2.1. What you should use is the authorization code flow with PKCE. PKCE is a security enhancement for the authorization code flow.
So as of OAuth 2.1 you only have two main flows:
Authorization code flow, for a MVC client to login a user to the client
Client credentials flow, for API->API communication where no human is involved.
To answer your questions:
If the id_token can be stored in browser, why it's not safe to store access_token there too ?*
The ID-Token is only used to create the initial user session and after that you can throw it away. It also only have a short life time of 5 minutes by default in IdentityServer.
As the docs state, the tokens are stored inside the properties section of the cookie. It's confusing, because some guides says, that it's not safe to store access_token there. So where I should store access token in my ASP.NET MVC client?
The tokens can be stored in your session cookie in ASP.NET Core and that's secure. It's protected / encrypted using the Data Protection API. However, the cookies can grow in size quite a lot if you do that.
Am I right, that AddOpenIdConnect() configures my mvc app to retrieve access_token automatically from the token server? And if yes - In which moment I should authorize users with email/password and how to combine all tokens inside one JWT on my ASP.NET MVC client's backend when I will send requests to api resources?
AddOpenIdConnect only handles the initial login and retrieving the first ID and access token. It does not handle refreshing of the access token using refresh tokens. For that you can add the IdentityModel library.
Today when you use the auth code flow, you redirect the user to IdentityServer and you let the user login there instead of passing the username/pwd from you browser to identityserver.

Using JWT Authentication without Identity at Blazor Server app Login page

Normally in the current authentication we’re using, after the user name and password is entered from login UI, the credentials are checked at server side and if the user is authorized then a JWT token is sent back to client and this JWT token is saved in localstorage. The [Authorize] tag is doing the authorization in the middleware.
I want to use Blazor’s CascadingAuthenticationState, AuthorizeView and JWT authentication without using Identity library, is this possible? Now I used Blazored.LocalStorage.IlocalStorageService and saved the token to localstorage. How can I add token to each requests. Most of examples are blazor webassembly. I could not find similar scenario like mine. Is Using Identity the only way to authentication blazor server app. I have to use my own server and middleware so I wont use Identity? Or maybe I should create hybrit way to use both of them. What is your suggestion?

IdentityServer4 login api

I am using IdentityServer4 to secure my API and also to authenticate users, the client is the main ASP.NET Core MVC App, I just want the login interface and UI to be at the MVC App and the login implementation at the IdentityServer, so the IdentityServer must have an API to just receive username and password from the MVC app login page return the token which will be used in cookies
It is a bad idea to move your views for several reasons. Some of them:
If you move the views to your MVC client you will have to create those views in all your clients.
OAuth2 / OpenId Connect should delegate authorization / authentication to your Idp to avoid credentials sharing. Instead of that, you are forced to use Resource Owner Password Credentials which implies that we cannot use the user's consent pages from the Idp.
You won't have Autentication Cookie from your Idp for Single Sign On.

Refresh Signin & Reload claims

I am storing the user selected culture into the user claims and i have a custom RequestCultureProvider that reads this value and set the request culture accordingly.
The application will have a profile page where the user can change his preferences (culture included). After save the data to the database I need to silently re-signin the user in order to update his claims.
Additional info:
I'm using IdentityServer4 with AspNet Core 2.0 and Asp.Net Identity
I'm loading the culture to the claims in the OnTokenValidated event (client apps). It can also be done in the GetProfileDataAsync (IProfileService) or UserClaimsPrincipalFactory (ASP.NET Core Identity)
The system is composed by 3 web apps (Idsv4 + app1 + app2). The profile pages are implemented in the app applications.
With a single web app configured with Asp.NET Identity you can use the method RefreshSignInAsync from the SignInManager to regenerates the user's application cookie, however I need to trigger this process from the client apps (app1 & app2), so no access to SignInManager.
I tried to use HttpContext.Authentication.ChallengeAsync("oidc") HttpContext.Authentication.SignInAsync and apparently the authenticate endpoint is invoked however I cannot handle the response and it generates a infinite loop in the MVC action where I'm invoking this code.
So, how can I achieve the silently re-signing with Idsrv4?

When will be IResourceOwnerPasswordValidator be called?

I have my users data back in my old app. I wanted to try IdentityServer4 for my auth with ASPNET Core Identity.
I've seen examples that they used Aspnet Core MVC with Auth for their login. They also implemented IProfileService and IResourceOwnerPasswordValidator.
Saw an example where he used Postman to connect to http://localhost:5000/connect/token, it triggered the IResourceOwnerPasswordValidator
Now, when using the UI (referring to AspNet Core MVC Auth) for login, when will be the IResourceOwnerPasswordValidator be called? Or will it be ever called?
IResourceOwnerPasswordValidator is the interface that denotes the contract for validating all resource owner password grant/flows.
Basically it will only be called when you do the password grant against the token endpoint. It will not be called upon in a normal UI based flow (like implicit flow for example). So if you try a password grant you will see it being used.