Modify SAML attribute from IDP inside keycloak - attributes

I'm getting an SAML attribute (personal id number) following a successful IDP login. In our keycloak implementation I fetch this using an identity provider mapper with type 'Username Template Importer' and template {ATTRIBUTE.uid}
This attribute is then used within keycloak (via user federation defined endpoints) to call other services to verify the user. The problem I have is that this attribute is in the wrong format. Is it possible somehow in keycloak when fetching the attribute to modify it? Or does this need to be done within the verification service's code?

To solve this type of issue I would think you need to implement your own authenticator, and use that as a "Post Login Flow" on the identity provider.
So first, you have a simple attribute mapper that maps the attribute, and then map this value programmatically to the correct format in the authenticator.

Related

To pass givenname and surname from IdP to SP, where does it have tobe specified in the metadata?

We need to pass first name and last name from IdP to Service Provider, does this have tobe specified in the IdP metadate or in the SP metadata, and how? I can not find OneLogin java properties for this.
They are included as attributes in SAML Assertion which is a part of SAML Response. They don't have to be included in the metadata (but some scenarios may need that).
When you create your custom app in Onelogin (either by using UI or API), you can specify which fields are included in the SAML assertion.
Identity provider sends Response to ACS URL. Behind this URL is service provider's backend service which validates the response (idp, SP, ACl url, StatusCode, session NotOnOrAfter, etc. depending on the needs) and processes/forwards needed values and redirects user to relayState location.
Note: There are also other ways to implement SAML authentication flow and it is possible that SAML response could include only authentication assertion with NameID and attributes are queried afterwards. This may require also adding attribute related fields to metadata.
We got the names in the SAML attributes in the assertion sent by the IdP. So no need for the Attribute Consume Service URL etc.

Azure AD B2C Access token claims do not update after refreshing token

We are using Azure AD B2C with our application.
We authorize user using the API
https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize?client_id=<client-id-uuid>
&nonce=defaultNonce&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Findex.html
&scope=openid%20offline_access%20https%3A%2F%2F{tenant}.onmicrosoft.com%2F<client-id-uuid>%2FUser.all
&response_type=code&prompt=login
using above we fetch the authorization_code.
This auth code is being used to authenticate the user with the application and fetch the access_token , refresh_token and id_token using
POST /{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token HTTP/1.1
Host: {tenant}.b2clogin.com
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
grant_type=authorization_code&code={auth code received in previous step}
&scope=openid%20offline_access%20https%3A%2F%2F{tenant}.onmicrosoft.com%2F<client-id-uuid>%2FUser.all
&client_id={client id}&redirect_uri=localhost%253A4200%252Flogin.html%3A
after authentication the code is used for accessing various endpoints and azure functions.
In hte process we need user attributes like email, display_name, country, etc information that user had input while singing up.
Along with default attributes we have some custom attributes like team_name which is specific to our Web application use case. These attributes change over time.
For eg: person may switch team. thus we modify that in the user attribute using Graph APIs.
so in that case if attribute team_name = 'Team ABC' now changes to team_name = 'Team XYZ'
But after the attributes are changed, the attributes do not reflect the new values in the access_token / refresh_token or id_token. Is there a way we can get the refreshed values in the tokens without re authorizing the user?
currently we fetch the user attributes from the Graph APIs but its faster and more convenient if we get refreshed values in the token.
Custom policy doesn't have a mechanism publicly documented to get new access token claims in refresh token flow. So what You have observe is expected
As a somewhat workaround, we have found out that when refreshing the authentication via SSO cookie ("Web app session" in Azure B2C configuration portal), the claims are refreshed.
I think this basically amounts to "re-logging-in" but without a user-visible prompt.
We are using the msal-browser library to do SSO login automatically for us (it uses a hidden iframe for that), but I think you could also do the same by hand.
You need to call the /authorize endpoint with all the usual query parameters, and also:
prompt=none must be set
one of sid (with account-id) or login_hint (with the username) must be set
Haven't done it myself manually, so I might still be missing something, but I think these should be the major things.

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!

Liferay jsonws api: how do I get p_auth from a client?

I'm trying to develop a javascript mobile app that will use a liferay portal jsonws api. I have a username and password. If I try a request using curl with basic auth I can access the resources, but I don't get a token in return, I get a cookie with a sessionid and I have to include username and password in every request. I've no control on the portal. How do I get the p_auth token?
You can use Liferay.authToken to get p_auth from client.
You may go to browser console and type Liferay.authToken to verify that the object is available.
I've used the same object for auth purpose where I was listing down results from JSONW service call. You can save the value in a variable and set anywhere per requirements. I found this the easiest way:
var pAuth = Liferay.authToken;
console.log(pAuth);
Becareful, the parameter p_auth is used to prevent CSRF attack. You can obtain the value with this code:
String pAuth = com.liferay.portal.security.auth.AuthTokenUtil.getToken(request);
TokenUtil is a part of the liferay core, so you must create a hook because the jsp must be in liferay directory, not in a plugin or a portlet because in other classpath you dont have acces to this object.
You can get the authentication token (p_auth) by using Liferay.authToken predefined variable.

Resources