Giter VIP home page Giter VIP logo

user-migration's People

Contributors

altenstedt avatar constantlb avatar felickz avatar jassuri avatar subbuquest avatar whippsp avatar yoelhor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

user-migration's Issues

How to pass logged in "useranme" to API or any custome attribute?

Hi All

Please refer the following screen shot:-

image

please refer the highligted section with red band.

Our requirment is we need to pass either logged in user name or a custom attribute. How the same can be done?
Any inputs would be helpful. I am reading the documentation also.

Cannot Register an requiresMigration Attribute in seamless-account-migration

Getting the following error when running part 2 of the script. ...

Invoke-WebRequest : {"odata.error":{"code":"Request_BadRequest","message":{"lang":"en","value":"Updates to converged applications are not
allowed in this version."},"requestId":"d5c452eb-8555-4cdb-827a-e30d1b2e7326","date":"2020-06-17T05:19:11"}}
At line:34 char:11

  • $result = Invoke-WebRequest -Headers $authHeader -Uri $url -Method Po ...
  •       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    • FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
      ConvertFrom-Json : Cannot bind argument to parameter 'InputObject' because it is null.
      At line:37 char:20
  • ($result.Content | Convertfrom-Json).name
  •                ~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidData: (:) [ConvertFrom-Json], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ConvertFromJsonCommand

Invoke-WebRequest : {"odata.error":{"code":"Request_BadRequest","message":{"lang":"en","value":"The following extension properties are not
available: extension_29f3a41ad6bc4e77bb65d4d4ff5a3947_requiresMigration."},"requestId":"4d66bd5a-fff5-449f-9136-1534b7764f5c","date":"2020-06-1
7T05:19:12"}}
At line:87 char:1

  • Invoke-WebRequest -Headers $authHeader -Uri $url -Method Post -Body $ ...
  •   + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
      + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
    
    

The Script

#Part 2 - Register the extension attribute named "requiresMigration" into Azure AD B2C
#ObjectID of the B2CUserMigration App Registration
$AppObjectID = ""

#Set the endpoint to register extension attributes
$url = "https://graph.windows.net/$tenant/applications/$AppObjectID/extensionProperties?api-version=1.6"

#Define the extension attribute
$body = @"
{
"name": "requiresMigration",
"dataType": "Boolean",
"targetObjects": ["User"]
}
"@

#Generate the authentication header and make the request
$authHeader = @{"Authorization"= $oauth.access_token;"Content-Type"="application/json";"ContentLength"=$body.length }
$result = Invoke-WebRequest -Headers $authHeader -Uri $url -Method Post -Body $body

#Print the full attribute Name
($result.Content | Convertfrom-Json).name

ROPC with User Migration API issue

Related to #14; hoping @JasSuri can help out here...

Are there policy samples available for the ROPC flow with user migration included?

I'm working on one, but when I start my steps with the directory read for the migration status I get a "Method or operation not implemented" exception through App Insights before the first step even executes. When I change the order and do OAUTH first, my lookup succeeds as the second step, but obviously that doesn't work for actually migrating the user.

Here is the exception I get when leading with the directory read:

{
"Kind": "FatalException",
"Content": {
"Time": "3:18 PM",
"Exception": {
"Kind": "Handled",
"HResult": "80004001",
"Message": "The method or operation is not implemented.",
"Data": {}
}
}
}

Missing Base file

In in documentation instructions, the first file to upload is SeamlessMigration_TrustFrameworkBase.xml
https://github.com/azure-ad-b2c/user-migration/tree/master/seamless-account-migration#upload-the-policy-to-your-tenant

But that file is not included in the project
https://github.com/azure-ad-b2c/user-migration/tree/master/seamless-account-migration/policy

I have been trying to use the base file from the custom policy starter pack, but am getting several errors when uploading the seamless migration files.

Thanks,
-Eric

seamless migration xml configuration problem

When I use the tool, it can't read the property requiresMigration, so no request to our identity API.
When I set the default value to true, it called our API but does not update the requiresMigration (but password got changed und login with new password works).
<OutputClaim ClaimTypeReferenceId="requiresMigration" PartnerClaimType="extension_requiresMigration" DefaultValue="true" />
At first I have tried the sampleconfigs, the flag got flipped, but I can't sign in.
How can I fix this? Thanks

Problem with configuration

I have followed all the steps, but is no working properly.

When the authentication occurs, is hitting the API correctly, is event changing the flag but it's only returning this message:

"The username or password provided in the request are invalid."

I'm using seamless account migration flow.

What can i do to find the problem?

<?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="defaulttestdervanil.onmicrosoft.com"
					  PolicyId="B2C_1A_TrustFrameworkExtensions"
					  PublicPolicyUri="http://defaulttestdervanil.onmicrosoft.com/B2C_1A_TrustFrameworkExtensions">

	<BasePolicy>
		<TenantId>defaulttestdervanil.onmicrosoft.com</TenantId>
		<PolicyId>B2C_1A_TrustFrameworkBase</PolicyId>
	</BasePolicy>
	<BuildingBlocks>
		<ClaimsSchema>
			<ClaimType Id="requiresMigration">
				<DisplayName>extension_07eb19197f8e4ad8930988e4dd4d7eeb_requiresMigration</DisplayName>
				<DataType>boolean</DataType>
				<AdminHelpText>extension_07eb19197f8e4ad8930988e4dd4d7eeb_requiresMigration</AdminHelpText>
				<UserHelpText>extension_07eb19197f8e4ad8930988e4dd4d7eeb_requiresMigration</UserHelpText>
			</ClaimType>
			<ClaimType Id="extension_07eb19197f8e4ad8930988e4dd4d7eeb_requiresMigration">
				<DisplayName>extension_07eb19197f8e4ad8930988e4dd4d7eeb_requiresMigration</DisplayName>
				<DataType>boolean</DataType>
				<AdminHelpText>extension_07eb19197f8e4ad8930988e4dd4d7eeb_requiresMigration</AdminHelpText>
				<UserHelpText>extension_07eb19197f8e4ad8930988e4dd4d7eeb_requiresMigration</UserHelpText>
			</ClaimType>
			<!-- Holds the value of whether the authentication succeeded at the legacy IdP -->
			<ClaimType Id="tokenSuccess">
				<DisplayName>tokenSuccess</DisplayName>
				<DataType>boolean</DataType>
				<AdminHelpText>tokenSuccess</AdminHelpText>
				<UserHelpText>tokenSuccess</UserHelpText>
			</ClaimType>
			<!-- Holds the value 'false' when the legacy IdP authentication succeeded -->
			<ClaimType Id="migrationRequired">
				<DisplayName>migrationRequired</DisplayName>
				<DataType>boolean</DataType>
				<AdminHelpText>migrationRequired</AdminHelpText>
				<UserHelpText>migrationRequired</UserHelpText>
			</ClaimType>
		</ClaimsSchema>
	</BuildingBlocks>

	<ClaimsProviders>
		<ClaimsProvider>
			<DisplayName>Local Account SignIn</DisplayName>
			<TechnicalProfiles>

				<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email">
					<ValidationTechnicalProfiles>
						<!--Add user migration validation technical profiles before login-NonInteractive -->

						<!-- Populate extension_requireMigration into the claims pipeline -->
						<ValidationTechnicalProfile ReferenceId="Get-requiresMigration-status-signin" ContinueOnError="false" />

						<!-- If extension_requireMigration is true, call the legacy IdP via the REST API -->
						<ValidationTechnicalProfile ReferenceId="UserMigrationViaLegacyIdp" ContinueOnError="false">
							<Preconditions>
								<Precondition Type="ClaimEquals" ExecuteActionsIf="true">
									<Value>requiresMigration</Value>
									<Value>False</Value>
									<Action>SkipThisValidationTechnicalProfile</Action>
								</Precondition>
							</Preconditions>
						</ValidationTechnicalProfile>

						<!-- If the API returned 'tokensuccess', write the new password and unmark the account for migration -->
						<ValidationTechnicalProfile ReferenceId="AAD-WritePasswordAndFlipMigratedFlag" ContinueOnError="false">
							<Preconditions>
								<Precondition Type="ClaimsExist" ExecuteActionsIf="false">
									<Value>tokenSuccess</Value>
									<Action>SkipThisValidationTechnicalProfile</Action>
								</Precondition>
							</Preconditions>
						</ValidationTechnicalProfile>

						<!-- Initiate a normal logon against Azure AD B2C -->
						<ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
					</ValidationTechnicalProfiles>
				</TechnicalProfile>
				<TechnicalProfile Id="login-NonInteractive">
					<Metadata>
						<Item Key="client_id">ProxyIdentityExperienceFrameworkAppId</Item>
						<Item Key="IdTokenAudience">IdentityExperienceFrameworkAppId</Item>
					</Metadata>
					<InputClaims>
						<InputClaim ClaimTypeReferenceId="client_id" DefaultValue="ProxyIdentityExperienceFrameworkAppId" />
						<InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="IdentityExperienceFrameworkAppId" />
					</InputClaims>
				</TechnicalProfile>
				<TechnicalProfile Id="AAD-Common">
					<Metadata>
						<Item Key="ClientId">07eb1919-7f8e-4ad8-9309-88e4dd4d7eeb</Item>
						<Item Key="ApplicationObjectId">e3d67481-bdb8-46dd-a6b8-6f7f1b559057</Item>
					</Metadata>
				</TechnicalProfile>
			</TechnicalProfiles>
		</ClaimsProvider>
		<ClaimsProvider>
			<DisplayName>Local Account SignIn - Read migration status</DisplayName>
			<TechnicalProfiles>
				<TechnicalProfile Id="Get-requiresMigration-status-signin">
					<Metadata>
						<Item Key="Operation">Read</Item>
						<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
						<Item Key="UserMessageIfClaimsPrincipalDoesNotExist">An account could not be found for the provided user ID.</Item>
					</Metadata>
					<IncludeInSso>false</IncludeInSso>
					<InputClaims>
						<InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="signInNames.emailAddress" Required="true" />
					</InputClaims>
					<OutputClaims>
						<OutputClaim ClaimTypeReferenceId="objectId" />
						<!-- Set a default value (false) in the case the account does not have this attribute defined -->
						<OutputClaim ClaimTypeReferenceId="requiresMigration" PartnerClaimType="extension_07eb19197f8e4ad8930988e4dd4d7eeb_requiresMigration" DefaultValue="false" />
					</OutputClaims>
					<IncludeTechnicalProfile ReferenceId="AAD-Common" />
				</TechnicalProfile>
			</TechnicalProfiles>
		</ClaimsProvider>
		<ClaimsProvider>
			<DisplayName>REST API to communicate with Legacy IdP</DisplayName>
			<TechnicalProfiles>
				<TechnicalProfile Id="UserMigrationViaLegacyIdp">
					<DisplayName>REST API call to communicate with Legacy IdP</DisplayName>
					<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
					<Metadata>
						<Item Key="ServiceUrl">https://example.azurewebsites.net/users</Item>
<!--the api works it's removed-->
						<Item Key="AuthenticationType">None</Item>
						<Item Key="SendClaimsIn">Body</Item>
						<Item Key="AllowInsecureAuthInProduction">True</Item>
					</Metadata>
					<InputClaims>
						<InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="email" />
						<InputClaim ClaimTypeReferenceId="password" />
					</InputClaims>
					<OutputClaims>
						<OutputClaim ClaimTypeReferenceId="tokenSuccess" DefaultValue="false"/>
						<OutputClaim ClaimTypeReferenceId="migrationRequired"/>
					</OutputClaims>
					<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
				</TechnicalProfile>
			</TechnicalProfiles>
		</ClaimsProvider>
		<ClaimsProvider>
			<DisplayName>Local Account SignIn - Write new password and unmark for migration</DisplayName>
			<TechnicalProfiles>
				<TechnicalProfile Id="AAD-WritePasswordAndFlipMigratedFlag">
					<Metadata>
						<Item Key="Operation">Write</Item>
						<Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item>
					</Metadata>
					<IncludeInSso>false</IncludeInSso>
					<InputClaims>
						<InputClaim ClaimTypeReferenceId="objectId" Required="true" />
					</InputClaims>
					<PersistedClaims>
						<PersistedClaim ClaimTypeReferenceId="objectId" />
						<PersistedClaim ClaimTypeReferenceId="userPrincipalName" />
						<PersistedClaim ClaimTypeReferenceId="displayName" />
						<PersistedClaim ClaimTypeReferenceId="password" PartnerClaimType="password"/>
						<PersistedClaim ClaimTypeReferenceId="passwordPolicies" DefaultValue="DisablePasswordExpiration, DisableStrongPassword" AlwaysUseDefaultValue="true"/>
						<PersistedClaim ClaimTypeReferenceId="extension_07eb19197f8e4ad8930988e4dd4d7eeb_requiresMigration" DefaultValue="false" AlwaysUseDefaultValue="true"/>
					</PersistedClaims>
					<IncludeTechnicalProfile ReferenceId="AAD-Common" />
					<UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
				</TechnicalProfile>
			</TechnicalProfiles>
		</ClaimsProvider>
		<ClaimsProvider>
			<DisplayName>Local Account Password Reset - Read migration flag</DisplayName>
			<TechnicalProfiles>
				<TechnicalProfile Id="Get-requiresMigration-status-password-reset">
					<Metadata>
						<Item Key="Operation">Read</Item>
						<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
						<Item Key="UserMessageIfClaimsPrincipalDoesNotExist">An account could not be found for the provided user ID.</Item>
					</Metadata>
					<IncludeInSso>false</IncludeInSso>
					<InputClaims>
						<InputClaim ClaimTypeReferenceId="objectId" Required="true" />
					</InputClaims>
					<OutputClaims>
						<OutputClaim ClaimTypeReferenceId="requiresMigration" PartnerClaimType="extension_07eb19197f8e4ad8930988e4dd4d7eeb_requiresMigration" DefaultValue="false" />
					</OutputClaims>
					<IncludeTechnicalProfile ReferenceId="AAD-Common" />
				</TechnicalProfile>
			</TechnicalProfiles>
		</ClaimsProvider>
		<ClaimsProvider>
			<DisplayName>Local Account Password Reset - Flip migration flag</DisplayName>
			<TechnicalProfiles>
				<TechnicalProfile Id="AAD-FlipMigratedFlag">
					<Metadata>
						<Item Key="Operation">Write</Item>
						<Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item>
					</Metadata>
					<IncludeInSso>false</IncludeInSso>
					<InputClaims>
						<InputClaim ClaimTypeReferenceId="objectId" Required="true" />
					</InputClaims>
					<PersistedClaims>
						<PersistedClaim ClaimTypeReferenceId="objectId" />
						<PersistedClaim ClaimTypeReferenceId="userPrincipalName" />
						<PersistedClaim ClaimTypeReferenceId="displayName" />
						<PersistedClaim ClaimTypeReferenceId="migrationRequired" PartnerClaimType="extension_07eb19197f8e4ad8930988e4dd4d7eeb_requiresMigration" DefaultValue="false" AlwaysUseDefaultValue="true"/>
					</PersistedClaims>
					<IncludeTechnicalProfile ReferenceId="AAD-Common" />
					<UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
				</TechnicalProfile>
			</TechnicalProfiles>
		</ClaimsProvider>
		<ClaimsProvider>
			<DisplayName>Local Account Password Reset - Write Password</DisplayName>
			<TechnicalProfiles>
				<TechnicalProfile Id="LocalAccountWritePasswordUsingObjectId">
					<ValidationTechnicalProfiles>
						<ValidationTechnicalProfile ReferenceId="Get-requiresMigration-status-password-reset" ContinueOnError="false" />
						<ValidationTechnicalProfile ReferenceId="AAD-FlipMigratedFlag" ContinueOnError="false">
							<Preconditions>
								<Precondition Type="ClaimEquals" ExecuteActionsIf="true">
									<Value>requiresMigration</Value>
									<Value>False</Value>
									<Action>SkipThisValidationTechnicalProfile</Action>
								</Precondition>
							</Preconditions>
						</ValidationTechnicalProfile>
						<ValidationTechnicalProfile ReferenceId="AAD-UserWritePasswordUsingObjectId" />
					</ValidationTechnicalProfiles>
				</TechnicalProfile>
			</TechnicalProfiles>
		</ClaimsProvider>
	</ClaimsProviders>
</TrustFrameworkPolicy>

seamless migration missing base XML

Hey, I am wanting to use the seamless migration example. TheTrustFrameworkBase.xml is missing, should I be using the base of another example?

Bug in technical profile sample - jit-migration-v2

I think this technical profile validation step is missing a precondition. It should not run the REST call if the user is already found in AzureAD. We only want to know if it is in the legacy DB when it's not found in Azure AD.

Probably something like

          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisValidationTechnicalProfile</Action>
            </Precondition>
          </Preconditions>

Just wanted to post this issue rather than make a pull request because I'm still fairly new to all this and don't want to presume I'm right

Can't upload SignIn Policy

Hello,

I have been following the readme for seamless migration and I can't upload the signuporsign.xml policy. I started with the "getting started" pack in which I added the seamless migration technical profiles as saisd in the read me. Here is what I ended up with :

TrustFrameworkExtensions.xml

https://github.com/NicolasRiou/custom-policies/blob/main/TrustFrameworkExtensions.xml

And SignUpOrSignin.xml

https://github.com/NicolasRiou/custom-policies/blob/main/SignUpOrSignin.xml

And I am getting this error when I try to upload the SignUpOrSignin.xml using the VS Code extension:

Validation failed: 2 validation error(s) found in policy "B2C_1A_SEAMLESSMIGRATION_SIGNUPORSIGNIN" of tenant "xxxxxxxxx.onmicrosoft.com".

DisableStrongPassword is required in Technical Profile 'AAD-WritePasswordAndFlipMigratedFlag' of policy 'B2C_1A_SeamlessMigration_signuporsignin' for custom password complexity or legacy password restriction with weak custom regular expression. 

Add "DisablePasswordExpiration, DisableStrongPassword" into PersistedClaim "passwordPolicies"

Profile 'UserMigrationViaLegacyIdp' uses an insecure authentication mode that is only allowed in production mode policies with metadata key 'AllowInsecureAuthInProduction' set to true.

DisableStrongPassword is required in Technical Profile 'AAD-WritePasswordAndFlipMigratedFlag' of policy 'B2C_1A_SeamlessMigration_signuporsignin' for custom password complexity or legacy password restriction with weak custom regular expression. 

Add "DisablePasswordExpiration, DisableStrongPassword" into PersistedClaim "passwordPolicies...

Any help would be greatlly appreciated, thank you

Force account creation to match local users Id's

How can I force account creation to match local users Id's???
I tried creating a user, but the id is not passed:

`private static async Task MigrateUserAsync(GraphServiceClient client, MigratedUser user, string b2cDomainName)
{
var userPrincipalName = $"cpim_{Guid.NewGuid()}@{b2cDomainName}";
await client.Users.Request().AddAsync(new User
{
AccountEnabled = true,
Id = "837b0857-11cb-46ad-a229-4cd8de66d033",

            DisplayName = user.DisplayName,
            GivenName = user.GivenName,
            Surname = user.Surname,
            Identities = new List<ObjectIdentity>
            {
                new ObjectIdentity
                {
                    SignInType = "emailAddress",
                    Issuer = b2cDomainName,
                    IssuerAssignedId = user.Email
                },
            },

            PasswordProfile = new PasswordProfile
            {
                Password="xXx111!!!",
                ForceChangePasswordNextSignIn=false
            },

            PasswordPolicies = "DisablePasswordExpiration",
        });
    }`

from my code, I am passing Id = "837b0857-11cb-46ad-a229-4cd8de66d033",
but adb2c created the user with a different id.

Additional Closing Brace in TrustFrameworkExtensionsSeamlessMigration.xml

Thanks for all your work on this project--it has been extremely useful to me in implementing a custom B2C sign in for users migrating from another system. Whilst working with the project, I noticed a small typo in the TrustFrameworkExtensionsSeamlessMigration.xml file--there is an additional closing brace on line 141:

<PersistedClaim ClaimTypeReferenceId="passwordPolicies" DefaultValue="DisablePasswordExpiration, DisableStrongPassword" AlwaysUseDefaultValue="true"/>/>

ROPC with REST API/Dictionary reads as first step - returns 200 with HTML Response

I have two copies of an ROPC policy

  1. Has the standard sample of ResourceOwnerPasswordCredentials-OAUTH2 as the first step, the rest of the provided sample as steps 2 and 3, and correctly returns a 200 with the tokens, or a 400 on Bad U/N or bad Password

  2. Has additional logic for seamless migration (as described https://github.com/azure-ad-b2c/user-migration) which involves looking up a user's info in the dictionary, checking migration status, and then calling REST APIs to complete password migration. Once fully migrated, it calls the same exact ResourceOwnerPasswordCredentials-OAUTH2 profile, and returns a 200 with the tokens if successful, BUT, responds with a 200 with an html page containing an error message, rather than a 400 error.

ROPC : Does the user-migration with Sign-In & Rest-API to validate user on Legacy IDP work for ROPC ?

ROPC : Does the user-migration with Sign-In & Rest-API to validate user on Legacy IDP work for ROPC ?

We are using a mobile device and have users to migrate from an Database as part of Migration,
I followed

  1. ROPC Custom Policy https://docs.microsoft.com/en-us/azure/active-directory-b2c/ropc-custom?tabs=app-reg-ga
  2. Defined custom attributes https://docs.microsoft.com/en-us/azure/active-directory-b2c/user-flow-custom-attributes
  3. Setup a Rest-API on Legacy IDP to return migrationStatus
    https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-rest-api-intro

However, I think the ROPC with REST-API is not supported ? because the
ROPC has Protocol Name="OpenIdConnect" />
vs
SelfAsserted-LocalAccountSignin-Email has

and ran into problem of
Invalid technical profile with id "ResourceOwnerPasswordCredentials-OAUTH2" only the protocol handler ""Web.TPEngine.Providers.SelfAssertedAttributeProvider"" can have a ValidationTechnicalProfile

I stumbled upon these and noticed, the migration does not apply for ROPC (mobile devices) ? Is that true ?
https://docs.microsoft.com/en-us/azure/active-directory-b2c/self-asserted-technical-profile
https://docs.microsoft.com/en-us/azure/active-directory-b2c/openid-connect-technical-profile

Can someone tell me how do we do migration during SignIn with Rest-API interaction for ROPC grant_type ?

Seamless user migration custom policy.

@JasSuri @altenstedt

I am validating the user password with the onprem-api.
here is the my FrameWorkExtensionPolicy file.

XXX B2C_1A_TrustFrameworkLocalization_PasswordValidation extension_requiresMigration boolean extension_requiresMigration extension_requiresMigration extension_requiresMigration boolean extension_requiresMigration extension_requiresMigration tokenSuccess boolean tokenSuccess tokenSuccess migrationRequired boolean migrationRequired migrationRequired Bearer token string Grant type string scope string REST APIs https://login.microsoftonline.com/xxx.onmicrosoft.com/oauth2/v2.0/token Basic Form Local Account SignIn
    <TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email">
      <ValidationTechnicalProfiles>
        <!--Add user migration validation technical profiles before login-NonInteractive -->

        <!-- Populate extension_requireMigration into the claims pipeline -->
        <ValidationTechnicalProfile ReferenceId="Get-requiresMigration-status-signin" ContinueOnError="false" />

        <!-- If extension_requireMigration is true, call the legacy IdP via the REST API -->
        <ValidationTechnicalProfile ReferenceId="UserMigrationViaLegacyIdp" ContinueOnError="false">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>requiresMigration</Value>
              <Value>False</Value>
              <Action>SkipThisValidationTechnicalProfile</Action>
            </Precondition>
          </Preconditions>
        </ValidationTechnicalProfile>

        <!-- If the API returned 'tokensuccess', write the new password and unmark the account for migration -->
        <ValidationTechnicalProfile ReferenceId="AAD-WritePasswordAndFlipMigratedFlag" ContinueOnError="false">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="false">
              <Value>tokenSuccess</Value>
              <Action>SkipThisValidationTechnicalProfile</Action>
            </Precondition>
          </Preconditions>
        </ValidationTechnicalProfile>

        <!-- Initiate a normal logon against Azure AD B2C -->
        <ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
      </ValidationTechnicalProfiles>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

<ClaimsProvider>
  <DisplayName>Local Account SignIn - Read migration status</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="Get-requiresMigration-status-signin">
      <Metadata>
        <Item Key="Operation">Read</Item>
        <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
        <Item Key="UserMessageIfClaimsPrincipalDoesNotExist">An account could not be found for the provided user ID.</Item>
      </Metadata>
      <IncludeInSso>false</IncludeInSso>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="signInNames.emailAddress" Required="true" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="objectId" />
        <!-- Set a default value (false) in the case the account does not have this attribute defined -->
        <OutputClaim ClaimTypeReferenceId="requiresMigration" PartnerClaimType="extension_requiresMigration" DefaultValue="false" />
      </OutputClaims>
      <IncludeTechnicalProfile ReferenceId="AAD-Common" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

<ClaimsProvider>
  <DisplayName>REST API to communicate with Legacy IdP</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="UserMigrationViaLegacyIdp">
      <DisplayName>REST API call to communicate with Legacy IdP</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">https://xxx/b2c-password-validation-svc/v1/Password_migration?subscription-key=xxx</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AuthenticationType">Bearer</Item>
        <Item Key="UseClaimAsBearerToken">bearerToken</Item>
        <Item Key="AllowInsecureAuthInProduction">false</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="bearerToken"/>
        <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="email" />
        <InputClaim ClaimTypeReferenceId="password" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="tokenSuccess" DefaultValue="false"/>
        <OutputClaim ClaimTypeReferenceId="migrationRequired"/>
      </OutputClaims>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

<ClaimsProvider>
  <DisplayName>Local Account SignIn - Write new password and unmark for migration</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="AAD-WritePasswordAndFlipMigratedFlag">
      <Metadata>
        <Item Key="Operation">Write</Item>
        <Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item>
      </Metadata>
      <IncludeInSso>false</IncludeInSso>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
      </InputClaims>
      <PersistedClaims>
        <PersistedClaim ClaimTypeReferenceId="objectId" />
        <PersistedClaim ClaimTypeReferenceId="userPrincipalName" />
        <PersistedClaim ClaimTypeReferenceId="displayName" />
        <PersistedClaim ClaimTypeReferenceId="password" PartnerClaimType="password"/>
        <PersistedClaim ClaimTypeReferenceId="passwordPolicies" DefaultValue="DisablePasswordExpiration, DisableStrongPassword" AlwaysUseDefaultValue="true"/>
        <PersistedClaim ClaimTypeReferenceId="extension_requiresMigration" DefaultValue="false" AlwaysUseDefaultValue="true"/>
      </PersistedClaims>
      <IncludeTechnicalProfile ReferenceId="AAD-Common" />
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

<ClaimsProvider>
  <DisplayName>Local Account Password Reset - Read migration flag</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="Get-requiresMigration-status-password-reset">
      <Metadata>
        <Item Key="Operation">Read</Item>
        <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
        <Item Key="UserMessageIfClaimsPrincipalDoesNotExist">An account could not be found for the provided user ID.</Item>
      </Metadata>
      <IncludeInSso>false</IncludeInSso>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="requiresMigration" PartnerClaimType="extension_requiresMigration" DefaultValue="false" />
      </OutputClaims>
      <IncludeTechnicalProfile ReferenceId="AAD-Common" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

<ClaimsProvider>
  <DisplayName>Local Account Password Reset - Flip migration flag</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="AAD-FlipMigratedFlag">
      <Metadata>
        <Item Key="Operation">Write</Item>
        <Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item>
      </Metadata>
      <IncludeInSso>false</IncludeInSso>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
      </InputClaims>
      <PersistedClaims>
        <PersistedClaim ClaimTypeReferenceId="objectId" />
        <PersistedClaim ClaimTypeReferenceId="migrationRequired" PartnerClaimType="extension_requiresMigration" DefaultValue="false" AlwaysUseDefaultValue="true"/>
      </PersistedClaims>
      <IncludeTechnicalProfile ReferenceId="AAD-Common" />
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

<ClaimsProvider>
  <DisplayName>Local Account Password Reset - Write Password</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="LocalAccountWritePasswordUsingObjectId">
      <ValidationTechnicalProfiles>
        <ValidationTechnicalProfile ReferenceId="Get-requiresMigration-status-password-reset" ContinueOnError="false" />
        <ValidationTechnicalProfile ReferenceId="AAD-FlipMigratedFlag" ContinueOnError="false">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>requiresMigration</Value>
              <Value>False</Value>
              <Action>SkipThisValidationTechnicalProfile</Action>
            </Precondition>
          </Preconditions>
        </ValidationTechnicalProfile>
        <ValidationTechnicalProfile ReferenceId="AAD-UserWritePasswordUsingObjectId" />
      </ValidationTechnicalProfiles>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>
    <OrchestrationStep Order="3" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>objectId</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- This step reads any user attributes that we may not have received when in the token. -->
    <OrchestrationStep Order="4" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="5" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

  </OrchestrationSteps>
  <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>

I am getting error when trying to validate the password it is not calling the on-prem API.

"Unable to validate the information provided."
image

Can you please let me know what i am missing here?

Thanks,
Shiva

B2C Seamless Migration: First sign-in Attempt is Failing

We are experiencing what appears to be a race condition in B2C after following the seamless migration process outlined in https://github.com/azure-ad-b2c/user-migration/tree/master/seamless-account-migration.

The first time a user logs in, they are successfully validated against the legacy IdP via a web service, their 'requires migration' flag is successfully flipped to 'false', and their password is successfully written to B2C. However, when they hit the step 'login-NonInteractive', it is not authenticating them correctly and shows the error message "Invalid username or password." If the same user attempts a second login, it works.

Is it possible there is a race condition whereby the password is written to B2C in the AAD-UserWritePasswordUsingObjectId step, but it is not yet available to the login-NonInteractive step that does the authentication? If not, are there any other suggestions to look into?

Seamless user migration Error

Hi Team, @JasSuri @felickz @altenstedt @yoelhor

I am getting following error when trying to call a secure rest API to validate password:

image

i also validated the client id and secrete using postman i am able to generate a access token .

Here is the link to the Framework file https://github.com/softcloudservices/AADHTTP/blob/master/TrustFrameworkExtensions_PasswordValidation%20-%20Copy.xml

Please let me know if you need anything from myside.
Here are the details of the policy correlationID:

image

Thanks,
Shiva

JIT v2 missing step

As described, the JIT v2 flow does not work for legacy identity provider users logging in a second time. The first time a user with an account in the legacy directory authenticates, a user is created for them. The second time they authenticate, their login fails as the user already exists in B2C. One of two things should be changed:

  1. Ideally, there would be another step somewhere in the process (possibly at the start?) that checks if the username and password exist in AD B2C. If so, it would skip the migration process. Note that this could lead to a weird issue if the user has already signed up in both places
  2. Alternatively, and this may be what this policy is expecting, the REST call in REST-UserMigration-LocalAccount-SignIn should be stateful, and track the migration state of the user, returning null after migration has been completed. This seems like it requires a separate callback from ADB2C to a new REST endpoint after migration has been completed to be successful.

seamless-account-migration - Custom Policy Failing to upload

Hi ,

Wounder if you can help. I'm trying to action steps listed in seamless-account-migration section.

I've downloaded the start pack files and used Local account templates for TrustFrameworkExtensions.xml , but when trying to upload the files I get below error message .

Stage I'm on is
Upload SeamlessMigration_TrustFrameworkBase.xml and ensure that it does not fail the validation
Repeat last step to upload the SeamlessMigration_TrustFrameworkExtensions.xml, SeamlessMigration_SignUpOrSignin.xml and SeamlessMigration_PasswordReset.xml policy files.

TrustFrameworkBase.xml uploads fine but no other file after will upload , I've used start pack verson and also ones listed in sub sub folders within git hub.

Upload error of file -2
Upload error of file

Has anyone came across this issue before? File names listed in the document could they be files I need to download ?

Any help be great , thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.