So I created an enterprise application and have it configured for SAML based SSO. As I understand it, I've configured it so that the Unique User Identifier (Name ID) should be set the the email of the user within Azure.
When I attempted to login to test or use my new application through the portal, I can see that the NameID value in the response is actually set to a random string of characters (zReN4-W7ufefDDEh4pJ19K7pcMV84O5RKHSeOQ6wArU) which I assume unique identifies my user. I've tries altering the source attribute of the Name ID as well as the name identifer format but it always comes back as the exact same string in the response.
The application I'm trying to log into requires that the name ID be set to the user's email address and I don't understand why it's not being shown that way in the response. Any ideas why this is happening?
The NameID value is a targeted identifier that is directed only to the service provider that is the audience for the token. It is persistent - it can be revoked, but is never reassigned. It is also opaque, in that it does not reveal anything about the user and cannot be used as an identifier for attribute queries.
Generally, if the user does not have value in mail attribute, then Azure AD would send persistent format for Name ID and set random value in it.
For more information on the SAML Protocol can go through this article and similar question
Related
Hoping someone can shed some light on the following matter;
I got an Angular & .Net core Web API application that uses Azure B2C to authenticate users.
User accounts are created by the users themselves via the signin/signup custom policy or administrator can create accounts via the app using the Graph API.
Due to the requirements, the app uses usernames (as opposed to email addresses) to log into the application. So far I've managed to get everything working except for the following scenario:
When an account is created via the Graph API, the owner of that account cannot reset the account's password. The error is "An account could not be found for the provided user ID".
This isn't the case for accounts that get created via the custom signup policy so I did some comparison and found that for those account that get created via the Graph API, the Email is missing (which can be found under User -> Authentication Methods). I looked at populating that field, but it appears the "Mail" attribute is 'read only' (not sure if that's the right attribute anyway).
At the moment I'm having to manually set the email via Azure so those account's passwords can be reset by their owner if necessary. This is obviously not ideal and wanted to see if there is anyone that might have gotten around this issue, or a least get confirmation that this is indeed a limitation of the Graph API.
Thanks in advance for your help
So I managed to get this working using the approach outlined by Jas Suri. These are the steps that I went through
Created a custom attribute in my B2C tenant to hold the account email address
Included the custom attribute claim type (extension_emailAddress) as well as the strongAuthenticationEmailAddress in the TrustFrameworkBase.xml
Updated my apps's custom policies to include the technical profile for local account discovery. I basically just copied the necessary bits and pieces from here
Updated the local account discovery to perform the comparison against the extenstion_emailAddres instead of strongAuthenticationEmailAddress.
Added an extra step to the Sign up user journey so that the value in strongAuthenticationEmailAddress is copied to extension_emailAddress
Updated my Web API / Graph API "create user" function so that it sets the extension_appidguid_emailAddress
That's it. Now it doesn't matter how the account gets created, the email address will be stored in the extension attribute and the password reset will be able to find the account using that attribute.
happy to provide more details if anyone comes across this.
The problem is as you’ve identified, the Sign Up policy uses the strongAuthEmail attribute to store the verified email for a username based account. The Password reset policy will use this to verify the user owns the username. When creating the user with graph api, you can’t populate this field, it’s not exposed. The only option is to use a custom policy which stores this secure email in an extension attribute, and your graph api created users can then also target the same attribute to allow the stars to align.
Mail attribute is not the same as the Email under Authentication Methods, and currently there is no such graph api to set the Email value under Authentication Methods.
By the way, there is no need to create Azure AD B2C user for a user as users can sign up themselves.
I have 2 questions:
As per the client requirement, while Sign Up using Azure B2C UI flow (signInNames – Type is userName), user should get suggestions for username once they entered some value in username field(on the basis of existing usernames in B2C AD).
How we can achieve this functionality?
Note: I am using B2C built in Sign Up policy.
Other requirement is that multiple user can have same Email Id (as we are already using signInNames – Type : userName ).
So once user enters the email Id and if that email Id is already associated with other username(s), we need to populate the list of usernames associated with the email. How we can achieve this functionality?
Any help is very much appreciated, I actually got stuck so please offer any suggestion.
You mean the "email address" property, right, not the actual email messages? If so, you should be able to use the /users endpoint: https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/user_get
What is the resource you want to access via the access token ? If resource is https://graph.windows.net/,you could use Azure AD Graph API to get the email information of the signed-in user :
GET https://graph.windows.net/me?api-version=1.6
Authorization: Bearer yourAccessToken
If resource is https://graph.microsoft.com/,you could use Microsoft Graph API to get the email information of the signed-in user:
Get https://graph.microsoft.com/v1.0/me
Authorization: Bearer yourAccessToken
In response you could check UserPrincipalName claim value which is an email address that can receive emails.
For the username suggestion part, if you are talking about when you fill out the username form field and the chrome/IE box pops up above, that is cached at the client and you can't do that. If you are talking about the user tries to register with a username that is already taken and you want to give them suggestions you may, but I doubt it, be able to do it in a custom policy. More than likely, however, you would need to use a custom web application to do that as that is more of an advanced sign in journey.
The second part of your requirements would also need to be fulfilled within a custom web application as well, you can retrieve and access AD items within the custom user journey's but again this is more of an advanced sign in journey.
I have a webapi that is published as a service on Azure. It uses the integrated AD security.
In my Controller, I can get access to the ClaimsPrincipal via the User property. Which of ClaimsPrincipal's properties can be used to uniquely identify the user so that I can use that value to search a SQL table for that users data or store data to a SQL table and include the users unique identification? The identity property has a Name but I was thinking of a more unique identifier.
Or is there a different intended strategy to do this?
AFAIK, you can use either, the upn or the oid (Object Identifier) claim.
The UPN is typically your login name e. g. yourname#yourtenant.onmicrosoft.com whereas the oid is the ObjectId of that user.
Note: If you delete and recreate a user with the same email, the upn will be the same whereas the oid will change.
We have a multi-clients (internally identified as "corporates"), web-based software, in which we have implemented SSO via SAML 2.0. Each client is a Corporate, and each Corporate has its own users.
At the moment, the users are identified by the NameId property of the SAML response (matching the Username field in our application), and the value of the Issuer field allows us to know which Corporate the user is from.
Now, one of our big client has white-labelled the solution, and is using it in-house, with a single Identity Provider for all of its own clients. This mean there is a unique Issuer value for all SAML messages, and we can no longer rely on that to identify the user's Corporate. Fortunately, their SAML message gives all the information we need, formatted this way:
The NameId value is formatted as "corporate:username"
There is a specific "companyId" Attribute, with value "corporate"
There is a specific "operatorId" Attribute, with value "username"
I guess that identifying the Corporate is then straightforward : we need to check the value of the custom "companyId Attribute and compare that with the Corporate name. Easy.
But what about the username? Is it safe, or does it follow best practices, to check the "operatorId" Attribute instead of the NameID property ? Or should we in all cases always rely on NameId, and therefore put a custom parsing logic in place to extract the corporate and username from the NameId ?
How would you do that? I'm not able to find a similar case.
Thanks!
It doesn't seem to follow your company best practices :), but as soon you have validated the request is all up you and what you agree with your customer. It will be thought harder to maintain because it is an exception.
We're using an application that authenticates using Azure ACS with a Google ID. But the nameidentifier that we get from Google keeps changing. It appears that this is based on the IP address which fluctuates when using Azure. So I'd like to have the output claim type be something other than the nameidentifier.
However if I change the output claim type (in the Rule Group panel) for the input nameidentifier to emailaddress we get a server error when trying to authenticate: Sequence contains more than one element
Is there a trick to setting up the rule groups for Google so you get back a token that doesn't change all the time?
As you already suspected, the ID is unique per realm/domain, but this should be based on the ACS namespace, not the URL of your application.
Now, using emailaddress is much safer in case you might need to use a different ACS namespace or if you no longer want to use ACS at all. In order to map the emailaddress claim to the namidentifier (output claim), you'll need to delete the actual nameidentifier first: