IdentityServer4 SPA to BFF to API Logout Problem - asp.net-core

I'm working through building a prototype of an IdentityServer4-based process where I have an Angular SPA, a "Back-end for Front-end" (BFF) ASP.NET Core API, and a back-end API service (also ASP.NET Core) all interacting with a derivative of the https://demo.identityserver.io/ IdP.
My BFF and back-end API services are based on the samples found at "https://github.com/leastprivilege/AspNetCoreSecuritySamples/tree/aspnetcore3/BFF"
Everything is going pretty well until I try to create the scenario where the user chooses to logout from the IdP Logout page. The BFF service does not 'notice' the user's token and session has been revoked/removed until the tokens expire much later.
I suspect I should be using the process found in the sample https://github.com/IdentityServer/IdentityServer4/tree/main/samples/Clients/src/MvcHybridBackChannel where a cookie event handler in the BFF service implements ValidatePrincipal(CookieValidatePrincipalContext context) to make an explicit call to the IdP to verify the user's token on each request.
First question: is this the correct pattern to accomplish this? Or am I making this needlessly complex?
Second question: what is the method to ask the IdP "Is this session still valid?" (This seems like something that should be easy to do!)
Thank you in advance.

First question: is this the correct pattern to accomplish this? Or am I making this needlessly complex?
Yes it it correct, when you logout directly from IDP you need to inform the client apps that user has signed out. If you are using cookie on the BFF you need to do the same for it. Read more here
Second question: what is the method to ask the IdP "Is this session still valid?" (This seems like something that should be easy to do!)
Idp is not validating the session or cookie, it validates the token. session/cookie management is the responsibility of client apps. Read more here

Related

Consume JWT token in asp.net core web application

In one of my project need to consume JWT token from asp.net core web application. My trial project is on github https://github.com/SapanPatibandha/JWTAuthentication
This has one server JWTAuthentication which is generating jwt token base on username and password.
Second component is AnyAPI which method is protected by self verification of JWT.
Third important part and where I have problem is Web application.
Need to create login screen in this application, base on this user detail call login api from JWTAuthentication and use that token for all further use of api from that web application.
I am not sure about middleware configuration and how to store this token on web application.
Thanks
IMO, What you asking for is a journey that need some investigating time, that's not what could be answered shortly, so... I'm gonna make this as compact as possible
What you're doing in the repo is hand-generate and validate Jwt Token. If that's required, investigate these stuff:
Generating Jwt on central identity provider server (which you currently have)
Validate Jwt on api resource (which you currently comment that out)
On application(seems like you make use of classic MVC or razor page), create login form that use ajax to get Jwt from identity provider server, store it on client side (browser), then attach it with every request that make use of AnyAPI, by cookie or header or something you saw reasonable. Or if you choose to save the token on Server side, implement your own session-Jwt mapping logic(Actually, some kind of Js SPA would be more suitable for this kind of approach).
Another approach would be implement a more proper Oauth implementation. I consider 2 most widely acknowledged in .net ecosystem would be Identity Server and OpenIdDict. Highly recommend to check them out.

Permanent bearer token authentication for ASP.NET Core Web API actions

I have a working ASP.NET Core 3.1 Web API, and I would like to restrict access to specific actions in some of the controllers.
There are no valid human or web browser consumers of this API, so no cookies, and no need for a standard challenge/response authentication model. I just want to make sure that anyone invoking certain actions is allowed to do so.
Since the controller actions are so atomic, I was hoping I could implement something simple, or at least simpler than a complex, external, role-based identity service. That's what led me to reading about bearer tokens, where I read very helpful guides such as this stack overflow answer, and this JWT overview.
However, these models seem to treat the token as a temporary replacement credential to a permanent, conventional username/password credential.
Would it be difficult to model this with permanent bearer tokens instead? This would greatly simplify most authorization flows and management, as consuming apps would only need to request a new token if the Web API revoked them. And since the authentication is at the action level, a simple "yes/no" answer to access seems perfect for a permanent token that doesn't care about long term claim or role management.
I don't know if I'm thinking about this incorrectly or naively, but that's my question. Is it reasonable to use permanent bearer tokens, and if so, how do I implement that in ASP.NET Core 3.1?
Thanks!

Authentication flow for temporary credentials in the browser

