Change client credentials of a client app after initial load in identityserver4 - oauth-2.0

We are using identityserver4 for single-sign on and to protect our api resources. We have a scenarios where we are exposing our API endpoint to external apps using Client Credential mechanism. Now the business ask is to not share the client-secret to users in an offline mode rather than give them an option to do a self serve for periodically rotating their keys.
Now the problem is after the application starts and initial load of the in-memory clients, incase if we want to refresh the ClientId-ClientSecret for a Client we are unable to do that and the new credentials are in force only after we restart our application.
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryPersistedGrants()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients(Configuration)) //Loading Clients
.AddAspNetIdentity<ApplicationUser>()
.AddProfileService<ProfileService>()
.AddDeveloperSigningCredential();
We are looking for an option were we can dynamically refresh client credential for our client apps. Any help is appreciated. Thanks :)

Related

Oauth2.0 | How to manage user session in Single Page application running in an iframe?

I'm new to security domain, and recently I have learned about Oauth2.0/OpenID connect and JWT tokens. I have an existing REST based web application where I need to implement security.
Server
Application A: Spring boot back-end application sever, with some RestEndpoints exposed connected with Mysql database.
Front End
Application B: Spring boot Web Applicaiton which have some JSP pages for login and some other template features(Also connected with same Mysql database used by back-end server).
Application C: Inside application B we have an Iframe in which Angular app is running, angular app calls the back-end server and show data.
Also in future we want to use SSO for our application as well.
Current Security
At the moment we don't have any security on back-end server (i.e We can simply call RestEnd points without any authentication), Application B has basic login security implemented via spring security. User logins on application B and then he/she can use application C (Angular) as well. User session is managed at Application B, when session expires users forced to logout.
Oauth2 Authorization
What we are trying to acheive is make the server (Application A) as Oauth2Resource server and Oauth2Authorization server. Application B (JSP front end) remove database connection from it as well as the login controller, application B will call oauth2 server for authorizing user with "password" flow, when application B will receive access_token and refresh_token it will then somehow pass it to Iframe (angular app) to store these tokens inside cookie and on every subsequent request to server angular will add access token to it.
I've read articles about that Oauth2.0 have deprecated the use of "Implicit Flow", and they prefer to use the "Authorization Code Flow". I am having a very hard time to understand how this flow can be used for single page applications(SPA like angular). Also where to store the access_token and refresh_token if I use the implcit flow? I'm aware that storing both tokens in cookies is not a good practice.
Also how to manage user session now? what I have gathered so far is that, on requesting resource server with Bearer access token, when we get unauthorized response, we'll then request for new access token with help of refresh token, but in case when refresh_token is also expired I will force user to login screen. Is this right approach?
Sorry for the long context, any help will be highly appreciated. Thanks
A couple of recommendations:
Use a low cost cloud Authorization Server, eg Azure or AWS
Focus on building great UIs and APIs, which is not easy
In terms of flows, use the Authorization Code Flow (PKCE) and the OIDC Client library to manage SPA security.
A good starting point might be my First Tutorial to understand how to get integrated. Generally:
SPAs use short lived access tokens and should store them in memory
SPAs traditionally do not use refresh tokens directly
Feel free to post back follow up questions and I can point you to additional resources. You should aim to avoid running the SPA in an iframe by the way - see my other answer.

using third-party identity provider with Azure AD and MSAL.js

I have created a Single Page Application with Angular and authentication/authorisation is managed by Azure AD. I have used MSAL.js to initiate the implicit flow.
Everything is working fine, but now my client wants to use her own identity provider (IDP) so that users have a single point of entry for all apps (including mine). This IDP is not mainstream, it is built in-house by the client;
I want to keep using Azure AD to manage authorisations (groups, roles...). I also want my application and its dedicated backend API to be registered in Azure AD, not in the third-party IDP.
Azure AD should remain responsible for providing the Access Token to the SPA in order to call the API.
Somehow, I should redirect the user to the third-party IDP login form and upon successful login it will redirect to my SPA, which should then associate the tokenID with an AzureAD account and retrieve the Access Token (I suppose I will have to create an account in Azure AD for users identified in the third-party provider)
However I'm having a hard time figuring out how to achieve this and if it is at all possible ?
What would be the recommended approach for this scenario ? Can I still use MSAL.js or do I have to rely on something else ?
ARCHITECTURE
Your goals are completely correct and you should not need to change a single line of code to integrate a new IDP - so you can continue to use MSAL.js.
PREREQUISITES
In order to integrate their own IDP into your system you need to insist on certain prerequisites:
The client needs to provide a Standards Compliant Identity Provider
Typically the IDP needs to communicate with your Authorization Server (Azure AD) via either Open Id Connect messages or SAML2P messages
A home grown IDP may not meet these prerequisites in which case you need to explain to the client that they need to get standards compliant.
HOW FEDERATION WORKS
Your UI will redirect to your AS
The AS will redirect to the IDP, when given a trigger
The user will authenticate in the IDP
The IDP will post a token to your AS to identify the user
The AS will issue another token to your UI
Note that there is no coding involved here - there is only standards based integration between vendor systems.
WHAT THE CLIENT WILL GIVE YOU
Client details are often supplied by giving you their metadata document, and these details are then configured in Azure AD as a trust entry:
The entity id of the IDP
The token signing public key for IDP tokens, so that your AS can validate them
A URL to redirect to
WHAT YOU WILL GIVE THE CLIENT
A similar trust entry will need to be configured in the client IDP so that it trusts requests and issues tokens - though no certificate is usually needed here:
The entity id of the AS
A URL to post tokens to
TRIGGERING THE REDIRECT FROM THE AS TO THE IDP
One option is to forward the entity id to the authorization server in Open Id Connect redirects. Often an 'idp' query parameter is used, something like this:
Client accesses your app with a bookmarked URL:
https://app.mycompany.com?idp=urn:client.com
You add an extra parameter to the Open Id connect redirect to tell it where authentication should happen:
https://login.mycompany.com/authorize?client_id=XX&idp=urn:client.com
AZURE AD SPECIFICS
Once you understand the high level process there is some technical stuff to configure the connection and you'll need to consult vendor documentation, such as this Microsoft Azure B2B article.
PRACTICE
If you haven't done this before then you need to invest some time to get a connection working and then document the process.
You can use Windows Server and ADFS to simulate a client connection, then integrate it as a SAML2P connection. There is a learning curve though, and you'll need infrastructure such as ADFS certificates.

