Can you add to a claims identity in Identity 2.0 without redirecting the user - asp.net-identity-2

So, if you have a claims authenticated user, and you need to add additional claims that your application needs, can you do that without sending the user back through another request?
What I have is an application that has an existing identity token that is set in a cookie. I want to push an update that requires us to update that claims identity so it has a new claim. I don't want to log all the users out.
I'm familiar with using AuthenticationManager.AuthenticationResponseGrant to do that in an action method, however, I want to (somehow) detect that it doesn't exist in a global way, and dynamically run that?
Is there a way to use OnValidateIdentity?

Related

SAML protected resource

I am trying to protect a resource using SAML. There are three actors at play: identity provider (IDP, outside of my control), service provider (SP, I happen to be using spring-security-saml, but this question is not specific to that), and the protected resource (PR, some protected endpoint in a service outside of the SP).
There are two scenarios that I need to support:
The user attempts to access the PR for the first time, without any kind of session.
The user attempts to access the PR again, when they have previously accessed it.
There is ample guidance on how scenario 1 should work as it is the standard way to use SAML from what I've seen. Scenario 2 seems to be less standard though and I have yet to find any definitive documentation on how it should be handled.
In scenario 1, the flow seems to be standard:
User attempts to access PR
PR directs the user to the SP
SP does the normal SAML assertions with the IDP then redirects the user to login with the IDP
User successfully logs into IDP
User is redirected back to SP with information about the user
SP redirects back to PR (possibly with some kind of generated token to use in the future or additional information about the user)
Information from PR is supplied to the user
It is scenario 2 that I am less clear on, my thinking is the following:
User attempts to access PR with token provided in previous scenario
PR checks the validity of the token with SP
SP determines if token is valid (how is this done? There doesn't seem to be anything in the SAML standard for checking if a session is active)
PR allows access to resource depending on response from SP
My questions are:
Is my understanding of scenario 2 correct? Is this how SAML is intended to be used?
How would I check the validity of the session with the IDP?
Does the PR have to check the validity of the session on every request? Since SAML doesn't require an expiration (like OAuth access tokens) there doesn't seem to be any way to cache a user's session.
There can be two conditions for accessing the PR.
A valid application session created by PR with a specified time before it needs to be renewed.
A valid SAML token on which to base the application session.
The PR could take the view that as long as the SAML token is valid then the application session is valid. Or it could decide it wants to create a new session every 10mins, which means redirecting to the IdP to get a new SAML token on which to base the new application session. It depends on the resource being protected. In a sensitive resource, medical data perhaps, the session should be managed accordingly.
In terms of SAML token validity, the IdP issues the token for a set period of time using Response/Conditions/NotBefore and Response/Conditions/NotOnOrAfter which are shown in the examples. There is also Response/AuthnStatement/SessionNotOnOrAfter which can be used to check validity. This:
Gets or sets the time instant at which the session between the
principal identified by the subject and the SAML authority issuing
this statement must be considered ended
from here. This effectively limits the PR session as the IdP "disowns" the user after this time. e.g. a public walk-in access request for an hour's access to PR. NotOnOrAfter refers to the assertion while SessionNotOnOrAfter refers to the user. After SessionNotOnOrAfter the IdP might not authenticate the user depending on policy etc.
If the PR needs to renew the application session, it could ask the SP to validate the SAML token, which could involve working out whether NotOnOrAfter is in the past. If it is, then the SP would start the process with the IdP again to get a new SAML token. If an IdP is dealing with a sensitive PR, it may release attributes for a limited time, depending how access is granted at its end.

How do I specify a custom policy to only the first time a user signs in?

Context
We have created a custom policy used when users are invited to our SPA application.
The policy does one time user initialization like creating records in our database by invoking the REST API capabilities. Everything here works as expected: The custom logic is executed and we get and id token back.
The problem starts when we are supposed to get an access token for a protected API when invoking the msal.js method
"acquireTokenSilent".
We now see, that the custom policy is executed again, the REST endpoint is once again executed and it's trying to create the user again.
Question
Isn't it possible to get an access token without executing all business logic defined in a custom policy?
I thought that getting an acccesstoken was completely separate from the policy, since we are already authenticated when we got the id token.
acquireTokenSilent in MSAL.js 1.x uses an iframe that runs through the login with prompt=none.
So in the case of implicit grant flow (which is used here), the answer is that it runs through the login flow every time the token is refreshed.
There are a couple choices here:
Make the API endpoint idempotent, i.e. allow calling it multiple times (but ignore the request if the user already exists)
Set a claim on the user that is stored in session state (SSO) and skip the REST API orchestration step if that claim has a value (or you can use the objectIdFromSession claim, which I think is there in the starter template)
The first option is sort of the simplest, and I assume you've already made it like that since it would be called again also when the user logs out and logs back in.
It might result in a lot of requests to that API though.
To avoid that, you could use the newUser claim or set an extension property on the user after the API call.
When calling acquireTokenSilent(), pass in a new authority for a normal Sign In policy. That Sign In policy needs to have session management (SM-AAD) and the same SM-AAD SM technical profile must be present in a technical profile within your invite policy, such that the user can get SSO via the Sign In policy after using the Invite policy.

Link a third party application account in Cognito

I need to link a third party application credentials to the one the user uses to connect to my application through Cognito. In other words: user connects to application A (my application), then application A asks user for credentials to connect to application B. Application A then interact with application B with the credentials provided by the user. I would like to link those identities but let the user connect to application A only with credentials I provided him (and not from the ones he uses for B).
AWS has AdminLinkProviderForUser in Cognito which doesn't satisfy the last requirement.
Application B offers multiple authentications: Form, Basic HTTP, SSO, OAuth2 and OpenID.
Is there any way to link the two identities in the way described above and store it in Cognito for future use?
If I am understanding you correctly - what you need is for the user to log into your application with credentials they have for another application and then store the login they have for that application and provide them with new login details where those login details link them to your application and the that application.
Have a look here: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-identity-federation.html
However taking that approach the users will still login with application B details. But Cognito provides that out of the box.
If for some reason you do not want to take that approach - and you want to have a force change on the password you must do the link yourself.
A suggested approach would be as follows (Making use of Lambda Triggers in Cognito User Pools):
Pre-signup lambda trigger:
Get the user credentials
Use the credentials to make the call in that lambda function to
application B.
Get the authentication response from that call
Pass this as a param to your Cognito user attributes
Make a call using AdminCreateUser(https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminCreateUser.html)
Now you have the user stored with the auth data from application B as a custom attribute.
This is not the best way to do it though because auth data usually needs to get refreshed which will add extra complexity. You could do that refresh in a Pre-Authentication Trigger that updates that custom attribute for the user.
Honestly, if application B is custom, I think the best approach for you will be to use OIDC Provider approach https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-oidc-idp.html

Auth0 - Rules & Groups && User Management

I have created an account with Auth0 and I am trying to get a simple login for Angular 2 to our backend API.
1. What I am trying to do is to be able to access the roles in the API to see whether the user has the correct permissions.
I have enabled the Auth0 Authorization extension I have gone in and created one group and one role, I have assigned these to a test user which I have created, I have then gone to the configuration and published the rules for token contents and persistence.
How can I view the permissions/groups from the JWT in an nodejs app? I am using express-jwt and this:
const authenticate = jwt({
secret: config.get('AUTH0_CLIENT_SECRET'),
audience: config.get('AUTH0_CLIENT_ID'),
credentialsRequired: false,
});
Which is giving me details such as iss, sub, aud. But no details on the user metadata, how am I able to retrieve this? Also as I have clearly not used Auth0 before, is it best practice to store the user details on our own databases also so I can use my own ID to store against the user actions, or is it possible to use an ID if Auth0 give one to store against user actions in our database.
EDIT 1
Ok I can see there is an options parameter for the Lock which you can pass scopes in, is it bad practice to request these when logging in? There will only really be a handful of groups/roles for now. Or is better that the API can lookup the user using the token provided to get the app_metadata to view the permissions etc, if so how can I look this up?
2. How am I able to manage the users and view them so I can display them in our own admin panel and manage the permissions they have.
For the case where the groups and roles information are available within the token itself (as groups and roles claims) and given that you're using express-jwt then you can access this information on the server-side by accessing:
req.user.groups
req.user.roles
In essence, express-jwt will make the claims contained within the token available in the req.user object.
In relation to the ID you use to identify the user you can use the value contained within the sub claim of the user token. This value is guaranteed to be unique and stable so a recurring user that uses authenticates in exactly the same way will always have the same value within the sub claim.
You already discovered that one way to include the groups and roles information is to request it through the scope parameter. It's not a bad practice to request this information to be included in the token, however, you need to take in consideration that tokens delivered through the implicit grant which is used by SPA are included as a part of the callback URL and as such their maximum size is constrained by the limits imposed on URL's.
In regards to your second question, you could implement your own management backend by integrating both the Auth0 Authorization extension API and also the Auth0 Management API; see the following links for more info:
https://auth0.com/docs/extensions/authorization-extension#enabling-api-access
https://auth0.com/docs/api/management/v2

Building a Web-API with Oauth2/OpenID connect

I'm trying to understand conceptually and practically how to perform an oauth2 with openID-connect flow in my web-api application, utilising Azure AD.
Importantly, when a request is made to the API I want to know who made the request.
My current understanding is :-
My client would detect that the user isn't logged in and redirect to a sign-in.
The user would provide their credentials, and be redirected back to the client, along with an oauth2 token.
This token would be supplied to web-api endpoints for any requests.
This is where it gets murky for me.
How exactly do I use this token to authorize access to a particular resource, determine who is accessing the resource, and what is the mechanism that does so?
I'm sort of assuming that I would need to reuse the token to make a call to the Azure AD user endpoint - if the token was indeed valid, the AD endpoint would return the users details - thereby providing some means of determining that the token is valid and providing details on the users identity. Authorizing access to a resource could be done through membership of groups in Azure AD.
BUT ...
I can only assume this a solved problem, and have noticed use of OWIN middleware as per this example
https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet
But I'm still rather unsure as to what is exactly going on.
The service makes mention of scopes and claims, but I don't understand where these are derived from (I assume from a token supplied by the client, but not sure). The service must be receiving identity information in the call.
Which brings me to two points, for this to be secure -
The token provided in call to the service would need to be secured in transmission (hence the use of HTTPS) - to prevent MITM.
The token would need to be signed some how - I guess by using client secret or something - to prevent information in the token being spoofed.
Can someone help me clear up this muddled mess?
In particular -
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
How to limit access to some endpoints of the API based on a user role?
What do I do to practically achieve this by building on existing middleware and libraries available to me?
Disclaimer: This will not be a comprehensive answer. It is off the top of my head.
OpenID Connect provides an identity layer on top of OAuth. In your case, Active Directory provides the authentication and sends back an access_token. The access token represents a user that AD has authenticated. If your doing OpenID Connect, then AD will also send an id_token, which may contain additional identity information (such as birthday, avatar, and whatever else AD exposes.)
Neither OpenID Connect nor Active Directory have anything to do with the the roles that your app assigns to a user; roles are entirely the bailiwick of your app. You assign user roles just like you normally would; you assign them to the nameid though instead of to an email address or username. Your app no longer has to authenticate the user but it does need to assign roles to the nameid.
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
The identity is embedded in the access_token that AD includes in its response. This token will have a nameid in it that your app can associate with a user and role. The nameid is like an email address, username, or other uniqueID that your app uses to recognize the user.
How to limit access to some endpoints of the API based on a user role?
You choose. When your app receives a request with a particular access_token, that token will be associated with a particular user via its nameid, and you can assign whatever roles and rights to that user. Basically, associate roles with a nameid.
What do I do to practically achieve this by building on existing middleware and libraries available to me?
There is an unfinished demo here, though it doesn't use Active Directory as the provider, instead, it uses an internal provider. For the demo, the username is shaun and password is Testing123!. The source code is here.
Here is the link to the source of another demo, though again, it doesn't use Active Directory as the provider, instead, it uses Twitter.
The nice thing about OAuth and OpenID Connect is that we can use whatever identity provider we want, so you can adapt the demos to use Active Directory.
Apart from question #1 (the identity is verified on the service side) all your question are very open ended and would require a super long answer.
I would recommend reading https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/ - it is a good introduction to the flows underlying many of the modern authentication cenarios, including the web API one you are focusing on.
Once you have read that, you will find a complete set of samples in https://azure.microsoft.com/en-us/documentation/articles/active-directory-code-samples/ - in particular, I suggest studying the web API and thru authorization one to find guidance on the 3 questions you listed. HTH!

Resources