I'm trying to wrap my head around a specific proprietary authentication flow used by one of our customers, and how to implement it in IdentityServer4.
We're developing an SPA with some microservices as backend and do all our authentication/authorization with IdentityServer4. The standard workflow for the SPA is (as expected, I guess) the implicit flow using oidc-client-js (for now).
Now the problem: one of our customers has something like a homebrew SSO solution dating way back. Users basically authenticate at a central portal and get a link to the application with a token attached. This token is valid for a few minutes and contains the temporary user credentials, I need to somehow authenticate at our IdentityServer.
My first attempt was the client credentials flow. Doesn't work, as the client cannot refresh its access token later, once the initial credential token ran out (the client does not and cannot have access to permanent credentials.) My current approach would be to kind of "hijack" the implicit flow, by authenticating with the given temporary credentials and from there on out use the normal refresh cycle without further need for any credentials.
Is this a valid approach or am I completely on the wrong track? If it's valid: how do I get IdentityServer4 to do my bidding? I cannot use IResourceOwnerPasswordValidator, because that would require the client credentials flow (I think?). Is an IExtensionGrantValidator the way to go? (If so: any ideas, how to convince oidc-client-js to use a custom grant?)
Thanks for your help.
Regards,
Markus

ASP .NET Core Identity default authentication vs JWT authentication

I am developing ASP NET Core Web API and I am confused by choosing the authentication method. I used to apply default Asp Net Identity authentication, but recently I've known about JWT. So I've implemented Authentication almost as it done in this article: https://stormpath.com/blog/token-authentication-asp-net-core.
But I can't understand the benefits of this JWT. With simple Asp Net Identity Authentication, I don't care about token storage etc. I only need to log in with signInManager and use authorized methods until logout. With JWT I need to think about the token store, expiration, and other difficulties. So, what're the benefits of this JWT? How can I store this JWT token after login? Furthermore, should I even use this JWT? In my case, I need simple authentication for simple WebApi which will be used by one or little bit more users. I've also heard about OpenIddict, Auth0, IdentityServer, so what's the difference between all of these authentication mechanisms?
This is the way I understand this, split in to 3 logical parts.
Authentication Server - this will authenticate and issue the JWT token, when the API need's to validate the token it will send the token to this server to validate it.
Client - this is what serves your web pages, or you app perhaps. This is what will need to request and store the the JWT token. The client will need to pass the token to the api every time it requests data.
API - this is what serves the information and needs to validate the token with the Authentication Server.
So, what're the benefits of this JWT?
JWT is issued to the client and stored on the client side. Having JWT allows multiple client's (App's or Websites) use the same authentication server which distributes JWT and states which API's the client's can use and how.
How can I store this JWT token after login?
I only tried to store it in an Ionic 2 app which uses angular 2 which has a storage module. But i'm pretty sure numerous people have done this already and asked this question:
Simple JWT authentication in ASP.NET Core 1.0 Web API
Token Based Authentication in ASP.NET Core (refreshed)
Update
If your front end is made purely html/js/css and doesn't have a back end to accommodate it you would store your token in local storage, there a multiple npm packages that help you with this like this one. You want to look for Implicit flow.
Otherwise if you do have a back end that comes with your front end you want to store the token in a session/database your pick, there are 3rd party providers to do this like IdentityServer4. You want to use Hybrid flow
Furthermore, should I even use this JWT? In my case, I need simple
authentication for simple WebApi which will be used by one or little
bit more users.
The reason for the whole separation of concerns is performance so you don't really need it since it's just one or a little more users. Do it because it's a learning experience, JWT is not easy to setup from the beginning and will require you to do a lot of reading and you will fail and you will be frustrated but at the end you will know how to set it up and how it works
I've also heard about OpenIddict, Auth0, IdentityServer, so what's the difference between all of these authentication mechanisms?
So what you did in the Stormpath tutorial is NOT production ready. That is just a little demo, to help you understand what JWT is and how it works. The above mentioned are complete libraries that tackle all the heavy lifting and do not require you to built the whole thing from scratch. And the main difference between them is the scope that they cover.
I personally used IS4 and it had me crying no more than 2 times (It was simpler than I thought):
http://identityserver4.readthedocs.io/en/release/
https://github.com/openiddict/openiddict-core
https://auth0.com/docs/quickstart/webapp/aspnet-core/00-intro
Use tokens (JWT) if you have multiple applications or services (web, mobile, other services) connection to your API. Benefits: Stateless, Scalability, No cookie, no CORS problems (if you allow it).
If your API will be used by only one web application use the default ASP default authentication system. Its easier to set up.
If you webapi and user interface are hosted in the same web application, token bases security does not buy you anything over the cookie based authentication provided by the built in authentication. That's because the authentication cookie gets sent back to the keep application on every HTTP request. When you make calls to a website other than the one you signed in on those cookies do not get sent. So JSON Web Tokens (JWT) provide a standard format for browser to send identity information to a website when a cookie isn't an option.
If your Web Api is to be accessed by AJAX calls then JWT may be a desired choice, but not mandatory. judging by the description of your app,it seems to me that the default authentication system can serve you well.
Auth2 is the authentication mechanism that enable external login such as Facebook. It is part of the default authentication system, and you need not do much in order to employ it in your app.
OpenIddict sits on top of Auth2. It is part of the default authentication system, and you need not do much in order to employ it in your app. It is the authentication mechanism that enable external login such as Google+
IdentityServer may be used for large Wep Api that is accessed by Ajax calls. As for instance, you can use IdentityServer to authenticate users longing to a front end Angular app.
Once again, the default authentication system can serve you well.
Hope this helps...

