Identity server 4 and Angular app authenticate to achieve forever lasting session - angularjs

Current structure:
I have angular app as Client, API as data source and Identity server as Identity source. In angular I authenticate user against identity server and use returned token to authorize user against API. Which Grant type should I use to authenticate my angular app user against identity server?
According to http://docs.identityserver.io/en/release/topics/grant_types.html, I should use Implicit grant type.
Problem is that with Implicit grant type there are no refresh tokens. So my question is, how should I keep my user session alive in angular app (access token valid) ? - without asking user to authenticate himself after every time access token gets expired.
My goal is to have session alive (token valid) until its killed by user (logged out)

Yes, the Implicit flow is the one I would use. If your authentication provider supports sessions, you can use OpenID Connect to get new tokens without user interaction. Before the token expiration, create an authentication request (/auth endpoint) in a hidden iframe with prompt=none URL parameter (id_token_hint=... parameter should be present too according to the OpenID Connect RFC). If the user session is open, you will get new tokens, otherwise error is returned (user interaction required).
There is the OpenID Connect Session Management RFC that describes this process and more (single sign on).

Related

Initiate a logged in session by providing a valid access token with mod_auth_openidc

The scenario I am facing is the following:
My server has acquired a valid access (and refresh) token for the identity provider. I would like to start a mod_auth_openidc session and put it's value in the appropriate cookie.
Is this possible with mod_auth_openidc?

IdentityServer4 - Understanding flows and Endpoints. How is it related to OAuth and OpenIDConnect?

