AzureAD B2C - SAML LogoutRequest are not signed - azure-ad-b2c

We have a custom policy that federates to an ADFS IDP (using SAML). Login works fine. But logout is failing or ignored.
ADFS is logging an error in it's eventlog:
MSIS7084: SAML logout request and logout response messages must be signed when using SAML HTTP Redirect or HTTP POST binding.
Viewing the GET request built by B2C, it is indeed missing a Signature. It not a query parameter nor in the saml body.
Signatures are being sent for the login requests (as query parameters).
Here's the metadata settings for the Claims Provider:
<Metadata>
<Item Key="IssuerUri">https://ourissuer</Item>
<Item Key="PartnerEntity">metadata removed for brevity</Item>
<Item Key="XmlSignatureAlgorithm">Sha256</Item>
<Item Key="ResponsesSigned">true</Item>
<Item Key="WantsSignedRequests">true</Item>
<Item Key="WantsSignedAssertions">true</Item>
<Item Key="WantsEncryptedAssertions">false</Item>
<Item Key="IdpInitiatedProfileEnabled">true</Item>
<Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
<Item Key="SingleLogoutEnabled">true</Item>
</Metadata>
What could be wrong?

In order to validate the application , certification should be specified in the ADFS application properties section.
I tried below steps to resolve the reported issue.
Please follow below steps:
Open ADFS
Expand servers
Select the required application
Right click on the application to select properties
Choose signature category and verify If the certificate is trusted and make sure it is not expired.
Your SignAuthnRequest must also be set to true
<PartnerIdentityProvider Name="https://ExampleIdentityProvider" SignAuthnRequest="true"

Related

Is there a way to integrate generic custom identity provider like NHS Login with Azure ADB2C which provide private key to fetch access token