Authenticate Microsoft Account user with ACS using REST

I would like to leverage ACS to authenticate Windows Account users (and eventually users from other identity providers in the future) on a website.
I have found a lot of resources regarding ACS, but most revolve around using WIF/using managed code in the UI layer in order to validate a user. I'd like to avoid that. Is it possible to retrieve a token from ACS by making a REST-based call to ACS using javascript/jQuery to retrieve a token for a Microsoft Account user?
One example that I saw that came close, is this link, however this uses a service identity instead of leveraging identity providers. http://code.msdn.microsoft.com/windowsazure/MVC4-Web-API-With-SWT-232d69da
Here's my end goal:
This website would have two layers, a UI layer (MVC 4) and a service layer (MVC WebAPI). Both of these layers will need to scale independently of each other in Azure.
I'd like to have the UI layer call ACS to determine if the current session is authenticated. If it is, I'd like ACS to return a token to the client. I'd like to store that token on the client as for use in step 3.
Once the user has logged in, I'd like to have the client make a REST based calls to the service layer passing the Microsoft Account/ACS user token along in the header of each request, completely bypassing the UI layer for this second service request. The service layer would authenticate the user with each request.
The client would handle the response codes (200, 401, ect) from the Service layer by either redirecting to the login page, or by displaying the results.
I am unsure about step 2. How would the client browser retrieve a token from ACS that it can pass along to the Service layer?
I essentially want to do what Vittorio describes here, but I want to use a MVC4 web app instead of a Windows 8 store app.
In step 2, your MVC4 Web App is a relying party and therefore relies on the claims in the token presented by the subject/user. So, rather than the UI call ACS, it's really just redirecting the user to ACS for authentication. Anyway, based on your requirements and description, I believe this is the solution you're looking for.
http://blogs.msdn.com/b/vbertocci/archive/2013/01/09/using-the-jwt-handler-for-implementing-poor-man-s-delegation-actas.aspx
Hope this helps.
-Rick
I wrote up this answer before reading Vittorio's blog post that Rick linked to. That seems to pretty much what you want. I'll answer anyway to give some more context on WIF and how this scenario works, but you should check out that post.
First, it's important to note that when using WIF in your MVC 4 application, no authentication or validation is happening in the UI/presentation layer. WIF works at the request layer, and does a lot of things you would have to do yourself if you chose to go the Javascript route (which I don't think is a valid route, though it could probably be done with a lot of work).
It goes like this: When a user hits a page that requires authentication, WIF redirects them to to ACS, where you are then sent to Google/Microsoft to login (the identity provider). After you've authenticated with your identity provider, ACS then posts the resulting access token and claims about the authenticated user back to your application (the return URL in ACS configuration). Finally, WIF handles validating the token that was sent by ACS (no small task), and creates a ClaimsPrincipal object in your application that can be used to identify the user.
It sounds like what you want is impersonation/delegation, where a user logs in and their credentials get carried through from frontend to backend. For this situation, I see no reason why you shouldn't just use WIF for user authentication in your MVC 4 app. The user authenticates and WIF handles/validates the token (though because you're calling a web API you should probably use the JWTTokenHandler for its lightweight-ness). You create an Action in your MVC project that sends a request to your Web API with the token in the Authorization header. Your Web API gets configured to read the Authorization header of incoming request, uses JWTTokenHandler to validate the token, then you're done. You can steal much of the code for the Web API portion from this code sample (particularly the code in Global.asax.cs): http://code.msdn.microsoft.com/AAL-Native-Application-to-fd648dcf