Where is the OAuth access token stored in the browser in case of Authorization Code Grant flow

I entered my credentials and logged into a web application protected by OAuth Authorization Code flow. Then I performed below steps:
Open browser developer tools (F12) and start capturing network traffic
Try to get data from an API. This request will require access token to be sent. But I am able to view the access token on the network tab for that particular request in the request headers as seen in screenshot below:
My understanding was as below:
The access token would be stored on the web server where my web application is running. That will never be stored in the browser.
Since I am able to see it in the network tab, where exactly is the access token stored in the browser? We use Azure AD as the IDP and Owin packages to integrate OAuth auth code flow.
The API request is over HTTPS and I am able to view the full request details in network tab. Is this expected?
There are only so many places where you can persistently store data in the browser.
As of this writing:
Cookies
Session Storage
Local Storage
IndexedDB
Web SQL
If you are using libraries to implement the OAuth2 flow any of these could be used. You can find and inspect these storage systems under the "application" developer tools tab in Chrome, or similar spots in other browsers. What you can see/inspect depends on the domain you are currently on in the active tab.
If your client is server based, and thus confidential, you should store your token in a Secure HttpOnly cookie. Then proxy requests to the backend through your own server, including the bearer token from the cookie. This would be the best spot.
If your client is a single page application, you should consider storing it "in memory" and just reauthorize when reloading the page.
If that is not an option then Session Storage is your most secure option. This is most often used if OAuth2 is performed by your frontend.
In any case, if the OAuth2 flow is performed by frontend components only, it is to be expected that the token resides somewhere in the mentioned storage systems, and that it is included in the requests as visible in the network tab of your developer tools.

Is it possible to re-use access token at multiple server - IdentityServer4

Currently, we are building a web-based application, and we have web-server and we have application server host our resources. Also we will use Mule ESB to be able to use any web-service or api. And we will have Alfresco DMS solution and we will use alfresco service with Mule ESB .
We are investigating how we can implement SSO approach for this scenario. We have already IdentityServer4 for identity federation. It issues access token for client, and we need to authenticate the user whenever the user at the Mule ESB side without asking user the credentials again.
According to my researches, external Identiy provide can be added on Mule ESB. The thing we do not is that can the access token issued the cliet while user logging into application server be passed to Mule ESB and Mule ESB can validate the access token before
Actually, the question that we are looking for answer is that is it possible issue client an access token only for once, then validate this token in each side (Mule ESB, Alfresco) without asking user to enter the credentials again and again.
Using access token for multiple applications is not recommended. This is highlighted through this and this resources. Basically scope of the access token must be restricted. This is to precent access token being misused.
In your scenario, you have multiple applications. If you goal is to use one access token shared across all of them, I suggest not to do that. Instead, you may use single access token against multiple APIs given that you request access tokens with such scope. For example, APIs in ESB can be designed to accept access tokes if scope allowed to do so (scope can be validated from API endpoint through token introspection). But allow each client app to obtain their own tokens. This make your architecture more secure.
One solution for SSO is to allow browser based SSO. Identity providers maintain a session in the browser. So if one of your client go through a login, your next client will use that previous session to skip the login page. This is essentially a SSO behavior. For example this is what allows you to use Gmail, Youtube and Google Drive with single login. Browser maintain a session with Google. Each app obtain tokens, but skipping login page.

SSO for IdentityServer4 with grant type "authorization_code"

We're in a scenario where a single page application that we develop ourselves (AngularJS front end with https server APIs in the back) opens another
web application developed by a partner of ours in a new browser tab, and where this second web application needs access to a https server API that is also developed by us.
After looking around for possible solutions, we have now created a proof of concept using IdentityServer4, where the second web application is configured as a client with "authorization_code" grant type. When all applications are running on the same domain, the third party application is able to access our https server API without being prompted for user id and password.
The implementation of the second web application in this proof of concept is very much like the solution presented by bayardw for the post
Identity Server 4 Authorization Code Flow example
My question now is:
When - in production - the second web application no longer shares domain with our application and our https server API, will a call from the second web application be prompted for username and password when accessing our http server API?
Seems, you are missing some major things. First of all any API should never ask for username and password. Instead your app(s) should put a token into each request and API should validate that token. Where the user credentials should be asked is when a user accesses your (or 3-rd party) web application. Then Identity Provider creates an Identity token (usually to be persisted in a cookie and used within the app) and access token (to be provided to APIs). Each token is issued for specific Client (app) pre-registered in IdP. Probably when been hosted at the same domain your two apps shared the identity cookie and Client Id what is not correct. In production scenario you have to register the apps separately. All the rest should work fine (if you follow the routine i briefly described at the beginning).
Chosing to post an answer myself from feedback through other channels:
This boils down to the session tracking of the IdP. If cookies are being used to track IdP session, the behavior is impacted by whether a session cookie or a persistent cookie is used.
In general, I have found that Robert Broeckelmann has great articles on medium.com.

Resources