We are trying to integrate custom identity provider like NHS Login with Azure ADB2C which provides private key to fetch access token. When we try to login using credentials, we get the error saying "We encountered an error connecting to the identity provider. Please try again later." Is there any source or starting point which we can refer where user has integrated generic custom identity provider like NHS Login with Azure ADB2C successfully and able to fetch access token using private key as token endpoint auth method Azure ADB2C tech profile
(new account so can't comment on the above - but i think the below is useful to this thread).
Jas Suri, Could you possibly expand on the last sentence please, as from what I've experienced, its a requirement?
It is best to use the OAuth2 technical profile to get the most out of
NHS Login platform
I have now got NHS Login working with Azure B2C, but I had initially had the claims tech profile setup as OpenIdConnect, but was getting validation errors:
(IDX10618:
AsymmetricSecurityKey.GetHashAlgorithmForSignature( 'RS512' ) threw an
exception.\nAsymmetricSecurityKey:
'System.IdentityModel.Tokens.RsaSecurityKey'\nSignatureAlgorithm:
'RS512', check to make sure the SignatureAlgorithm is supported)
We have integrated NHS Login with AAD B2C.
The document linked shows two metadata items that make us compatible with NHS Login:
token_endpoint_auth_method: Specifies how Azure AD B2C sends the authentication header to the token endpoint. Possible values: client_secret_post (default), and client_secret_basic (public preview), private_key_jwt (public preview).
token_signing_algorithm: Specifies the signing algorithm to use when token_endpoint_auth_method is set to private_key_jwt. Possible values: RS256 (default) or RS512.
The technical profile will look like this:
<TechnicalProfile Id="NHS-Login-OAUTH2">
<DisplayName>NHS-Login-OAUTH2</DisplayName>
<Description>Login with your NHS account</Description>
<Protocol Name="OAuth2" />
<Metadata>
<Item Key="authorization_endpoint">https://auth.sandpit.signin.nhs.uk/authorize</Item>
<Item Key="AccessTokenEndpoint">https://auth.sandpit.signin.nhs.uk/token</Item>
<Item Key="ClaimsEndpoint">https://auth.sandpit.signin.nhs.uk/userinfo</Item>
<Item Key="client_id">yourClientIdFromNHS</Item>
<Item Key="scope">openid email profile phone profile_extended gp_integration_credentials</Item>
<Item Key="response_mode">form_post</Item>
<Item Key="BearerTokenTransmissionMethod">AuthorizationHeader</Item>
<Item Key="response_types">code</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="UsePolicyInRedirectUri">false</Item>
<Item Key="token_endpoint_auth_method">private_key_jwt</Item>
<Item Key="token_signing_algorithm">RS512</Item>
</Metadata>
<CryptographicKeys>
<Key Id="assertion_signing_key" StorageReferenceId="B2C_1A_NhsSandpit" />
</CryptographicKeys>
..snip..
NHS Login requires private_key_jwt and RS512. This will use a client assertion to authenticate to the NHS Login /token endpoint.
Take the PEM file which NHS login docs state to generate, and convert it to PFX. Upload that PFX into B2C policy keys. This is referenced in the CryptographicKeys node of the technical profile.
It is best to use the OAuth2 technical profile to get the most out of NHS Login platform.

Azure B2C: Issues with blocked iframe during signout on Federated Identity Provider

We are experiencing issues completing the sign out flow using Azure B2C with custom policies.
We have created a sample Enterprise Application in our Azure AD and set it up as a federated identity provider in our custom policies in the B2C environment, besides the sign out issue everything works as expected.
The sign out flow.
The first step works well and the session is cleared on the B2C identity provider.
We can see in the network tab that the correct endpoint is called on the federated identity provider, but this request is blocked (net::ERR_BLOCKED_BY_RESPONSE) I then checked the response header and found X-Frame-Options: DENY. I am unsure but to me it looks like the request is made from an iframe but is blocked.
The user is redirected back to the app's post_logout_redirect_url
A workaround is to put the end_session_endpoint as the post_logout_redirect_url:
https://domain.b2clogin.com/domain.onmicrosoft.com/signin/oauth2/v2.0/logout?post_logout_redirect_uri=https://login.microsoftonline.com/guid/oauth2/v2.0/logout?post_logout_redirect_url=https://app.com/callback.html
and that works fine.
Here is the technical profile
<TechnicalProfile Id="Company-OpenIdConnect">
<DisplayName>Company</DisplayName>
<Description>Company</Description>
<Protocol Name="OpenIdConnect"/>
<Metadata>
<Item Key="METADATA">https://login.microsoftonline.com/tenantID/v2.0/.well-known/openid-configuration</Item>
<Item Key="client_id">guid</Item>
<Item Key="response_types">code</Item>
<Item Key="scope">openid profile</Item>
<Item Key="response_mode">form_post</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="UsePolicyInRedirectUri">false</Item>
</Metadata>
...
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin"/>
</TechnicalProfile>
This is expected, most IdPs will not allow to be rendered in an iframe for login or logout. Azure AD does not allow to be rendered in an iframe either, hence the logout does not complete.
Your workaround causes a full page redirect, which will work, but the user experience maybe jarring.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/session-behavior?pivots=b2c-custom-policy#sign-out
The sign-out clears the user's single sign-on state with Azure AD B2C, but it might not sign the user out of their social identity provider session.

Azure AD ADFS gving Error "AADB2C90168: The HTTP-Redirect request does not contain the required parameter 'Signature' for a signed request."

I am trying to use the following article to get ADFS working with Azure AD B2C in the start almost 3 weeks ago it worked and now I am getting this error.
AzureAD B2C ADFS Configuration
The Error I get after providing the credentials into ADFS.
AADB2C90168: The HTTP-Redirect request does not contain the required parameter 'Signature' for a signed request.
I removed my Custom policy and took on a vanilla policy from starter pack and configured ADFS but had the same result.
There is no guidance on AADB2C90168 on the Internet on this error.
For info
The ADFS is using a Public certificate and AzureAD B2C is using a self-signed certificate (as described in Pre-Requisites section).
Any help will be appreciated.
Turning off response signature checking weakens security, so probably not a good idea.
Azure B2C is expecting both the message and the assertion to be signed. By default, ADFS only signs the Assertion.
Run this on your ADFS Server:
Set-AdfsRelyingPartyTrust -TargetName <RP Name> -SamlResponseSignature MessageAndAssertion
In your technical profile for ADFS, add the following key <Item Key="ResponsesSigned">false</Item> to the metadata to see if this corrects your issue or not?
<TechnicalProfiles>
<TechnicalProfile Id="MyADFS-SAML2">
<DisplayName>MyADFS</DisplayName>
<Description>Login with your MyADFS account</Description>
<Protocol Name="SAML2"/>
<Metadata>
<Item Key="RequestsSigned">false</Item>
<Item Key="ResponsesSigned">false</Item>
<Item Key="WantsEncryptedAssertions">false</Item>
<Item Key="PartnerEntity">https://sts.myadfs.com/FederationMetadata/2007-06/FederationMetadata.xml</Item>
</Metadata>
...
</TechnicalProfile>
</TechnicalProfiles>

MS Azure AD B2C as SAML IDP not working

Background
I have an application in which users signup/sign through AD B2C. In the application, there is a link which will redirect to another application which works on SAML so want MS Azure to work as IDP and sends SAML to the third application.
We achieved this in AAD (not AD B2C) through the non-gallery application but getting problems in AD B2C.
We followed this document https://github.com/Azure-Samples/active-directory-b2c-advanced-policies/blob/master/Walkthroughs/RP-SAML.md
but when we hit the URL then it says "AADB2C: An exception has occured".
Base file - https://www.dropbox.com/s/ro6arbs57c43el2/base.xml?dl=0
Extension file - https://www.dropbox.com/s/uqojtk432b3wny1/base_Extensions.xml?dl=0
SignInSaml file - https://www.dropbox.com/s/i950s4bwwagry5k/signinsaml.xml?dl=0
The best thing you could do is work with OIDC first and confirm the policy is working and then overwrite the step where you issue a JWT token with SAML
When working with SAML i have this format
Base
Base-extensions (if you want it - i tend not to)
policy-OIDC (This extends base)
policy-SAML (This extends OIDC)
In the policy SAML I then override my user journey orchestration step that calls the JWTIssuer and then call my SAML token creator
The reason for this approach is B2C has been designed to work with OIDC , you can confirm that the journey is working as expected in OIDC and then switch to your SAML
Id also use the journey recorder, I find the older B2C journey recorder you get better than app insights but both track the same data
After checking my SAML in the office your missing some META data to tell SAML how to behave in your policy
<Metadata>
<Item Key="IdpInitiatedProfileEnabled">true</Item>
<Item Key="RequestsSigned">false</Item>
<Item Key="WantsSignedResponses">true</Item>
<Item Key="ResponsesSigned">true</Item>
<Item Key="AssertionsEncrypted">false</Item>
<Item Key="WantsEncryptedAssertions">false</Item>
<Item Key="PartnerEntity">https://my-calling-application/authservices</Item>
</Metadata>
<SubjectNamingInfo ClaimType="UserId" />
Your SubjectNamingInfo will also need to be
http://schemas.microsoft.com/identity/claims/userprincipalname
as this is the SAAML name you defined in your base policy

Increase refresh token lifetime in B2C custom policy

I am able to retrieve refresh tokens for my custom B2C policies but would like to increase the token lifetime to the max limit or set the sliding window lifetime to No Expiry.
This was able to be done via the Azure Portal B2C settings for Basic policies but is not available in the portal for custom policies.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-token-session-sso#token-lifetimes-configuration
How can I configure this in my policies?
Check out this article.
Specifically add the following in your RP technical profile.
<Item Key="token_lifetime_secs">3600</Item>
Can look like this (copied from docs)
<ClaimsProviders>
<ClaimsProvider>
<DisplayName>Token Issuer</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="JwtIssuer">
<Metadata>
<Item Key="token_lifetime_secs">3600</Item>
<Item Key="id_token_lifetime_secs">3600</Item>
<Item Key="refresh_token_lifetime_secs">1209600</Item>
<Item Key="rolling_refresh_token_lifetime_secs">7776000</Item>
<Item Key="IssuanceClaimPattern">AuthorityAndTenantGuid</Item>
<Item Key="AuthenticationContextReferenceClaimPattern">None</Item>
</Metadata>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
</ClaimsProviders>
What Parakh said is correct but please take note of the banner on the page that he linked to which says the following about SPA apps with PKCE:
Note
Single-page applications using the authorization code flow with PKCE always have a refresh token lifetime of 24 hours while mobile apps, desktop apps, and web apps do not experience this limitation. Learn more about the security implications of refresh tokens in the browser.
That means that settings such as the following may not be respected for those apps:
refresh_token_lifetime_secs
rolling_refresh_token_lifetime_secs
allow_infinite_rolling_refresh_token
This last one is never respected for SPA w/ PKCE

Resources