I am integrating the security aspect of webapplication. I have decided to use OAuth,
so we have a REST WebApi in AspNet Core 3.0, the client which is a SPA created in React, and the Identity Server 4.0 app which is also in AspNet Core 3.0.
I read that OAuth is created for Authorization and not for Authentication.
For Authentication, seems that exists something else called OpenIDConnect, so the first question that comes to my mind, and on which I cannot find an easy answer is: are OAuth, OpenIDConnect and IdentityServer related technology?
Which is the best solution for authentication, considering that I would like to create users in a SqlServer Database, and if it's possible I would like to use Entity Framework for the porpose?
The flow for my authentication would be:
User writes Username and Password, if they are right he receive the JWT Token, without redirecting him/her to the authorization page.
At this point the problem are:
which is the right endpoint to do this flow:
is it the /authorize or the /token endpoint?
I have a lot of confusion for the questions above.
The second thing, what is the best way to retrieve the user informations?
For example if my endpoint needs to understand from the logged in user what are his data, I think that or I retrieve from the endpoint or from the JWT token.
Even here I have no clue on which is the best.
I read that OAuth is created for Authorization and not for Authentication. For Authentication, seems that exists something else called OpenIDConnect, so the first question that comes to my mind, and on which I cannot find an easy answer is: are OAuth, OpenIDConnect and IdentityServer related technology?
That's right. OAuth was the first one introduced and allows the person requesting it access to the resources (its handing out access tokens). OIDC (OpenID Connect) on the other-side extends this concept by an identity, the authentication part.
The identity token verifies the identity of the person to your application. Instead of providing identity via username + password (i.e. user creating an account on your website), they get redirected to your authentication provider/app and enter their login there and you get an identity token in return (and/or an access token, depending on the flow and scopes you request).
The identity token is an JWT token (or reference token). The JWT token contains all of the users identity information required for your application (user id, email, displayname, age, etc.) and is cryptographically signed. Only the Identity Server knows the key used to sign it up and you can verify it with the public key from the OIDC (IdSrv here) provider.
Reference token works similar, but claims are requested on the server side and cached.
With identity token you can not access the users resources. Example: Facebook.
When you sign in your application with an facebook account, most page will only request identity token to verify that its the same user (instead of using a username / password combination). But with that one, the application can't access your facebook posts or do posts in your name.
If the application requests an access token (token scope), then also an access token will be returned (if the application is allowed to via allowed scopes). You will be asked to grant the permissions to the resources which the application requests.
With that token, the application can read your posts or post in your name.
Which is the best solution for authentication, considering that I would like to create users in a SqlServer Database, and if it's possible I would like to use Entity Framework for the porpose?
Doesn't really matter. Either one can be used, all you really need is the "sid" (subject id) claim and associate that one with your user.
Identity Server can issue both, depending on what the client asks (if client asks for id_token response type, it will receive an identity token, if it asks for token an access token. Both can be specified or just one).
At this point the problem are: which is the right endpoint to do this flow: is it the /authorize or the /token endpoint? I have a lot of confusion for the questions above.
/authorize is used to authorize the user (have him login, and send back to your website). Its used for so called interactive flows, where the user enters credentials
/token endpoint you can only retrieve a token (resource owner flow (username + password), client credentials (for machine to machine authentication), refresh token (to get a new access token by using an refresh token (if you asked for offline_access scope, which gives and refresh token)
The second thing, what is the best way to retrieve the user informations?
the /userinfo endpoint, see docs: http://docs.identityserver.io/en/latest/endpoints/userinfo.html
As the doc says to access that, the client needs to request the openid scope.
For example if my endpoint needs to understand from the logged in user what are his data, I think that or I retrieve from the endpoint or from the JWT token.
Yes you can retrieve it from JWT token, if you use JWT token. If you use reference token, its just an ID.
And last but not least the /introspection endpoint can be used to validate the token (if your consuming application has no libraries to decrypt and validate signature of the token.
If you can, its best to use the Identity Server client libraries (i.e. IdentityServer4.AccessTokenValidation package for ASP.NET Core or oidc-client for npm/javascript based applications) which should be picking up the correct endpoints, so you don't have to worry about it

How jwt token get reissued in azure ad OuthImplicitFlow

Currently the scenario is. When I am trying to access my app,it first sends my app to Microsoft login page and after successful login it returns a id token which is used to retrieve the data from backend server. Now the expiry time of token is approx 1 hr. Now when this token expires, Microsoft issues a new token(JWT Token), it not redirects me back to login page.
But ideally it should be redirected to login page, as in implicit flow, there is no refresh token. Then on what basis it is issuing a new token ?
I am using Microsoft adal library in my front end side for authentication.
here's the link: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow#refreshing-tokens
The implicit grant does not provide refresh tokens. Both id_tokens and
access_tokens will expire after a short period of time, so your app
must be prepared to refresh these tokens periodically. To refresh
either type of token, you can perform the same hidden iframe request
from above using the prompt=none parameter to control the identity
platform's behavior. If you want to receive a new id_token, be sure to
use id_token in the response_type and scope=openid, as well as a nonce
parameter.

How to redirect to another application Single Sign On Identity Server 4 and logout

I have an application A and an application B both of which are Asp.Net MVC Core 2.2 which should behave as if they are a single application to the end user; I'm using SSO in Identity Server; and in order to share claims between them I have given them the same Authentication Cookie name, Application name and access to a shared data protection key location as per the instructions:
https://learn.microsoft.com/en-us/aspnet/core/security/cookie-sharing?view=aspnetcore-2.2
If I login to A and then Redirect to B I can see the claims as expected shared between the applications; however if I then logout from B the logoutId which is generated and sent to the Identity Server 4 has no knowledge of B.
If I give a different name for the Authentication Cookie then I cannot share the claims but after redirecting to B and then logout from B the logoutId which is generated works correctly.
If after redirecting to B then waiting for the login session to timeout and re-authenticating then logout the logout of B works correctly; and the logoutId which is generated and sent to Identity Server 4 has knowledge of both A and B.
I believe this is because after redirecting to B when the Authorize attribute triggers a check that the user is Authenticated; which the user is in Application A and this is 'mistaken' for being already Authenticated in B; as this is a SSO there is no reason to authenticate in B as if authentication was checked with the Identity Server 4 then the user would be authenticated; however since the authentication is not checked the knowledge that the user has redirected to B is not stored in the shared authentication cookie and thus on Sign-out the Identity Server 4 does not receive the correct logoutId.
What can I do to force Identity Server 4 to be notified and thus update the Shared Cookie after the redirect to Application B?
You should not use shared cookies between your Angular apps to achieve SSO behavior. Neither you should share claims between those apps. In OAuth, the SSO is achieved by having a single authority uri (your Identity Server 4) that all your domain apps use to authenticate users, meaning that once user goes to application A and is redirected to login and completes login flow, the cookie is left on the on your Identity Server 4 app, and then once you redirect your application B it will see that it's not authenticated and redirect to the Identity Server 4 which will then use the cookie and automatically log the user in (can even skip consent page optionally).
Single sign out is a bit more difficult and is achieved by using SignOutIFrame on your Identity Server 4. In a nutshell, the idea is that once you initiate the logout flow from one of your apps, after the user successfully logs out from the Identity Server 4 app, the rendering of this SignOutIFrame causes all other clients to optionally participate in the logout flow and clear the session, etc. for a given user. More info can be found here.

How to determine in Keycloak JS adapter whether user is logged in with SSO?

To introduce my current setup, I have 3 components:
Website with some static (CMS) and dynamic parts, a couple of Single Page Applications, everything works on domain spa.com.
REST API, which provides any dynamic functionality (user profile) and is hosted on api.com and requires SSO tokens to work.
SSO server is hosted under sso.com domain
I'd like to determine in my SPA whether user has an active SSO session, so when I'm logged in but I do not have tokens, I can:
do a redirection dance to get tokens
do not allow user to use registration form
I'm using Keycloak JS adapter, which uses iframe mechanism and checks for KEYCLOAK_SESSION cookie and communicates with host window via some flags:
var cookie = getCookie('KEYCLOAK_SESSION');
if (cookie) {
data.loggedIn = true;
data.session = cookie;
}
The problem is that I can not rely on this cookie to check if user is logged in because the cookie has 30 day expiration date, which is way more than an actual Keycloak session lasts, let's say 15 minutes.
This cookie is being set when user gets authenticated and is not refreshed on each token update. I do not understand then it's purpose and the purpose of this flag.
I'm also thinking about relying on local storage and keeping refresh & access token there to determine if user is logged in, either by checking timeout or trying to refresh access token. BUT.. this also is not reliable, because user might have already authenticated using some other application.
To add more context to the problem... one of my SPA applications is a registration wizard, which uses REST API to register user and receives login_hint in return. This login_hint can be used as a wildcard in SSO redirect to pass the challenge and log in immediately.
However, if some other user is already logged in, we get in return session of this other user, not the one that should be logged in because of used login_hint.

Resources