Microsoft Azure SSO via SAML - NameID Format - azure

I am trying to integrate my application with Microsoft Azure SSO using SAML. Unlike the Google SSO SAML, their XML file does not contain the Name ID Format. Therefore I assume that it is "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress".
The SSO login works, but somehow the attributes return from Microsoft Azure looks weird. What I expect is the user information (e.g., first name, last name and other attributes I set in the control panel), instead, it returns something like:
[samlUserdata] => Array
(
[http://schemas.microsoft.com/identity/claims/tenantid] => Array
(
[0] => 123456-a43f-4dfd-8888-f5fa5e547790
)
[http://schemas.microsoft.com/identity/claims/objectidentifier] => Array
(
[0] => 123456-e20c-46f1-8888-204cc360d7d8
)
[http://schemas.microsoft.com/identity/claims/identityprovider] => Array
(
[0] => https://sts.windows.net/123456-a43f-4dfd-8888-f5fa5e547790/
)
[http://schemas.microsoft.com/claims/authnmethodsreferences] => Array
(
[0] => urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
)
)
What am I missing?
P.S. I am using One Login PHP library. It works with Google.

Therefore I assume that it is "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress".
I suppose a more appropriate format should be urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified, specially if you are to leave it unspecified.
What am I missing?
It seems as though your SAML2 IdP, Microsoft Azure SSO, is not correctly set up to release claims/attributes to you. I don't think this has anything to do with nameid formats; it's about the IdP configuration and its attribute release policy. You can cross check this by looking at the raw SAML2 XML response that should be passed back to your SP. If you do not find any claims/attributes in there, then the IdP is not releasing anything to you and that's something to take up with them.

The Azure AD data is correct.
In Azure AD, a lot of attributes are GUID's and that is what you are seeing.
You will note that "authnmethodsreferences" is in plain text.
If you pass given name, surname etc. they will also be in plain text.

Related

I need all users details from ADFS using c# in single outgoing claim

hi I created the custom claim for that so please check the below claim which is created by me:
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"] =] issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"), query = "(&(objectClass=user)(objectCategory=person));mail,givenName;{0}", param = c.Value);
But in this case, I got all emails in an outgoing claim (http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress ), Also get all the givenname in another outgoing claim (http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname).
Please check the below Screenshot of how I got the values of email and name right now from the adfs using code of C#.
https://learn.microsoft.com/en-us/answers/storage/attachments/137282-image.png
But I need in a single outgoing claim like email= abc#gmail.com, Givenname=abc (with any comma separate or any separator), I need both email and given name in one single outgoing claim.
I already generate this same in the Microsoft Ignite forum: https://learn.microsoft.com/en-us/answers/questions/566015/how-to-get-all-users-of-adfs-with-all-attributes-e.html
Can you please help me to get all user's details from adfs using windows account login and get all user's details?
Thanks
You can't out of the box.
That's not how claims work.
You could use a custom attribute store.
You could also combine the claims into a single type.
See this under "Combining Claim Values".

Unable to get Sign Ins for Service Principal using Microsoft Graph API

I am trying to use List SignIns API to get a list of sign-ins for my Service Principal however the API is not returning any results when I try to filter the results by Service Principal id and/or Service Principal Application Id. If I remove the filter, I am able to get the data.
Essentially I am trying to get the data shown in Azure Portal as shown in the screenshot below.
I have tried both Graph Explorer as well as Microsoft.Graph SDK (C#) and in both places I am not getting any result back.
Things I tried:
In Graph Explorer, I tried the following request URL: https://graph.microsoft.com/1.0/auditLogs/signIns?$filter=id eq 'my-service-principal-id' and that did not give any results back.
I even tried https://graph.microsoft.com/beta/auditLogs/signIns?$filter=appId eq 'my-application-id' and still no results.
I tried with both beta and 1.0 version numbers and same results.
I checked the Azure Portal network request in browser and noticed that instead of using graph.microsoft.com, it is using graph.windows.net and is sending the following request:
https://graph.windows.net/tenant-id/activities/getSummarizedServicePrincipalSignIns(aggregationWindow='1d')?$filter=(createdDateTime ge 2021-04-21T13:03:32.608Z and createdDateTime lt 2021-04-28T13:03:32.608Z and (appId eq 'my-application-id' or contains(tolower(appDisplayName), 'my-application-id')))&$top=50&$orderby=createdDateTime desc&source=kds
I also read the documentation for List SignIns API and following caught my eye:
Retrieve the Azure AD user sign-ins for your tenant. Sign-ins that are
interactive in nature (where a username/password is passed as part of
auth token) and successful federated sign-ins are currently included
in the sign-in logs.
I am not sure if what I am trying to accomplish is even possible with Graph API considering I am not getting any results back and Azure Portal is not even using Graph API to get this data.
Any insights into this will be highly appreciated.
This is possible using the 'beta' endpoint - but at this point it only seems to include 'interactive' sign-ins by default. If you add a filter on signInEventTypes it can return other types too:
So for 'User sign-ins (non-interactive)':
https://graph.microsoft.com/beta/auditLogs/signIns?$filter=signInEventTypes/any(t: t eq 'nonInteractiveUser')
For 'Service principal sign-ins':
https://graph.microsoft.com/beta/auditLogs/signIns?$filter=signInEventTypes/any(t: t eq 'servicePrincipal')
For 'Managed identity sign-ins':
https://graph.microsoft.com/beta/auditLogs/signIns?$filter=signInEventTypes/any(t: t eq 'managedIdentity')
For all sign ins (let me know if there's a more concise way!
https://graph.microsoft.com/beta/auditLogs/signIns?$filter=signInEventTypes/any(t: t eq 'interactiveUser' or t eq 'nonInteractiveUser' or t eq 'servicePrincipal' or t eq 'managedIdentity')
https://learn.microsoft.com/en-us/azure/active-directory/reports-monitoring/concept-all-sign-ins#return-log-data-with-microsoft-graph
Beta API has ServicePrincipalId and ServicePrincipalName, you can filter based on these attributes. This link lists the supported Attributes in $filter. This API supports $filter, $skiptoken and $Top.How ever do note Beta API are subjected to change.
https://learn.microsoft.com/en-us/graph/api/signin-list?view=graph-rest-beta&tabs=http#attributes-supported-by-filter-parameter
Here's a blog about graph.windows.net and graph.microsoft.com
https://developer.microsoft.com/en-us/identity/blogs/microsoft-graph-or-azure-ad-graph/

Azure Authentication Id is not stable

I am using Azure mobile app services with Xamarin Forms.
In my app, I use web social media authentication (Facebook, Twitter, Google) configured in the azure portal.
I am taking the sid gotten from CurrentClient.Id to match it with users in my Easy Tables. However, for some users, after logging in with the same account and same provider, no match is found in my database because the sid is different! I am 100% sure that it is the same account used to login before, yet I get a different sid. How is that possible? Shouldn't it remain the same with every login or what's the whole point of it then?
You are using Azure App Service Authentication for this. There is a stable ID that is available within the JWT that you pass to the service. You can easily get it from the /.auth/me endpoint (see https://learn.microsoft.com/en-us/azure/app-service/app-service-authentication-how-to#validate-tokens-from-providers )
When you GET /.auth/me with the X-ZUMO-AUTH header set to the authenticationToken returned from the login, the user.userId field will be populated with a stable ID. So, the next question is "how do I add this / compare this within the Node.js backend?" Fortunately, the HOW-TO FAQ for Node.js explicitly answers this. Short version is, use context.user.getIdentity() (an async method) to get the identity, then do something with it:
function queryContextFromUserId(context) {
return context.user.getIdentity().then((data) => {
context.query.where({ id: data.userId });
return context.execute();
});
}
function addUserIdToContext(context) {
return context.user.getIdentity().then((data) => {
context.itme.id = data.userId;
return context.execute();
});
}
table.read(queryContextFromUserId);
table.insert(addYserIdToContext);
table.update(queryContextFromUserId);
table.delete(queryContextFromUserId);
The real question here is "what is in the data block?" It's an object that contains "whatever the /.auth/me endpoint with the X-ZUMO-AUTH header produces", and that is provider dependent.
The mechanism to figure this out.
Debug your client application - when the login completes, inspect the client object for the CurrentUser and get the current token
Use Fiddler, Insomnia, or Postman to GET .../.auth/me with an X-ZUMO-AUTH header set to the current token
Repeat for each auth method you have to ensure you have the formats of each one.
You can now use these in your backend.

Email verification code in app url (deployed on azure) not finding endpoint

I have .net core identity email verification endpoint setup like this:
/api/[controller]/{userId}/{emailVerificationCode}
and I encoded it in registration endpoint with Uri. EscapeDataString (decoding with Uri. UnescapeDataString but that's irrelevant here). So when I get email and I click the link, locally I hit endpoint and can debug it, but after deploying to azure (web app resource group) I get this response:
The resource you are looking for has been removed, had its name changed,
or is temporarily unavailable.
When I shorten code to not contain any special characters (which are now encoded so they are for example %2F, %3D etc) endpoint is hit (but ofc token is invalid).
Any idea what could be the case?
The code that is generated is Base64 encoded, and certain characters in Base64 are not allowed in the path segment of a URL by default, for security reasons, even when URL-encoded. While it's possible to change that, you should not, as the security concerns are valid, and you don't want to expose your app to exploits.
Instead, you can simply let the code be part of the query string. The same vulnerabilities do not exist for the query string portion of a URL, and the characters will be allowed there. Alternatively, you can use a different type of code. The token providers used by Identity for things like email confirmation and password resets can be customized.
Identity includes other token providers for the purposes of two-factor auth that you can switch out with, if you like. These use TOTP-based tokens (the 6-7 digit numbers you see all the time with 2FA). Or, you can create your own custom provider and handle it however you like. To change providers, you simply configure the Tokens member when setting up Identity:
services.AddIdentity<ApplicationUser, IdentityRole>(o =>
{
// other options here like password reqs, etc.
o.Tokens.ChangeEmailTokenProvider = TokenOptions.DefaultEmailProvider;
o.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
o.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
}
The above will cause those three scenarios to generate tokens via EmailTokenProvider, which is one of the TOTP-based providers builtin.
If you want to use a custom provider, you simply create a class that implements IUserTwoFactorTokenProvider<TUser> and register that:
services.AddIdentity<ApplicationUser, IdentityRole>(o =>
{
...
})
.AddTokenProvider<MyCustomTokenProvider<ApplicationUser>>("MyTokenProviderName");
The string you use as the "name" is what you would use to assign it as a token provider in the previous code above, i.e.:
o.Tokens.PasswordResetTokenProvider = "MyTokenProviderName";

SAML bindings for SSO for SimpleSAMLphp SP with PingFederate IdP

I have a PingFederate IdP set up and I want to enable SSO to my SimpleSAMLphp based SP. The PingFederate configuration requires SAML requests to be sent with POST bindings, as well as the LogoutRequest as a POST request. SimpleSAML sends SAML requests to the SignOnService in default HTTP-Redirect binding. I tried changing the binding of the idp in the saml20-idp-remote.php in the following way:
'SingleSignOnService' => array(
0 => array(
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
'Location' => 'https://myidp.com'
),
),
When I try to test the authentication, after selecting the IdP, I get the following error:
Exception during login:
Exception: saml20-idp-remote/'stagingsp'['SingleSignOnService']:Could not find a supported SingleSignOnService endpoint.
Am I not setting the correct binding, or am I doing it in an incorrect way? Is some configuration required in the SP metadata?
Did you exchange metadata between parties? This is meant to work as two-way communication. You have to exchange metadata (i.e. as .xml files) between IdP and SP.
Generally it should look like this:
- Generate metadata file (in PingFederate/IdP), and send it to SP.
- SP registers that metadata file
- SP generates own metadata file, and sends it to IdP
- IdP regeisters metadata from SP
This way both parties know about each other, know each other SingleSignOn and SingleLogOut URLs

Resources