Handling name change using Google / GSuite as SAML identity provider - single-sign-on

I have recently integrated with G Suite to use it as a SAML 2.0 IdP for my application. When configuring the SAML app through the G Suite control panel you are only able to map some basic employee attributes like First Name, Last Name and Primary Email Address.
Previously our application has been used with ADFS which is also configured to send an immutable ID. The intention of this is if someone gets married or otherwise changes their name, their email address will likely also change. By matching on the immutable ID we are able to update our record on our application with the new details.
However, if someone was to change their email + name in Google we are unable to determine that this may be an old account by a different name.
I've noted that you can add custom attributes to Users and can probably map these through but we wouldn't want to impose this on consumers of our SaaS. I see that there is an Employee Id attribute but this doesn't appear to be selectable on the SAML mapping screen.

Related

Keycloak: mapping user information from external IDP. How do I know attribute names?

I have 2 Keycloak instances:
KC1 which is the main Keycloak for my app
KC2 which acts as an IDP (linked to KC1 via SAML protocol)
I'm trying to retrieve users info (email, name and roles, mainly) in KC1 whenever a SSO user (from KC2) connects to my app. As far as I understand this should be done via IDP mappers.
I tried creating multiple ones with the "Attribute Importer" type with no success. The main problem is that attribute name fields are just textboxes. I don't know where to look to get the correct value I should enter here. For instance for email I tried multiple things like "email", "emailAddress", "mail", etc.. (with all possible cases, i.e. all uppercase, all lowercase, camelcase, etc.) but this is just guess work.
Is there a table somewhere telling what we should enter here? Or at least some way to see what is being sent in the claims (everything is very auto-magic so it's hard to know what's going on under the hood).
The documentation ( https://www.keycloak.org/docs/latest/server_admin/index.html#_mappers ) mentions that you can put the log level to debug to see the claims. Couldn't see them personally, so not sure about that.
Edit : found the problem for basic info (I had to create client scopes with the correct protocol, in my case SAML, and then bind it in the client on the KC2 side. Then use the SAML attribute name defined in the client scope mapper).
However, I still struggle for the roles. Do I have to create them on the KC1 side as well?
Edit 2 : Solved. For future reference, the roles can be found in the access token (not the ID token like basic user info), but they have to be mapped in KC1 to be visible there.
However, I still struggle for the roles. Do I have to create them on
the KC1 side as well?
You can't simply import the roles from KC2 directly to KC1. Instead, you have to create the roles that you want in KC1, and in the appropriate IDP configuration section (of KC1) create a External Role to Role Mapper:
Where you map the role that the user has on the external IDP (i.e., KC2) to the one that the user should have in the KC1. Do that for every role that you want to map.
For SAML IdP integrations you can try the same idea but using the Advance Attribute to Role mapper:

Single Sign On: Is it necessary/preferred to keep a table of linked accounts?

I build websites and authentication/account management systems. In our database, we have an user table that (conceptually) looks
TABLE: USER
id | name | email_address (unique)
====|===========|=========================
88 | Ben Ghazi | bgazi#gmail.com
We wanted to allow Single-Sign-On from Google. So we added a Database table that (conceptually) looks like this:
TABLE: SSO_LINK
id | our_account_id | sso_provider_name | sso_provider_account_id
====|================|===================|=========================
99 | 88 | GOOGLE | xyz983
The row in the above table indicates that if Google account #xyz983 ever tries to login, we should log them in as our user #88.
I'm now implementing Google SSO on a new project from scratch. I'm designing how it will work. I am realizing that perhaps this SSO_LINK table was completely unnecessary. Instead of maintaining a list of linked accounts and checking against it, we could just match the email address that Google provides us. If that email matches any of our users, then simply log that user in. That should work. Right?
However, I suspect that most serious implementation of SSO maintain the SSO_LINK table. What is best practice in this case and why?
Well, it depends.
In a simple world , you must take the token part as a successfull user authentication and check if the email is ok, then, you can proceed further and logged in your user.
In an enhanced and secured way, few tips :
You can check the data around the connection if it smells logical about that user :
in the middle of the night, we usually sleep
in this is a new device/computer/cellphone inside a country
reputed for bad users or an ip of any monkey private or public WLAN
used as open proxies or anything like that.
You can use any verifier service provider is a good way yo authenticate your users, but there is another ways : LDAP protocol with OpenLDAP (Free, Open Source Software) or Active Directory (if you are using a Windows Server).
Please, I hope your are hashing or crypting with strong algorithms user passwords and use a smart secured system of your own to not expose privacy concerns. If you are doing that well, you're better than some very big IT companies in USA/Europe. Time is money and user concerns are not their concerns until the RGPD has raised inside the law, so we are working a lot about that since years, and we will continue.
It is recommended to have an accounts and linked_accounts table as you suggest. But how account linking works will vary depending on the provider and the customer use case.
EXAMPLES
At Curity we support many types of authenticator:
Some are standards based identity providers, OpenID Connect or SAML
Some have vendor specific behavior
Some are not IDPs but need to map an identifier, eg a WebAuthn key, to a user account
TECHNIQUES
Sometimes you can deterministically match based on a field such as email, if you are sure that they are the same in both cases. In such cases you can run scripted logic to link accounts, as in this Sign in with Apple tutorial, which matches by email.
Note that there are peculiarities to how this provider works, and not all providers will give you an email. Access to Personally Identifiable Information (PII) is a hot topic these days.
In order for account linking to be reliable, you will sometimes need to involve the user, eg to prove their identity via passwords when they first sign in using a different method, so that you can link the provider specific ID to the user account.
SUMMARY
Account linking, like many other areas of Identity and Access Management, is a toolbox, rather than an out of the box solution. Extensibility features, including custom fields, are often needed. One step at a time though - start by getting the data structure broadly correct and then adding support for one provider at a time.
As a final point, storing the provider's subject claim is more stable than matching on email, since it copes better with future scenarios where the email changes, eg if the user marries.

Capture IDP User attributes in SAP cloud foundry app via SDK UserAccesor API

I wanted to capture user attributes coming from SAP IDP(Identity & Authentication tenant service like department,salutation ,company etc ,via UserAccessor SDK api,but although those attributes are set and has value in IDP user and all the integration with IDP and sub account is in place post authentication ,user attributes object is empty ,i am only able to retrieve specific attributes like first names ,last name,email address ,user groups etc via JWT and UserAccessor api ,but no luck with other attributes ,in IDP i have mentioned these attributes as well under assertion attributes in SAP Identity authentication tenant .
Please guide and help in this matter .
Thanks Siddharth
Update: As we have now identified the problem, I will update my answer to reflect that. The original answer below is outdated:
Okay so the problem is that you haven't mapped any additional user attributes from your Identity Provider (IdP) to your JWT. As far as I'm aware there are three things you will need to do:
You need to create attributes in your xs-security.json (the file you used to configure your XSUAA service instance). This documentation should explain how to do that.
You need to configure which attributes are exposed by your IdP (in your case the SAP Identity & Authentication service. This documentation looks like a good place to start looking).
You need to map the attributes exposed by your IdP to the attributes defined in your xs-security.json. You will probably need to reconfigure (i.e. delete, recreate and rebind) your XSUAA service instance with the updated config, before you can do this step. Then, navigate to your application in the Cloud Platform Cockpit, from the left toolbar click "Security > Roles" and create your mapping.
Let me know if this works for you!
Original Answer:
As far as I'm aware the default IdP does not support SAML. Without SAML, I'm not sure whether you can propagate any attributes from your IdP into the JWT.
Please also check out this discussion for more information.

Pass through incoming claims

Is it possible to send a SAML claim to ADFS and then have ADFS use values from that incoming claim to generate its own?
Basically, we need to send a) information about the user (fairly straightforward), and b) information about the target (the question at hand). The target is chosen by the user at time of SSO.
I've had it suggested to me to store the dynamic data in a database and then pull it in ADFS, but that runs the risk of creating issues if a user tries to open two targets in two windows at the same time.
EDIT: When a user SSOs into the target application, they will be taken to a screen that shows information about a specific item. We need to provide which item the user will need to see - and that will be selected by the user in the source application.
Essentially, user goes to Site A, clicks on Item 2, which SSOs them into Site B with Item 2 in context. If the user selects Item 7 instead, they SSO into Site B with Item 7 in context. This information isn't tied to the user because the user can access any of the items, but it needs to be provided in the SAML token to Site B.
First of all "maweeras" is very authorative. You can trust has answer/comment to be correct :-).
As maweeras said: To get it into the SAML Token you have to use "claims rules". The trouble is getting it into the input set of the claimrules. That can either be something from: a. specific to the user (you said you don't want that, multiple windows could be fixed, but it is awful indeed), b. another SAML Token Issuer, or c. from some very specific HTTP headers.
As you specify it, only option c. remains. Already being tough, I must warn you to be extremely cautious because all of them already may have specific consequences. Some people would say that you are abusing them. Shooting yourself in the foot.
Not an answer, but a tip. You do not specify why you want it in the SAML token. If possible I would try to put it in a query parameter of a redirect from app A to app B. That will be preserved in the wctx (if authentications kicks in). You may already have to add several other things there to make sure the user will get the correct SSO (IdP, authnlevel etc.). If you need it signed, then sign it before you stuff it in the redirect?

Expiration of accountId in Rest API

Before first sending signing request I should get a accountId.
So is there any expiration time for this accountID? Can I save it and use it any time with unlimited time if there is no changes in credential or/and other api key and so on?
I can't find information about strategy for accountId in rest api documentation.
Thank you
ref:
https://www.docusign.com/developer-center/recipes/request-a-signature-via-email
https://www.docusign.com/p/RESTAPIGuide/RESTAPIGuide.htm#REST API References/Login.htm
The account ID is part of your developer account. You can find it when you login by clicking on the little down arrow in the top right corner next to your avatar. It will display your name the name of the company then a number. That is the account ID.
The account ID does not expire. The way DocuSign manages access to the API's is through an Integrator key. For information about the Integrator key please refer to the following link. https://www.docusign.com/developer-center/api-overview
So from a broad overview you would want to break up the different business processes by business group and have a different Integrator Key for each unit. That way if someone builds bad code or something strange happens and they turn of one of the Integrator keys it does not affect every group in the company.
There is no expiration of your accountId however note that it will change between environments - i.e. when you move from demo to production. Therefore the best practice is to write your integration such that, for a given user, it makes the login call then uses the accountId returned from that in subsequent API requests. By writing it this way you also make the go live process easier since you wouldn't have to remember to go back and change any hard-coded values in your app.
Note that when you are in production, your organization (or your customers' organizations) may well have more than one account id. And that individuals within the organization may well have access to more than one account.
Example: a company has different rules for electronic signature requests that are sent from the legal department and all the other corporate departments. Depending on the differences in the rules, the best DocuSign configuration may be to establish two different accounts, one for legal and one for everybody else. And some people may have access to both accounts.
Bottom line: when your API integration app logs in, it should enable either the human or your config file to specify the account that should be used (if the user has access to more than one account.) While all users have a "default account," it is not always the case that the default is the one that should be used by your integration.