azure-ad-b2c / samples

Azure AD B2C custom policy solutions and samples.
840 stars 597 forks source link

Adding "Already have account" button to sign up page with custom policies - Azure B2c #126

Closed rdcoperving closed 4 years ago

rdcoperving commented 4 years ago

Need to show singup page first for my website and a button on signup page to redirect to singin

I'm creating custom policy to first show singup form which has "Already a user then singin " button, on click which takes user to signin form(something like default singin and singup toggle) Extensionfile:

<?xml version="1.0" encoding="utf-8" ?>
<TrustFrameworkPolicy
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" 
  PolicySchemaVersion="0.3.0.0" 
  TenantId="myid.onmicrosoft.com" 
  PolicyId="B2C_1A_Test_QA_TrustFrameworkExtensions" 
  PublicPolicyUri="http://myid.onmicrosoft.com/B2C_1A_Test_QA_TrustFrameworkExtensions">
    <BasePolicy>
        <TenantId>myid.onmicrosoft.com</TenantId>
        <PolicyId>B2C_1A_TrustFrameworkBase</PolicyId>
    </BasePolicy>
    <BuildingBlocks></BuildingBlocks>
    <ClaimsProviders>
        <ClaimsProvider>
            <DisplayName>Facebook</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="Facebook-OAUTH">
                    <Metadata>
                        <Item Key="client_id">facebook_clientid</Item>
                        <Item Key="scope">email public_profile</Item>
                        <Item Key="ClaimsEndpoint">https://graph.facebook.com/me?fields=id,first_name,last_name,name,email</Item>
                    </Metadata>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
        <ClaimsProvider>
            <DisplayName>Local Account SignIn</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="login-NonInteractive">
                    <Metadata>
                        <Item Key="client_id">cid</Item>
                        <Item Key="IdTokenAudience">id</Item>
                    </Metadata>
                    <InputClaims>
                        <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="cid" />
                        <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="id" />
                    </InputClaims>
                </TechnicalProfile>
                <TechnicalProfile Id="App_SignUpWithLogonEmail">
                    <DisplayName>Email signup</DisplayName>
                    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                    <Metadata>
                        <Item Key="IpAddressClaimReferenceId">IpAddress</Item>
                        <Item Key="ContentDefinitionReferenceId">api.localaccountsignup</Item>
                        <Item Key="language.button_continue">Create</Item>
                    </Metadata>
                    <CryptographicKeys>
                        <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
                    </CryptographicKeys>
                    <InputClaims>
                        <InputClaim ClaimTypeReferenceId="email" />
                    </InputClaims>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="objectId" />
                        <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />
                        <OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />
                        <OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
                        <OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" />
                        <OutputClaim ClaimTypeReferenceId="authenticationSource" />
                        <OutputClaim ClaimTypeReferenceId="newUser" />
                        <!-- Optional claims, to be collected from the user -->
                        <OutputClaim ClaimTypeReferenceId="displayName" Required="true" />
                        <OutputClaim ClaimTypeReferenceId="givenName" Required="true" />
                        <OutputClaim ClaimTypeReferenceId="surName"  Required="true"/>
                        <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress"  Required="true" />
                    </OutputClaims>
                    <ValidationTechnicalProfiles>
                        <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
                    </ValidationTechnicalProfiles>
                    <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
        <ClaimsProvider>
            <DisplayName>Token Issuer</DisplayName>
            <TechnicalProfiles>
                <!-- SAML Token Issuer technical profile -->
                <TechnicalProfile Id="Saml2AssertionIssuer">
                    <DisplayName>Token Issuer</DisplayName>
                    <Protocol Name="SAML2"/>
                    <OutputTokenFormat>SAML2</OutputTokenFormat>
                    <Metadata>                       
                        <Item Key="IssuerUri">https://myid.b2clogin.com/myid.onmicrosoft.com/B2C_1A_test_QA_SAML_SignUpOrSignin</Item>
                    </Metadata>
                    <CryptographicKeys>
                        <Key Id="MetadataSigning" StorageReferenceId="B2C_1A_MyQA"/>
                        <Key Id="SamlAssertionSigning" StorageReferenceId="B2C_1A_MyQA"/>
                        <Key Id="SamlMessageSigning" StorageReferenceId="B2C_1A_MyQA"/>
                    </CryptographicKeys>
                    <InputClaims/>
                    <OutputClaims/>
                    <UseTechnicalProfileForSessionManagement ReferenceId="SM-Saml-issuer"/>
                </TechnicalProfile>
                <!-- Session management technical profile for SAML based tokens -->
                <TechnicalProfile Id="SM-Saml-issuer">
                    <DisplayName>Session Management Provider</DisplayName>
                    <Protocol Name="Proprietary" Handler="Web.TPEngine.SSO.SamlSSOSessionProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
    </ClaimsProviders>
    <!--UserJourneys></UserJourneys-->
</TrustFrameworkPolicy>

SingupPolicy:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TrustFrameworkPolicy
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
  PolicySchemaVersion="0.3.0.0"
  TenantId="myid.onmicrosoft.com"
  PolicyId="B2C_1A_test_QA_SAML_SignUpOrSignin"
  PublicPolicyUri="http://myid.onmicrosoft.com/B2C_1A_test_QA_SAML_SignUpOrSignin">
    <BasePolicy>
        <TenantId>myid.onmicrosoft.com</TenantId>
        <PolicyId>B2C_1A_test_QA_TrustFrameworkExtensions</PolicyId>
    </BasePolicy>
    <UserJourneys>
        <UserJourney Id="SignUp">
            <OrchestrationSteps>
                <OrchestrationStep Order="1" Type="ClaimsExchange">
                    <ClaimsExchanges>
                        <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="App_SignUpWithLogonEmail" />
                    </ClaimsExchanges>
                </OrchestrationStep>
                <!-- This step reads any user attributes that we may not have received when in the token. -->
                <OrchestrationStep Order="2" Type="ClaimsExchange">
                    <ClaimsExchanges>
                        <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
                    </ClaimsExchanges>
                </OrchestrationStep>
                <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Saml2AssertionIssuer"/>
            </OrchestrationSteps>
        </UserJourney>
    </UserJourneys>
    <RelyingParty>
        <DefaultUserJourney ReferenceId="SignUp" />
        <TechnicalProfile Id="PolicyProfile">
            <DisplayName>PolicyProfile</DisplayName>
            <Protocol Name="SAML2"/>
            <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="displayName" />
                <OutputClaim ClaimTypeReferenceId="givenName" Required="true" />
                <OutputClaim ClaimTypeReferenceId="surname" Required="true" />
                <OutputClaim ClaimTypeReferenceId="email" Required="true" />
                <!-- <OutputClaim ClaimTypeReferenceId="identityProvider" /> -->
                <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" />
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="objectId"/>
            </OutputClaims>
            <SubjectNamingInfo ClaimType="objectId" ExcludeAsClaim="true"/>
        </TechnicalProfile>
    </RelyingParty>
</TrustFrameworkPolicy>

Something like this: User Flow

JasSuri commented 4 years ago

You must use custom HTML, add a link that redirects to your app: https://myapp.com/sign-in. This will then initialize a proper auth request through your OIDC library to the sign in page. Only the combined sign in and sign up page has a built in link to go to sign up, the sign up page does not have this capability.