├── .vs ├── ProjectSettings.json ├── Scripts │ └── v16 │ │ └── .suo └── slnx.sqlite ├── ConvertLanguage ├── B2CConvert-Language.ps1 ├── Maori │ ├── DefaultLocalizedResources_api.localaccountsignup1.1_mi.json │ ├── DefaultLocalizedResources_api.phonefactor1.1_mi.json │ ├── DefaultLocalizedResources_api.selfasserted.blockminor_mi.json │ ├── DefaultLocalizedResources_api.selfasserted1.1_mi.json │ └── DefaultLocalizedResources_api.signinandsignupwithpassword_mi.json └── readme.md ├── GettingStarted ├── .gitignore ├── Az.ADB2C.psm1 ├── AzureADB2C-Scripts.psm1 ├── README.md ├── aadb2c-create-graph-app.ps1 ├── aadb2c-create-graphexplorer-user.ps1 ├── aadb2c-create-group.ps1 ├── aadb2c-create-user-attr.ps1 ├── aadb2c-gen-cert-restapi.ps1 ├── aadb2c-upload-ux-to-storage.ps1 ├── b2cAppSettings.json ├── clean-b2c-tenant.ps1 ├── media │ └── 01-permissions-to-grant.png └── old │ ├── aadb2c-add-appinsights.ps1 │ ├── aadb2c-add-claimsprovider.ps1 │ ├── aadb2c-add-customattribute-app.ps1 │ ├── aadb2c-app-grant-permission.ps1 │ ├── aadb2c-create-ief-apps.ps1 │ ├── aadb2c-create-new-policy-project.ps1 │ ├── aadb2c-create-test-webapi.ps1 │ ├── aadb2c-create-test-webapp.ps1 │ ├── aadb2c-delete-policy.ps1 │ ├── aadb2c-download-starter-pack.ps1 │ ├── aadb2c-env.ps1 │ ├── aadb2c-init.ps1 │ ├── aadb2c-login.ps1 │ ├── aadb2c-policy-key-create.ps1 │ ├── aadb2c-policy-set-tenant.ps1 │ ├── aadb2c-policy-ux-customize.ps1 │ ├── aadb2c-prep-starter-pack.ps1 │ ├── aadb2c-run-policy-saml.ps1 │ ├── aadb2c-run-policy.ps1 │ └── aadb2c-upload-policy.ps1 ├── IEFTenantSetup ├── .gitignore ├── B2CIEFSetupWeb │ ├── B2CIEFSetupWeb.sln │ ├── B2CIEFSetupWeb │ │ ├── B2CIEFSetupWeb.csproj │ │ ├── Connected Services │ │ │ └── Application Insights │ │ │ │ └── ConnectedService.json │ │ ├── Constants.cs │ │ ├── Controllers │ │ │ └── HomeController.cs │ │ ├── Models │ │ │ ├── ErrorViewModel.cs │ │ │ ├── SetupRequest.cs │ │ │ └── SetupState.cs │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── Utilities │ │ │ └── B2CSetup.cs │ │ ├── Views │ │ │ ├── Home │ │ │ │ ├── Index.cshtml │ │ │ │ ├── Privacy.cshtml │ │ │ │ └── Setup.cshtml │ │ │ ├── Shared │ │ │ │ ├── Error.cshtml │ │ │ │ ├── _Layout.cshtml │ │ │ │ ├── _LoginPartial.cshtml │ │ │ │ └── _ValidationScriptsPartial.cshtml │ │ │ ├── _ViewImports.cshtml │ │ │ └── _ViewStart.cshtml │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ │ ├── css │ │ │ └── site.css │ │ │ ├── favicon.ico │ │ │ ├── js │ │ │ └── site.js │ │ │ └── lib │ │ │ ├── bootstrap │ │ │ └── dist │ │ │ │ ├── css │ │ │ │ ├── bootstrap-grid.css │ │ │ │ ├── bootstrap-grid.css.map │ │ │ │ ├── bootstrap-grid.min.css │ │ │ │ ├── bootstrap-grid.min.css.map │ │ │ │ ├── bootstrap-reboot.css │ │ │ │ ├── bootstrap-reboot.css.map │ │ │ │ ├── bootstrap-reboot.min.css │ │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ │ ├── bootstrap.css │ │ │ │ ├── bootstrap.css.map │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── bootstrap.min.css.map │ │ │ │ └── js │ │ │ │ ├── bootstrap.bundle.js │ │ │ │ ├── bootstrap.bundle.js.map │ │ │ │ ├── bootstrap.bundle.min.js │ │ │ │ ├── bootstrap.bundle.min.js.map │ │ │ │ ├── bootstrap.js │ │ │ │ ├── bootstrap.js.map │ │ │ │ ├── bootstrap.min.js │ │ │ │ └── bootstrap.min.js.map │ │ │ ├── jquery-validation-unobtrusive │ │ │ ├── LICENSE.txt │ │ │ ├── jquery.validate.unobtrusive.js │ │ │ └── jquery.validate.unobtrusive.min.js │ │ │ ├── jquery-validation │ │ │ ├── LICENSE.md │ │ │ └── dist │ │ │ │ ├── additional-methods.js │ │ │ │ ├── additional-methods.min.js │ │ │ │ ├── jquery.validate.js │ │ │ │ └── jquery.validate.min.js │ │ │ └── jquery │ │ │ ├── LICENSE.txt │ │ │ └── dist │ │ │ ├── jquery.js │ │ │ ├── jquery.min.js │ │ │ └── jquery.min.map │ └── Microsoft.Identity.Web │ │ ├── AccountExtensions.cs │ │ ├── Architecture.dgml │ │ ├── AuthorizeForScopesAttribute.cs │ │ ├── ClaimConstants.cs │ │ ├── ClaimsPrincipalExtensions.cs │ │ ├── ClaimsPrincipalFactory.cs │ │ ├── Diagrams.cd │ │ ├── Extensions.cs │ │ ├── HttpContextExtensions.cs │ │ ├── ITokenAcquisition.cs │ │ ├── InstanceDiscovery │ │ ├── IssuerConfigurationRetriever.cs │ │ ├── IssuerMetadata.cs │ │ └── Metadata.cs │ │ ├── InternalsVisibleTo.cs │ │ ├── Microsoft.Identity.Web.csproj │ │ ├── Microsoft.Identity.Web.ruleset │ │ ├── Microsoft.Identity.Web.sln │ │ ├── NuGet.Config │ │ ├── OidcConstants.cs │ │ ├── README.md │ │ ├── Resource │ │ ├── AadIssuerValidator.cs │ │ ├── JwtBearerMiddlewareDiagnostics.cs │ │ ├── OpenIdConnectMiddlewareDiagnostics.cs │ │ └── ScopesRequiredHttpContextExtensions.cs │ │ ├── ServiceCollectionExtensions.cs │ │ ├── TokenAcquisition.cs │ │ ├── TokenCacheProviders │ │ ├── Distributed │ │ │ ├── DistributedTokenCacheAdapterExtension.cs │ │ │ └── MsalDistributedTokenCacheAdapter.cs │ │ ├── IMsalTokenCacheProvider .cs │ │ ├── InMemory │ │ │ ├── InMemoryTokenCacheProviderExtension.cs │ │ │ ├── MsalMemoryTokenCacheOptions.cs │ │ │ └── MsalMemoryTokenCacheProvider.cs │ │ ├── MsalAbstractTokenCacheProvider.cs │ │ ├── Session │ │ │ ├── MsalSessionTokenCacheProvider.cs │ │ │ └── SessionTokenCacheProviderExtension.cs │ │ └── TokenCacheSerializers.cd │ │ ├── WebApiServiceCollectionExtensions.cs │ │ └── WebAppServiceCollectionExtensions.cs └── README.md ├── IEFTenantSetupV2 ├── .gitignore ├── B2CIEFSetupWeb │ ├── B2CIEFSetupWeb.sln │ ├── B2CIEFSetupWeb │ │ ├── .config │ │ │ └── dotnet-tools.json │ │ ├── B2CIEFSetupWeb.csproj │ │ ├── Connected Services │ │ │ └── Application Insights │ │ │ │ └── ConnectedService.json │ │ ├── Constants.cs │ │ ├── Controllers │ │ │ └── HomeController.cs │ │ ├── Models │ │ │ ├── ErrorViewModel.cs │ │ │ ├── SetupRequest.cs │ │ │ ├── SetupRequestPolicySample.cs │ │ │ ├── SetupState.cs │ │ │ ├── UploadError.cs │ │ │ ├── policyRow.cs │ │ │ └── sampleFolderBootstrap.cs │ │ ├── Program.cs │ │ ├── Properties │ │ │ ├── ServiceDependencies │ │ │ │ └── B2CIEFSetupApp - Web Deploy │ │ │ │ │ └── profile.arm.json │ │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── Utilities │ │ │ └── B2CSetup.cs │ │ ├── Views │ │ │ ├── Home │ │ │ │ ├── Experimental.cshtml │ │ │ │ ├── ExperimentalSetup.cshtml │ │ │ │ ├── Index.cshtml │ │ │ │ ├── Privacy.cshtml │ │ │ │ ├── Setup.cshtml │ │ │ │ └── Support.cshtml │ │ │ ├── Shared │ │ │ │ ├── Error.cshtml │ │ │ │ ├── _Layout.cshtml │ │ │ │ ├── _LoginPartial.cshtml │ │ │ │ └── _ValidationScriptsPartial.cshtml │ │ │ ├── _ViewImports.cshtml │ │ │ └── _ViewStart.cshtml │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ │ ├── css │ │ │ └── site.css │ │ │ ├── favicon.ico │ │ │ ├── js │ │ │ └── site.js │ │ │ └── lib │ │ │ ├── bootstrap │ │ │ └── dist │ │ │ │ ├── css │ │ │ │ ├── bootstrap-grid.css │ │ │ │ ├── bootstrap-grid.css.map │ │ │ │ ├── bootstrap-grid.min.css │ │ │ │ ├── bootstrap-grid.min.css.map │ │ │ │ ├── bootstrap-reboot.css │ │ │ │ ├── bootstrap-reboot.css.map │ │ │ │ ├── bootstrap-reboot.min.css │ │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ │ ├── bootstrap.css │ │ │ │ ├── bootstrap.css.map │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── bootstrap.min.css.map │ │ │ │ └── js │ │ │ │ ├── bootstrap.bundle.js │ │ │ │ ├── bootstrap.bundle.js.map │ │ │ │ ├── bootstrap.bundle.min.js │ │ │ │ ├── bootstrap.bundle.min.js.map │ │ │ │ ├── bootstrap.js │ │ │ │ ├── bootstrap.js.map │ │ │ │ ├── bootstrap.min.js │ │ │ │ └── bootstrap.min.js.map │ │ │ ├── jquery-validation-unobtrusive │ │ │ ├── LICENSE.txt │ │ │ ├── jquery.validate.unobtrusive.js │ │ │ └── jquery.validate.unobtrusive.min.js │ │ │ ├── jquery-validation │ │ │ ├── LICENSE.md │ │ │ └── dist │ │ │ │ ├── additional-methods.js │ │ │ │ ├── additional-methods.min.js │ │ │ │ ├── jquery.validate.js │ │ │ │ └── jquery.validate.min.js │ │ │ └── jquery │ │ │ ├── LICENSE.txt │ │ │ └── dist │ │ │ ├── jquery.js │ │ │ ├── jquery.min.js │ │ │ └── jquery.min.map │ └── Microsoft.Identity.Web │ │ ├── AccountExtensions.cs │ │ ├── Architecture.dgml │ │ ├── AuthorizeForScopesAttribute.cs │ │ ├── ClaimConstants.cs │ │ ├── ClaimsPrincipalExtensions.cs │ │ ├── ClaimsPrincipalFactory.cs │ │ ├── Diagrams.cd │ │ ├── Extensions.cs │ │ ├── HttpContextExtensions.cs │ │ ├── ITokenAcquisition.cs │ │ ├── InstanceDiscovery │ │ ├── IssuerConfigurationRetriever.cs │ │ ├── IssuerMetadata.cs │ │ └── Metadata.cs │ │ ├── InternalsVisibleTo.cs │ │ ├── Microsoft.Identity.Web.csproj │ │ ├── Microsoft.Identity.Web.ruleset │ │ ├── Microsoft.Identity.Web.sln │ │ ├── NuGet.Config │ │ ├── OidcConstants.cs │ │ ├── README.md │ │ ├── Resource │ │ ├── AadIssuerValidator.cs │ │ ├── JwtBearerMiddlewareDiagnostics.cs │ │ ├── OpenIdConnectMiddlewareDiagnostics.cs │ │ └── ScopesRequiredHttpContextExtensions.cs │ │ ├── ServiceCollectionExtensions.cs │ │ ├── TokenAcquisition.cs │ │ ├── TokenCacheProviders │ │ ├── Distributed │ │ │ ├── DistributedTokenCacheAdapterExtension.cs │ │ │ └── MsalDistributedTokenCacheAdapter.cs │ │ ├── IMsalTokenCacheProvider .cs │ │ ├── InMemory │ │ │ ├── InMemoryTokenCacheProviderExtension.cs │ │ │ ├── MsalMemoryTokenCacheOptions.cs │ │ │ └── MsalMemoryTokenCacheProvider.cs │ │ ├── MsalAbstractTokenCacheProvider.cs │ │ ├── Session │ │ │ ├── MsalSessionTokenCacheProvider.cs │ │ │ └── SessionTokenCacheProviderExtension.cs │ │ └── TokenCacheSerializers.cd │ │ ├── WebApiServiceCollectionExtensions.cs │ │ └── WebAppServiceCollectionExtensions.cs ├── GitRepoManager │ ├── GitRepoManager.sln │ └── GitRepoManager │ │ ├── Controllers │ │ ├── FetchRepoController.cs │ │ └── WeatherForecastController.cs │ │ ├── GitRepoManager.csproj │ │ ├── Policies.cs │ │ ├── PolicyFiles.cs │ │ ├── PolicyRoot.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── RepoRoot.cs │ │ ├── Startup.cs │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── policyRow.cs └── README.md ├── IEFUploadDownload ├── .gitignore ├── README.md ├── Upload-IEFPolicies.ps1 └── sampleData │ └── LocalAccounts │ ├── PasswordReset.xml │ ├── ProfileEdit.xml │ ├── SignUpOrSignin.xml │ ├── TrustFrameworkBase.xml │ ├── TrustFrameworkExtensions.xml │ └── appsettings.json ├── README.md └── custom-domain ├── check_b2cdomain.py ├── images ├── bash.png └── powershell.png ├── readme.md └── requirements.txt /.vs/ProjectSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "CurrentProjectSetting": null 3 | } -------------------------------------------------------------------------------- /.vs/Scripts/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azure-ad-b2c/Scripts/ba936150984b5a96e62c83932f3fe82d79172a92/.vs/Scripts/v16/.suo -------------------------------------------------------------------------------- /.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azure-ad-b2c/Scripts/ba936150984b5a96e62c83932f3fe82d79172a92/.vs/slnx.sqlite -------------------------------------------------------------------------------- /ConvertLanguage/B2CConvert-Language.ps1: -------------------------------------------------------------------------------- 1 | # Translate B2C Language Customisation using the cognitive API 2 | # Ensure you change the laguage settings below 3 | $global:lan = "mi" 4 | $global:APIKey = "" 5 | $jsonlangfilePath = "C:\Tools\b2c\Language\" 6 | ## 7 | 8 | function Translate 9 | { 10 | Param($string, $language, $at) 11 | try{ 12 | $body = "[{`"Text`":`"$string`"}]" 13 | $url = "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&from=en&to=" + $language 14 | $resp = Invoke-WebRequest -Uri $url -Headers @{"Ocp-Apim-Subscription-Key"="$global:APIKey"; "Authorization"="Bearer $at"; "Content-Type"="application/json"} -Method POST -Body $body 15 | $respjson = $resp.Content |ConvertFrom-Json 16 | $respjson.translations.text 17 | } 18 | catch { 19 | Write-Warning "Error translating string ($string) : $_" 20 | return $string 21 | } 22 | } 23 | 24 | $atresp = Invoke-WebRequest -Uri https://api.cognitive.microsoft.com/sts/v1.0/issueToken -Headers @{"Ocp-Apim-Subscription-Key"="$APIKey"} -Method POST 25 | $at = [System.Text.Encoding]::ASCII.GetString($atresp.Content) 26 | 27 | $files = Get-ChildItem -Filter "*.json" -Path $jsonlangfilePath 28 | 29 | foreach($infile in $files) 30 | { 31 | $customlang = Get-Content -Path $infile -raw | ConvertFrom-Json 32 | foreach ($str in $customlang.LocalizedStrings) 33 | { 34 | $str.Override = "True" 35 | $str.Value = Translate $str.Value $lan $at 36 | } 37 | 38 | $file = Get-Item $infile 39 | $outfile = $file.Directory.FullName + "\" + $file.BaseName + "_" + $lan +".json" 40 | $customlang | ConvertTo-Json -depth 100 | Out-File $outfile 41 | } 42 | -------------------------------------------------------------------------------- /ConvertLanguage/Maori/DefaultLocalizedResources_api.phonefactor1.1_mi.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azure-ad-b2c/Scripts/ba936150984b5a96e62c83932f3fe82d79172a92/ConvertLanguage/Maori/DefaultLocalizedResources_api.phonefactor1.1_mi.json -------------------------------------------------------------------------------- /ConvertLanguage/Maori/DefaultLocalizedResources_api.selfasserted.blockminor_mi.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azure-ad-b2c/Scripts/ba936150984b5a96e62c83932f3fe82d79172a92/ConvertLanguage/Maori/DefaultLocalizedResources_api.selfasserted.blockminor_mi.json -------------------------------------------------------------------------------- /ConvertLanguage/Maori/DefaultLocalizedResources_api.selfasserted1.1_mi.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azure-ad-b2c/Scripts/ba936150984b5a96e62c83932f3fe82d79172a92/ConvertLanguage/Maori/DefaultLocalizedResources_api.selfasserted1.1_mi.json -------------------------------------------------------------------------------- /ConvertLanguage/Maori/DefaultLocalizedResources_api.signinandsignupwithpassword_mi.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azure-ad-b2c/Scripts/ba936150984b5a96e62c83932f3fe82d79172a92/ConvertLanguage/Maori/DefaultLocalizedResources_api.signinandsignupwithpassword_mi.json -------------------------------------------------------------------------------- /ConvertLanguage/readme.md: -------------------------------------------------------------------------------- 1 | # Convert Language files using the Azure Cognative API 2 | 3 | ## Community Help and Support 4 | Use [Stack Overflow](https://stackoverflow.com/questions/tagged/azure-ad-b2c) to get support from the community. Ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before. Make sure that your questions or comments are tagged with [azure-ad-b2c]. 5 | If you find a bug in the sample, please raise the issue on [GitHub Issues](https://github.com/azure-ad-b2c/samples/issues). 6 | To provide product feedback, visit the Azure Active Directory B2C [Feedback page](https://feedback.azure.com/forums/169401-azure-active-directory?category_id=160596). 7 | 8 | ## Overview 9 | Azure AD B2C currently supports [36 languages](https://docs.microsoft.com/en-gb/azure/active-directory-b2c/active-directory-b2c-reference-language-customization#supported-languages) out of the box. However if you language is not currently supported you have the ability to upload your own languages files, giving Azure AD B2C the ability to support **any** language. 10 | for more information on Azure AD B2C Language customisation see the B2C Documetation pages - [Language customization in Azure Active Directory B2C](https://docs.microsoft.com/en-gb/azure/active-directory-b2c/active-directory-b2c-reference-language-customization) 11 | 12 | This Powershell script uses [Azure Cognative API](https://www.microsoft.com/en-us/translator/) to translate the language file values from english to the specified language. 13 | The example sets the language to New Zealand Māori (mi) as the language to convert to. Samples of the output can also be seen under the [Māori folder](/ConvertLanguage/Maori) 14 | 15 | ## How to run the script 16 | 1. First download the default language files from B2C (See [documentation](https://docs.microsoft.com/en-gb/azure/active-directory-b2c/active-directory-b2c-reference-language-customization#customize-your-strings)) 17 | 1. Store the lange files in a single directory with the json file name prefix (eg DefaultLocalizedResources_api.selfasserted1.1_en.**json**) 18 | 1. There are 2 settings in the powershell file you need to change; 19 | 1. $global:lan - Set this to your desired language to convert to (eg mi = Mauori) 20 | 1. $global:APIKey - This is the Azure cognative services key. Form more information see their [documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/translator/translator-text-how-to-signup) 21 | 1. Thats it 22 | 23 | Then just run the sciript and it will allend the chosen language code to the new file names. 24 | -------------------------------------------------------------------------------- /GettingStarted/.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | demo*/ 3 | tmp/ 4 | other/ 5 | 6 | # 7 | *.pfx 8 | *.cer 9 | *.txt 10 | 11 | # 12 | b2cAppSettings_*.json 13 | 14 | -------------------------------------------------------------------------------- /GettingStarted/aadb2c-create-graphexplorer-user.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][Alias('t')][string]$TenantName = "", 3 | [Parameter(Mandatory=$false)][Alias('d')][string]$displayName = "GraphExplorer", 4 | [Parameter(Mandatory=$false)][Alias('u')][string]$username = "graphexplorer", 5 | [Parameter(Mandatory=$false)][Alias('p')][string]$Password = "", 6 | [Parameter(Mandatory=$false)][Alias('r')][string[]]$RoleNames = @("Directory Readers", "Directory Writers") # @("Company Administrator") for Global Admin 7 | ) 8 | 9 | if ( "" -eq $TenantName ) { 10 | write-host "Getting Tenant info..." 11 | $tenant = Get-AzureADTenantDetail 12 | if ( $null -eq $tenant ) { 13 | write-host "Not logged in to a B2C tenant" 14 | exit 1 15 | } 16 | $tenantName = $tenant.VerifiedDomains[0].Name 17 | $tenantID = $tenant.ObjectId 18 | } 19 | 20 | $PasswordProfile = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile 21 | if ( "" -eq $Password ) { 22 | $cred = Get-Credential -UserName $DisplayName -Message "Enter userid for $TenantName" 23 | $PasswordProfile.Password = $cred.GetNetworkCredential().Password 24 | } else { 25 | $PasswordProfile.Password = $Password 26 | } 27 | $PasswordProfile.ForceChangePasswordNextLogin = $false 28 | 29 | $user = New-AzureADUser -DisplayName $displayName -mailNickName $username -PasswordPolicies "DisablePasswordExpiration" ` 30 | -UserType "Member" -AccountEnabled $true -PasswordProfile $PasswordProfile -UserPrincipalName "$username@$tenantName" 31 | write-output "User`t`t$username`nObjectID:`t$($user.ObjectID)" 32 | 33 | foreach( $roleName in $RoleNames) { 34 | $role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq $roleName} 35 | if ( $null -eq $role ) { 36 | $roleTemplate = Get-AzureADDirectoryRoleTemplate | ? { $_.DisplayName -eq $roleName } 37 | $ret = Enable-AzureADDirectoryRole -RoleTemplateId $roleTemplate.ObjectId 38 | $role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq $roleName} 39 | } 40 | $ret = Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $user.ObjectId 41 | write-output "Role`t`t$($role.DisplayName)`nDescription:`t$($role.Description)" 42 | } 43 | -------------------------------------------------------------------------------- /GettingStarted/aadb2c-create-group.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$true)][Alias('g')][string]$GroupName = "", 3 | [Parameter(Mandatory=$false)][Alias('e')][string]$email = "" 4 | ) 5 | 6 | $user = Get-AzureADUser -Filter "signInNames/any(x:x/value eq '$email')" -ErrorAction SilentlyContinue 7 | if ( $null -eq $user ) { 8 | write-error "User with signInName email=$email not found" 9 | exit 1 10 | } 11 | $group = Get-AzureADGroup -SearchString $GroupName -ErrorAction SilentlyContinue 12 | if ( $null -eq $group ) { 13 | write-host "Createing group $GroupName" 14 | $group = New-AzureADGroup -DisplayName $GroupName -MailEnabled $False -SecurityEnabled $True -MailNickName $GroupName 15 | } 16 | $ret = Add-AzureADGroupMember -ObjectId $group.ObjectId -RefObjectId $user.ObjectId 17 | Get-AzureADGroupMember -ObjectId $group.objectId 18 | -------------------------------------------------------------------------------- /GettingStarted/aadb2c-create-user-attr.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$False)][Alias('o')][string]$AppDisplayName = "b2c-extensions-app", # use this for default 3 | [Parameter(Mandatory=$True)][Alias('n')][string]$attributeName = "", 4 | [Parameter(Mandatory=$False)][Alias('d')][string]$dataType = "String" # String, Boolean, Date 5 | ) 6 | 7 | $appExt = Get-AzureADApplication -SearchString $AppDisplayName 8 | 9 | New-AzureADApplicationExtensionProperty -ObjectID $appExt.objectId -DataType $dataType -Name $attributeName -TargetObjects @("User") 10 | 11 | <# 12 | # list all current extension attributes 13 | Get-AzureADExtensionProperty 14 | #> 15 | 16 | <# 17 | # remove a specific attribute 18 | $fullAttrName = "extension_" + $appExt.AppId.Replace("-","") + "_$attributeName" 19 | $attrObj = Get-AzureADExtensionProperty | where {$_.Name -eq $fullAttrName} 20 | Remove-AzureADApplicationExtensionProperty -ObjectId $appExt.objectId -ExtensionPropertyId $attrObj.ObjectId 21 | #> 22 | 23 | <# 24 | # set/get a users extension attribute 25 | Set-AzureADUserExtension -ObjectId $User.ObjectId -ExtensionName $attrName -ExtensionValue "001002003" 26 | Get-AzureADUserExtension -ObjectId $User.ObjectId 27 | #> 28 | 29 | 30 | -------------------------------------------------------------------------------- /GettingStarted/aadb2c-gen-cert-restapi.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][Alias('s')][string]$Subject = "", # CN=apiname.yourtenant.onmicrosoft.com 3 | [Parameter(Mandatory=$false)][Alias('y')][int]$YearsValid = 1, 4 | [Parameter(Mandatory=$false)][Alias('l')][string]$CertStoreLocation = "Cert:\CurrentUser\My", 5 | [Parameter(Mandatory=$false)][Alias('f')][string]$Path = (Get-Location).Path, 6 | [Parameter(Mandatory=$true)][Alias('p')][System.Security.SecureString]$Password # ConvertTo-SecureString -String $pwd -Force -AsPlainText 7 | ) 8 | 9 | if ( "" -eq $Subject ) { 10 | $tenant = Get-AzureADTenantDetail 11 | $tenantName = $tenant.VerifiedDomains[0].Name 12 | $Subject = "CN=restapi.$tenantName" 13 | } 14 | #$certCN = "CN=restapi.cljunglabb2c.onmicrosoft.com" 15 | 16 | write-host "Generating certificate $Subject in $CertStoreLocation" 17 | $cert = New-SelfSignedCertificate -KeyExportPolicy Exportable -KeyAlgorithm RSA -KeyLength 2048 -KeyUsage DigitalSignature ` 18 | -NotAfter (Get-Date).AddYears($YearsValid) -Subject $Subject -CertStoreLocation $CertStoreLocation 19 | 20 | write-host $cert.Thumbprint 21 | 22 | $certfile = "$Path\$($Subject.Substring(3))_$(Get-Date -format("yyyMMdd")).pfx" 23 | write-host "Exporting to $certFile" 24 | Export-PfxCertificate -cert "$CertStoreLocation\$($cert.Thumbprint)" -FilePath $certfile -Password $Password 25 | 26 | # $certContent = New-Object System.Security.Cryptography.X509Certificates.X509Certificate($certfile, $pwd) 27 | # $certRaw = [System.Convert]::ToBase64String($certContent.GetRawCertData()) 28 | 29 | -------------------------------------------------------------------------------- /GettingStarted/aadb2c-upload-ux-to-storage.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$true)][Alias('p')][string]$Path = "", 3 | [Parameter(Mandatory=$false)][Alias('s')][string]$StorageAccountConnectString = "DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net", 4 | [Parameter(Mandatory=$false)][Alias('c')][string]$ContainerPath = "" 5 | ) 6 | 7 | $stgCtx = New-AzStorageContext -ConnectionString $StorageAccountConnectString 8 | 9 | $containerName = $ContainerPath.Split("/")[0] 10 | $location = $ContainerPath.Substring($containerName.Length+1) 11 | 12 | $files = get-childitem -path $path -name | Where-Object {! $_.PSIsContainer } 13 | foreach( $file in $files ) { 14 | write-output "Uploading to $($stgCtx.BlobEndPoint)$ContainerPath/$file" 15 | $res = Set-AzStorageBlobContent -File "$Path\$file" -Container $containerName -Blob "$location/$file" -Context $stgCtx -Force 16 | } 17 | -------------------------------------------------------------------------------- /GettingStarted/b2cAppSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "TenantName": "yourtenant.onmicrosoft.com", 3 | "ProjectPrefix": "demo", 4 | "StarterPack": "SocialAndLocalAccounts", 5 | "IefAppName": "IdentityExperienceFramework", 6 | "IefProxyAppName": "ProxyIdentityExperienceFramework", 7 | "InstrumentationKey": "...guid...", 8 | 9 | "ClientCredentials": { 10 | "client_id": "...guid...", 11 | "client_secret": "...secret..." 12 | }, 13 | 14 | "AzureStorageAccount": { 15 | "AccountName": "yourstorageaccountname", 16 | "AccountKey": "...key...", 17 | "ContainerName": "...contanername...", 18 | "Path": "subfoldername", 19 | "EndpointSuffix":"core.windows.net", 20 | "docLink": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-ui-customization#2-create-an-azure-blob-storage-account" 21 | }, 22 | 23 | "CustomAttributes": { 24 | "Enabled": true, 25 | "AppDisplayName": "b2c-extensions-app", 26 | "ObjectId": "", 27 | "AppID": "", 28 | "docLink": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-custom-attributes" 29 | }, 30 | 31 | "UxCustomization": { 32 | "Enabled": false, 33 | "docLink": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-ui-customization" 34 | }, 35 | 36 | "ClaimsProviders": [ 37 | { 38 | "Enabled": true, 39 | "Name": "facebook", 40 | "client_id": "1234567890", 41 | "client_secret": "1234567890", 42 | "use": "sig", 43 | "SecretName": "FacebookSecret", 44 | "docLink": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-facebook" 45 | }, 46 | { 47 | "Enabled": false, 48 | "Name": "msa", 49 | "client_id": "...guid...", 50 | "client_secret": "...secret...", 51 | "use": "sig", 52 | "SecretName": "MicrosoftAccountSecret", 53 | "docLink": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-microsoft-account-custom" 54 | }, 55 | { 56 | "Enabled": false, 57 | "Name": "google", 58 | "client_id": "...guid...", 59 | "client_secret": "...secret...", 60 | "use": "sig", 61 | "SecretName": "GoogleSecret", 62 | "docLink": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-google-custom" 63 | }, 64 | { 65 | "Enabled": false, 66 | "Name": "twitter", 67 | "client_id": "...guid...", 68 | "client_secret": "...secret...", 69 | "use": "enc", 70 | "SecretName": "TwitterSecret", 71 | "docLink": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-twitter-custom" 72 | }, 73 | { 74 | "Enabled": false, 75 | "Name": "amazon", 76 | "client_id": "...guid...", 77 | "client_secret": "...secret...", 78 | "use": "sig", 79 | "SecretName": "AmazonSecret", 80 | "docLink": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-amazon-custom" 81 | }, 82 | { 83 | "Enabled": false, 84 | "Name": "azuread", 85 | "client_id": "...guid...", 86 | "client_secret": "...secret...", 87 | "use": "sig", 88 | "SecretName": "Yourdomain2Secret", 89 | "DomainName": "yourdomain.com", 90 | "docLink": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-azure-ad-single-tenant-custom" 91 | } 92 | ] 93 | 94 | } 95 | -------------------------------------------------------------------------------- /GettingStarted/clean-b2c-tenant.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # CAREFUL! 3 | # This script is intended to reset a B2C demo environment 4 | # It deletes IEF Keys, IEF Policies, Users (excl GlobalAdmins), Groups and Applications (excl b2c-extensions-app) 5 | # 6 | exit # safety switch 7 | 8 | $auth =Connect-AzureADB2CDevicelogin -TenantID $global:TenantName -Scope "TrustFrameworkKeySet.ReadWrite.All Policy.ReadWrite.TrustFramework Application.ReadWrite.All User.ReadWrite.All Group.ReadWrite.All" 9 | $authHeader =@{ 'Content-Type'='application/json'; 'Authorization'=$auth.token_type + ' ' + $auth.access_token } 10 | 11 | # delete all IEF Policy Keys 12 | $url = "https://graph.microsoft.com/beta/trustFramework/keySets" 13 | $resp = Invoke-RestMethod -Method GET -Uri $url -Headers $authHeader 14 | foreach( $pkey in $resp.value ) { 15 | $ret = Invoke-RestMethod -Method "DELETE" -Uri "$url/$($pkey.id)" -Headers $authHeader 16 | } 17 | 18 | # delete all IEF Custom Policies 19 | $url = "https://graph.microsoft.com/beta/trustFramework/policies" 20 | $resp = Invoke-RestMethod -Method GET -Uri $url -Headers $authHeader 21 | foreach( $p in $resp.value ) { 22 | $ret = Invoke-RestMethod -Method "DELETE" -Uri "$url/$($p.id)" -Headers $authHeader 23 | } 24 | 25 | # get all Global Admins (so we don't delete them) 26 | $url = "https://graph.microsoft.com/beta/directoryRoles?`$filter=displayName eq 'Global Administrator'" 27 | $resp = Invoke-RestMethod -Method GET -Uri $url -Headers $authHeader 28 | $idGlobalAdmin = $resp.value.id 29 | 30 | $url = "https://graph.microsoft.com/beta/directoryRoles/$idGlobalAdmin/members" 31 | $resp = Invoke-RestMethod -Method GET -Uri $url -Headers $authHeader 32 | $globalAdmins = $resp.value 33 | 34 | # delete all users EXCEPT admins (otherwise you would be locked out) 35 | $url = "https://graph.microsoft.com/beta/users" 36 | $resp = Invoke-RestMethod -Method GET -Uri $url -Headers $authHeader 37 | foreach( $u in $resp.value ) { 38 | # don't delete Admins 39 | # if ( !($u.UserPrincipalName.IndexOf("#EXT#") -gt 0 -or $u.UserPrincipalName.StartsWith("graphexplorer@") -eq $True) ) { 40 | if ( $null -eq ( Compare-Object -IncludeEqual -ExcludeDifferent $u.id $globalAdmins.id) ) { 41 | $ret = Invoke-RestMethod -Method "DELETE" -Uri "$url/$($u.id)" -Headers $authHeader 42 | } else { 43 | write-host "Skipping Global Admin " $u.id $u.displayName 44 | } 45 | } 46 | 47 | # delete all groups 48 | $url = "https://graph.microsoft.com/beta/groups" 49 | $resp = Invoke-RestMethod -Method GET -Uri $url -Headers $authHeader 50 | foreach( $g in $resp.value ) { 51 | $ret = Invoke-RestMethod -Method "DELETE" -Uri "$url/$($g.id)" -Headers $authHeader 52 | } 53 | 54 | # delete all applications 55 | $url = "https://graph.microsoft.com/beta/applications" 56 | $resp = Invoke-RestMethod -Method GET -Uri $url -Headers $authHeader 57 | foreach( $a in $resp.value ) { 58 | if ( !$a.displayName.StartsWith("b2c-extensions-app")) { # do NOT delete this app 59 | $ret = Invoke-RestMethod -Method "DELETE" -Uri "$url/$($a.id)" -Headers $authHeader 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /GettingStarted/media/01-permissions-to-grant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azure-ad-b2c/Scripts/ba936150984b5a96e62c83932f3fe82d79172a92/GettingStarted/media/01-permissions-to-grant.png -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-add-customattribute-app.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][Alias('p')][string]$PolicyPath = "", 3 | [Parameter(Mandatory=$false)][Alias('c')][string]$client_id = "", # client_id/AppId of the app handeling custom attributes 4 | [Parameter(Mandatory=$false)][Alias('a')][string]$objectId = "", # objectId of the same app 5 | [Parameter(Mandatory=$false)][Alias('n')][string]$AppDisplayName = "", # objectId of the same app 6 | [Parameter(Mandatory=$false)][Alias('f')][string]$PolicyFile = "TrustFrameworkExtensions.xml", # if the Extensions file has a different name 7 | [Parameter(Mandatory=$false)][boolean]$AzureCli = $False # if to force Azure CLI on Windows 8 | ) 9 | 10 | if ( $env:PATH -imatch "/usr/bin" ) { # Mac/Linux 11 | $isWinOS = $false 12 | } else { 13 | $isWinOS = $true 14 | } 15 | 16 | if ( "" -eq $PolicyPath ) { 17 | $PolicyPath = (get-location).Path 18 | } 19 | 20 | [xml]$ext =Get-Content -Path "$PolicyPath/$PolicyFile" -Raw 21 | 22 | $tpId = "AAD-Common" 23 | $claimsProviderXml=@" 24 | 25 | Azure Active Directory 26 | 27 | 28 | 29 | 30 | {client_id} 31 | 32 | {objectId} 33 | 34 | 35 | 36 | 37 | "@ 38 | 39 | if ( $ext.TrustFrameworkPolicy.ClaimsProviders.InnerXml -imatch $tpId ) { 40 | write-output "TechnicalProfileId $tpId already exists in policy" 41 | exit 1 42 | } 43 | 44 | # if no client_id given, use the standard b2c-extensions-app 45 | if ( "" -eq $client_id ) { 46 | if ( "" -eq $AppDisplayName ) { $AppDisplayName = "b2c-extensions-app"} 47 | write-output "Using $AppDisplayName" 48 | if ( $False -eq $isWinOS -or $True -eq $AzureCli ) { 49 | $appExt = (az ad app list --display-name $AppDisplayName | ConvertFrom-json) 50 | } else { 51 | $appExt = Get-AzureADApplication -SearchString $AppDisplayName 52 | } 53 | $client_id = $appExt.AppId 54 | $objectId = $appExt.objectId 55 | } 56 | write-output "Adding TechnicalProfileId $tpId" 57 | 58 | $claimsProviderXml = $claimsProviderXml.Replace("{client_id}", $client_id) 59 | $claimsProviderXml = $claimsProviderXml.Replace("{objectId}", $objectId) 60 | 61 | $ext.TrustFrameworkPolicy.ClaimsProviders.innerXml = $ext.TrustFrameworkPolicy.ClaimsProviders.innerXml + $claimsProviderXml 62 | 63 | $ext.Save("$PolicyPath/TrustFrameworkExtensions.xml") 64 | -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-app-grant-permission.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][Alias('t')][string]$TenantName = "", 3 | [Parameter(Mandatory=$false)][Alias('a')][string]$AppID = "", 4 | [Parameter(Mandatory=$false)][Alias('k')][string]$AppKey = "", 5 | [Parameter(Mandatory=$true)][Alias('n')][string]$AppDisplayName = "" 6 | ) 7 | 8 | $oauth = $null 9 | if ( "" -eq $AppID ) { $AppID = $env:B2CAppId } 10 | if ( "" -eq $AppKey ) { $AppKey = $env:B2CAppKey } 11 | 12 | $tenantID = "" 13 | if ( "" -eq $TenantName ) { 14 | write-host "Getting Tenant info..." 15 | $tenant = Get-AzureADTenantDetail 16 | if ( $null -eq $tenant ) { 17 | write-host "Not logged in to a B2C tenant" 18 | exit 1 19 | } 20 | $tenantName = $tenant.VerifiedDomains[0].Name 21 | $tenantID = $tenant.ObjectId 22 | } else { 23 | if ( !($TenantName -imatch ".onmicrosoft.com") ) { 24 | $TenantName = $TenantName + ".onmicrosoft.com" 25 | } 26 | $resp = Invoke-RestMethod -Uri "https://login.windows.net/$TenantName/v2.0/.well-known/openid-configuration" 27 | $tenantID = $resp.authorization_endpoint.Split("/")[3] 28 | } 29 | if ( "" -eq $tenantID ) { 30 | write-host "Unknown Tenant" 31 | exit 2 32 | } 33 | write-host "Tenant: `t$tenantName`nTenantID:`t$tenantId" 34 | 35 | $app = Get-AzureADApplication -All $true | where-object {$_.DisplayName -eq $AppDisplayName } -ErrorAction SilentlyContinue 36 | $sp = Get-AzureADServicePrincipal -All $true | where-object {$_.DisplayName -eq $AppDisplayName } -ErrorAction SilentlyContinue 37 | 38 | if ( $null -eq $app -or $null -eq $sp ) { 39 | write-output "No ServicePrincipal with name $AppDisplayName" 40 | exit 1 41 | } 42 | 43 | $oauthBody = @{grant_type="client_credentials";resource="https://graph.microsoft.com/";client_id=$AppID;client_secret=$AppKey;scope="https://graph.microsoft.com/.default"} 44 | $oauth = Invoke-RestMethod -Method Post -Uri "https://login.microsoft.com/$tenantName/oauth2/token?api-version=1.0" -Body $oauthBody 45 | 46 | $startTime = (get-date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") 47 | $expiryTime = ((get-date).AddYears(2)).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") 48 | $scope = "" 49 | foreach( $reqResAccess in $app.RequiredResourceAccess ) { 50 | $resource = (Get-AzureADServicePrincipal -All $true | where-object {$_.AppId -eq $reqResAccess.ResourceAppId }) 51 | $ResourceObjectId = $resource.ObjectId 52 | foreach( $ra in $reqResAccess.ResourceAccess ) { 53 | $scope += ($resource.oauth2Permissions | where-object {$_.Id -eq $ra.Id}).Value + " " 54 | } 55 | $body = @{ 56 | clientId = $sp.ObjectId 57 | consentType = "AllPrincipals" 58 | principalId = $null 59 | resourceId = $ResourceObjectId 60 | scope = $scope 61 | startTime = $startTime 62 | expiryTime = $expiryTime 63 | } 64 | write-output "Granting $($resource.DisplayName) - $scope to $AppDisplayName" 65 | $apiUrl = "https://graph.microsoft.com/beta/oauth2PermissionGrants" 66 | Invoke-RestMethod -Uri $apiUrl -Headers @{Authorization = "Bearer $($oauth.access_token)" } -Method POST -Body $($body | convertto-json) -ContentType "application/json" 67 | } 68 | 69 | -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-create-new-policy-project.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][Alias('t')][string]$TenantName = "", # current tenant assumed if not specified 3 | [Parameter(Mandatory=$false)][Alias('p')][string]$PolicyPath = "", # local path assumed if not specified 4 | [Parameter(Mandatory=$false)][Alias('n')][string]$PolicyPrefix = "", # prefix to add to PolicyIds, like B2C_1A__SignUpOrSignIn 5 | [Parameter(Mandatory=$false)][Alias('k')][boolean]$KeepPolicyIds = $False, # if this is $True, $PolicyPrefix is ignored and PolicyIds are kept unchanged 6 | [Parameter(Mandatory=$false)][Alias('c')][string]$ConfigPath = "", # full path to your b2cAppSettings.json config file 7 | [Parameter(Mandatory=$false)][Alias('s')][boolean]$UploadSecrets = $false # if to create secrets too 8 | ) 9 | 10 | & $PSScriptRoot\aadb2c-env.ps1 -p $PolicyPath -n $PolicyPrefix -k $KeepPolicyIds -c $ConfigPath 11 | 12 | $PolicyPath = $global:PolicyPath 13 | $PolicyPrefix = $global:PolicyPrefix 14 | 15 | function writeSeparator( $msg ) { 16 | write-output "*******************************************************************************" 17 | write-output "* $msg" 18 | write-output "*******************************************************************************" 19 | } 20 | 21 | # download StarterPack files from github and modify them to refer to your tenant 22 | writeSeparator "Downloading and preparing Starter Pack" 23 | & $PSScriptRoot\aadb2c-prep-starter-pack.ps1 -t $TenantName -x $PolicyPrefix -p $PolicyPath -b $b2cAppSettings.StarterPack ` 24 | -IefAppName $b2cAppSettings.IefAppName -IefProxyAppName $b2cAppSettings.IefProxyAppName 25 | 26 | # add custom attribute app 27 | if ( $null -ne $b2cAppSettings.CustomAttributes -and $true -eq $b2cAppSettings.CustomAttributes.Enabled ) { 28 | writeSeparator "Adding custom attributes app to AAD-Common Claims Provider" 29 | & $PSScriptRoot\aadb2c-add-customattribute-app.ps1 -n $b2cAppSettings.CustomAttributes.AppDisplayName ` 30 | -a $b2cAppSettings.CustomAttributes.ObjectId -c $b2cAppSettings.CustomAttributes.AppID 31 | } 32 | 33 | # add social IdPs 34 | writeSeparator "Adding Social IdPs" 35 | foreach( $cp in $b2cAppSettings.ClaimsProviders ) { 36 | if ( $true -eq $cp.Enabled ) { 37 | & $PSScriptRoot\aadb2c-add-claimsprovider.ps1 -i $cp.Name -c $cp.client_id -a $cp.DomainName 38 | if ( $true -eq $UploadSecrets -and ($null -ne $cp.client_secret -or "" -ne $cp.client_secret) ) { 39 | & $PSScriptRoot\aadb2c-policy-key-create.ps1 -n $cp.SecretName -s $cp.client_secret -y "secret" -u $cp.use 40 | } 41 | } 42 | } 43 | 44 | # change content definitions, enable javascript and point UX to our own url 45 | if ( $null -ne $b2cAppSettings.UxCustomization -and $true -eq $b2cAppSettings.UxCustomization.Enabled ) { 46 | writeSeparator "Enabling Javascript and UX Customization" 47 | & $PSScriptRoot\aadb2c-policy-ux-customize.ps1 -d $true -u "https://$uxStorageAccount.blob.$EndpointSuffix/$uxTemplateLocation" 48 | } 49 | # upload the Custom Policies to B2C 50 | writeSeparator "Uploading Custom Policies to B2C" 51 | & $PSScriptRoot\aadb2c-upload-policy.ps1 -t $TenantName 52 | 53 | # upload the UX elements to blob storage 54 | if ( $null -ne $b2cAppSettings.UxCustomization -and $true -eq $b2cAppSettings.UxCustomization.Enabled ) { 55 | writeSeparator "Uploading html files to Azure Blob Storage" 56 | & $PSScriptRoot\aadb2c-upload-ux-to-storage.ps1 -p "$PolicyPath\html" -s $storageConnectString -c $uxTemplateLocation 57 | } -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-create-test-webapi.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$true)][Alias('n')][string]$DisplayName = "Test-WebApi", 3 | [Parameter(Mandatory=$false)][Alias('a')][string]$AppID = "", 4 | [Parameter(Mandatory=$false)][Alias('k')][string]$AppKey = "" 5 | ) 6 | 7 | $oauth = $null 8 | if ( "" -eq $AppID ) { $AppID = $env:B2CAppId } 9 | if ( "" -eq $AppKey ) { $AppKey = $env:B2CAppKey } 10 | 11 | $tenant = Get-AzureADTenantDetail 12 | $tenantName = $tenant.VerifiedDomains[0].Name 13 | 14 | Function CreateScope( [string] $value, [string] $userConsentDisplayName, [string] $userConsentDescription, 15 | [string] $adminConsentDisplayName, [string] $adminConsentDescription) 16 | { 17 | $scope = New-Object Microsoft.Open.AzureAD.Model.OAuth2Permission 18 | $scope.Id = New-Guid 19 | $scope.Value = $value 20 | $scope.UserConsentDisplayName = $userConsentDisplayName 21 | $scope.UserConsentDescription = $userConsentDescription 22 | $scope.AdminConsentDisplayName = $adminConsentDisplayName 23 | $scope.AdminConsentDescription = $adminConsentDescription 24 | $scope.IsEnabled = $true 25 | $scope.Type = "User" 26 | return $scope 27 | } 28 | 29 | $requiredResourceAccess=@" 30 | [ 31 | { 32 | "resourceAppId": "00000003-0000-0000-c000-000000000000", 33 | "resourceAccess": [ 34 | { 35 | "id": "37f7f235-527c-4136-accd-4a02d197296e", 36 | "type": "Scope" 37 | }, 38 | { 39 | "id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182", 40 | "type": "Scope" 41 | } 42 | ] 43 | } 44 | ] 45 | "@ | ConvertFrom-json 46 | 47 | $reqAccess=@() 48 | foreach( $resApp in $requiredResourceAccess ) { 49 | $req = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess" 50 | $req.ResourceAppId = $resApp.resourceAppId 51 | foreach( $ra in $resApp.resourceAccess ) { 52 | $req.ResourceAccess += New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList $ra.Id,$ra.type 53 | } 54 | $reqAccess += $req 55 | } 56 | 57 | $scopes=@() 58 | $scope = CreateScope -value "Demo.Read" ` 59 | -userConsentDisplayName "Allow demo read" ` 60 | -userConsentDescription "Allow the demo application to read demo data on your behalf." ` 61 | -adminConsentDisplayName "Allow demo read" ` 62 | -adminConsentDescription "Allow the demo application to read demo data on your behalf." 63 | $scopes += $scope 64 | 65 | write-output "Creating application $DisplayName" 66 | $app = New-AzureADApplication -DisplayName $DisplayName -IdentifierUris "https://$TenantName/$DisplayName" -ReplyUrls @("https://jwt.ms") -RequiredResourceAccess $reqAccess -OAuth2Permission $scopes -Oauth2AllowImplicitFlow $true 67 | 68 | write-output "Creating ServicePrincipal $DisplayName" 69 | $sp = New-AzureADServicePrincipal -AccountEnabled $true -AppId $App.AppId -AppRoleAssignmentRequired $false -DisplayName $DisplayName 70 | 71 | Start-Sleep 15 72 | $oauthBody = @{grant_type="client_credentials";resource="https://graph.microsoft.com/";client_id=$AppID;client_secret=$AppKey;scope="https://graph.microsoft.com/.default Application.ReadWrite.All"} 73 | $oauth = Invoke-RestMethod -Method Post -Uri "https://login.microsoft.com/$tenantName/oauth2/token?api-version=1.0" -Body $oauthBody 74 | $apiUrl = "https://graph.microsoft.com/v1.0/applications/$($app.objectId)" 75 | $body = @{ SignInAudience = "AzureADandPersonalMicrosoftAccount" } 76 | Invoke-RestMethod -Uri $apiUrl -Headers @{Authorization = "Bearer $($oauth.access_token)" } -Method PATCH -Body ($body | ConvertTo-json) -ContentType "application/json" 77 | 78 | & $PSScriptRoot\aadb2c-app-grant-permission.ps1 -n $DisplayName -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-create-test-webapp.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$true)][Alias('n')][string]$DisplayName = "Test-WebApp", 3 | [Parameter(Mandatory=$false)][Alias('a')][string]$AppID = "", 4 | [Parameter(Mandatory=$false)][Alias('k')][string]$AppKey = "" 5 | ) 6 | 7 | $oauth = $null 8 | if ( "" -eq $AppID ) { $AppID = $env:B2CAppId } 9 | if ( "" -eq $AppKey ) { $AppKey = $env:B2CAppKey } 10 | 11 | $tenant = Get-AzureADTenantDetail 12 | $tenantName = $tenant.VerifiedDomains[0].Name 13 | 14 | $requiredResourceAccess=@" 15 | [ 16 | { 17 | "resourceAppId": "00000003-0000-0000-c000-000000000000", 18 | "resourceAccess": [ 19 | { 20 | "id": "37f7f235-527c-4136-accd-4a02d197296e", 21 | "type": "Scope" 22 | }, 23 | { 24 | "id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182", 25 | "type": "Scope" 26 | } 27 | ] 28 | } 29 | ] 30 | "@ | ConvertFrom-json 31 | 32 | $reqAccess=@() 33 | foreach( $resApp in $requiredResourceAccess ) { 34 | $req = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess" 35 | $req.ResourceAppId = $resApp.resourceAppId 36 | foreach( $ra in $resApp.resourceAccess ) { 37 | $req.ResourceAccess += New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList $ra.Id,$ra.type 38 | } 39 | $reqAccess += $req 40 | } 41 | 42 | write-output "Creating application $DisplayName" 43 | $app = New-AzureADApplication -DisplayName $DisplayName -IdentifierUris "https://$TenantName/$DisplayName" -ReplyUrls @("https://jwt.ms") -RequiredResourceAccess $reqAccess -Oauth2AllowImplicitFlow $true 44 | 45 | write-output "Creating ServicePrincipal $DisplayName" 46 | $sp = New-AzureADServicePrincipal -AccountEnabled $true -AppId $App.AppId -AppRoleAssignmentRequired $false -DisplayName $DisplayName 47 | 48 | 49 | # ----------------------------------------------------------------------------------------- 50 | # Patch WebApp with attributes Poweshell can't 51 | # ----------------------------------------------------------------------------------------- 52 | 53 | Start-Sleep 15 # replication 54 | 55 | $oauthBody = @{grant_type="client_credentials";resource="https://graph.microsoft.com/";client_id=$AppID;client_secret=$AppKey;scope="https://graph.microsoft.com/.default Application.ReadWrite.All"} 56 | $oauth = Invoke-RestMethod -Method Post -Uri "https://login.microsoft.com/$tenantName/oauth2/token?api-version=1.0" -Body $oauthBody 57 | 58 | $apiUrl = "https://graph.microsoft.com/v1.0/applications/$($app.objectId)" 59 | $body = @{ SignInAudience = "AzureADandPersonalMicrosoftAccount" } 60 | Invoke-RestMethod -Uri $apiUrl -Headers @{Authorization = "Bearer $($oauth.access_token)" } -Method PATCH -Body ($body | ConvertTo-json) -ContentType "application/json" 61 | 62 | & $PSScriptRoot\aadb2c-app-grant-permission.ps1 -n $DisplayName 63 | 64 | 65 | -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-delete-policy.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][Alias('p')][string]$PolicyPath = "", 3 | [Parameter(Mandatory=$false)][Alias('f')][string]$PolicyFile = "", 4 | [Parameter(Mandatory=$false)][Alias('t')][string]$TenantName = "", 5 | [Parameter(Mandatory=$false)][Alias('a')][string]$AppID = "", 6 | [Parameter(Mandatory=$false)][Alias('k')][string]$AppKey = "", 7 | [Parameter(Mandatory=$false)][boolean]$AzureCli = $False # if to force Azure CLI on Windows 8 | ) 9 | 10 | $oauth = $null 11 | if ( "" -eq $AppID ) { $AppID = $env:B2CAppId } 12 | if ( "" -eq $AppKey ) { $AppKey = $env:B2CAppKey } 13 | if ( "" -eq $TenantName ) { $TenantName = $global:TenantName } 14 | if ( $env:PATH -imatch "/usr/bin" ) { # Mac/Linux 15 | $isWinOS = $false 16 | } else { 17 | $isWinOS = $true 18 | } 19 | 20 | # invoke the Graph REST API to upload the Policy 21 | Function DeletePolicy( [string]$PolicyId) { 22 | # https://docs.microsoft.com/en-us/graph/api/trustframework-put-trustframeworkpolicy?view=graph-rest-beta 23 | # Delete the Custom Policy 24 | write-host "Deleteing policy $PolicyId..." 25 | $url = "https://graph.microsoft.com/beta/trustFramework/policies/$PolicyId" 26 | $resp = Invoke-RestMethod -Method DELETE -Uri $url -Headers @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"} 27 | } 28 | 29 | # either try and use the tenant name passed or grab the tenant from current session 30 | <##> 31 | $tenantID = "" 32 | $resp = Invoke-RestMethod -Uri "https://login.windows.net/$TenantName/v2.0/.well-known/openid-configuration" 33 | $tenantID = $resp.authorization_endpoint.Split("/")[3] 34 | 35 | <##> 36 | if ( "" -eq $tenantID ) { 37 | write-host "Unknown Tenant" 38 | exit 2 39 | } 40 | write-host "Tenant: `t$tenantName`nTenantID:`t$tenantId" 41 | 42 | # check the B2C Graph App passed 43 | if ( $False -eq $isWinOS -or $True -eq $AzureCli ) { 44 | $app = (az ad app show --id $AppID | ConvertFrom-json) 45 | } else { 46 | $app = Get-AzureADApplication -Filter "AppID eq '$AppID'" 47 | } 48 | if ( $null -eq $app ) { 49 | write-host "App not found in B2C tenant: $AppID" 50 | exit 3 51 | } else { 52 | write-host "`Authenticating as App $($app.DisplayName), AppID $AppID" 53 | } 54 | <##> 55 | if ( "" -eq $PolicyPath ) { 56 | $PolicyPath = (get-location).Path 57 | } 58 | 59 | # https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/directory-assign-admin-roles#b2c-user-flow-administrator 60 | # get an access token for the B2C Graph App 61 | $oauthBody = @{grant_type="client_credentials";resource="https://graph.microsoft.com/";client_id=$AppID;client_secret=$AppKey;scope="Policy.ReadWrite.TrustFramework"} 62 | $oauth = Invoke-RestMethod -Method Post -Uri "https://login.microsoft.com/$tenantName/oauth2/token?api-version=1.0" -Body $oauthBody 63 | 64 | if ( "" -ne $PolicyFile ) { 65 | $PolicyData = Get-Content $PolicyFile # 66 | [xml]$xml = $PolicyData 67 | DeletePolicy $xml.TrustFrameworkPolicy.PolicyId 68 | } else { 69 | $files = get-childitem -path $PolicyPath -name -include *.xml | Where-Object {! $_.PSIsContainer } 70 | foreach( $file in $files ) { 71 | #write-output "Reading Policy XML file $file..." 72 | $PolicyFile = (Join-Path -Path $PolicyPath -ChildPath $file) 73 | $PolicyData = Get-Content $PolicyFile 74 | [xml]$xml = $PolicyData 75 | if ( $tenantName -ne $xml.TrustFrameworkPolicy.TenantId ) { 76 | write-warning $xml.TrustFrameworkPolicy.PublicPolicyUri " is not in the current tenant $tenantName" 77 | } else { 78 | DeletePolicy $xml.TrustFrameworkPolicy.PolicyId 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-download-starter-pack.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][Alias('p')][string]$PolicyPath = "", 3 | [Parameter(Mandatory=$false)][Alias('b')][string]$PolicyType = "SocialAndLocalAccounts" 4 | ) 5 | 6 | [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls" 7 | 8 | $urlStarterPackBase = "https://raw.githubusercontent.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/master" #/SocialAndLocalAccounts/TrustFrameworkBase.xml 9 | 10 | function DownloadFile ( $Url, $LocalPath ) { 11 | $p = $Url -split("/") 12 | $filename = $p[$p.Length-1] 13 | $LocalFile = "$LocalPath/$filename" 14 | Write-Host "Downloading $Url to $LocalFile" 15 | $webclient = New-Object System.Net.WebClient 16 | $webclient.DownloadFile($Url,$LocalFile) 17 | } 18 | 19 | if ( "" -eq $PolicyPath ) { 20 | $PolicyPath = (get-location).Path 21 | } 22 | DownloadFile "$urlStarterPackBase/$PolicyType/TrustFrameworkBase.xml" $PolicyPath 23 | DownloadFile "$urlStarterPackBase/$PolicyType/TrustFrameworkExtensions.xml" $PolicyPath 24 | DownloadFile "$urlStarterPackBase/$PolicyType/SignUpOrSignin.xml" $PolicyPath 25 | DownloadFile "$urlStarterPackBase/$PolicyType/PasswordReset.xml" $PolicyPath 26 | DownloadFile "$urlStarterPackBase/$PolicyType/ProfileEdit.xml" $PolicyPath 27 | -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-env.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][Alias('t')][string]$TenantName = "", 3 | [Parameter(Mandatory=$false)][Alias('p')][string]$PolicyPath = "", 4 | [Parameter(Mandatory=$false)][Alias('n')][string]$PolicyPrefix = "", 5 | [Parameter(Mandatory=$false)][Alias('k')][boolean]$KeepPolicyIds = $False, 6 | [Parameter(Mandatory=$false)][Alias('c')][string]$ConfigPath = "" 7 | ) 8 | 9 | if ( $env:PATH -imatch "/usr/bin" ) { # Mac/Linux 10 | $isWinOS = $false 11 | } else { 12 | $isWinOS = $true 13 | } 14 | 15 | if ( "" -eq $PolicyPath ) { 16 | $PolicyPath = (get-location).Path 17 | } 18 | if ( "" -eq $ConfigPath ) { 19 | $ConfigPath = "$PolicyPath\b2cAppSettings.json" 20 | } 21 | if ( "" -eq $PolicyPrefix -and $True -ne $KeepPolicyIds ) { 22 | $PolicyPrefix = (Get-Item -Path ".\").Name 23 | } 24 | $global:PolicyPath = $PolicyPath 25 | $global:PolicyPrefix = $PolicyPrefix 26 | $global:ConfigPath = $ConfigPath 27 | $global:b2cAppSettings =(Get-Content -Path $ConfigPath | ConvertFrom-json) 28 | $global:InstrumentationKey=$b2cAppSettings.InstrumentationKey 29 | 30 | $env:B2CAppId=$b2cAppSettings.ClientCredentials.client_id 31 | $env:B2CAppKey=$b2cAppSettings.ClientCredentials.client_secret 32 | $global:B2CAppId=$b2cAppSettings.ClientCredentials.client_id 33 | $global:B2CAppKey=$b2cAppSettings.ClientCredentials.client_secret 34 | 35 | if ( $null -ne $b2cAppSettings.AzureStorageAccount ) { 36 | $global:uxStorageAccount=$b2cAppSettings.AzureStorageAccount.AccountName 37 | $global:uxStorageAccountKey=$b2cAppSettings.AzureStorageAccount.AccountKey 38 | $global:uxTemplateLocation= "$($b2cAppSettings.AzureStorageAccount.ContainerName)/$($b2cAppSettings.AzureStorageAccount.Path)/" + $PolicyPrefix.ToLower() 39 | $global:EndpointSuffix=$b2cAppSettings.AzureStorageAccount.EndpointSuffix 40 | $global:storageConnectString="DefaultEndpointsProtocol=https;AccountName=$uxStorageAccount;AccountKey=$uxStorageAccountKey;EndpointSuffix=$EndpointSuffix" 41 | } 42 | 43 | if ( "" -eq $TenantName ) { 44 | $TenantName = $b2cAppSettings.TenantName 45 | } 46 | 47 | if ( $False -eq $isWinOS -or $True -eq $AzureCli ) { 48 | try { 49 | $tenant = (az account show | ConvertFrom-json) 50 | } catch { 51 | write-output "Not logged in to a B2C tenant.`n Please run az cli -t {tenantId} or `n$PSScriptRoot\aadb2c-login.ps1 -t `"yourtenant`"`n`n" 52 | exit 1 53 | } 54 | if ( !($TenantName -imatch ".onmicrosoft.com") ) { 55 | $TenantName = $TenantName + ".onmicrosoft.com" 56 | } 57 | $resp = Invoke-RestMethod -Uri "https://login.windows.net/$TenantName/v2.0/.well-known/openid-configuration" 58 | $tenantID = $resp.authorization_endpoint.Split("/")[3] 59 | } else { 60 | try { 61 | $tenant = Get-AzureADTenantDetail 62 | } catch { 63 | write-output "Not logged in to a B2C tenant.`n Please run Connect-AzAccount -t {tenantId} or `n$PSScriptRoot\aadb2c-login.ps1 -t `"yourtenant`"`n`n" 64 | exit 1 65 | } 66 | if ( $tenantName -ne $tenant.VerifiedDomains[0].Name) { 67 | write-output "Logged in to the wrong B2C tenant.`nTarget:`t$TenantName`nLogged in to:`t$($tenant.VerifiedDomains[0].Name)`n`n" 68 | exit 1 69 | } 70 | $tenantName = $tenant.VerifiedDomains[0].Name 71 | $tenantID = $tenant.ObjectId 72 | } 73 | $global:tenantName = $tenantName 74 | $global:tenantID = $tenantID 75 | 76 | write-output "Config File :`t$ConfigPath" 77 | write-output "B2C Tenant :`t$tenantID, $tenantName" 78 | write-output "B2C Client Cred:`t$($env:B2CAppId), $($app.DisplayName)" 79 | write-output "Policy Prefix :`t$PolicyPrefix" 80 | 81 | 82 | -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-init.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$true)][Alias('c')][string]$ConfigPath 3 | ) 4 | 5 | $global:b2cAppSettings =(Get-Content -Path $ConfigPath | ConvertFrom-json) 6 | 7 | & $PSScriptRoot\aadb2c-login.ps1 -t $b2cAppSettings.TenantName 8 | 9 | & $PSScriptRoot\aadb2c-env.ps1 -ConfigPath $ConfigPath 10 | -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-login.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][Alias('t')][string]$Tenant = "", 3 | [Parameter(Mandatory=$false)][boolean]$AzureCli = $False # if to force Azure CLI on Windows 4 | ) 5 | 6 | if ( $env:PATH -imatch "/usr/bin" ) { # Mac/Linux 7 | $isWinOS = $false 8 | } else { 9 | $isWinOS = $true 10 | } 11 | if ( $Tenant.Length -eq 36 -and $Tenant.Contains("-") -eq $true) { 12 | $TenantID = $Tenant 13 | } else { 14 | if ( !($Tenant -imatch ".onmicrosoft.com") ) { 15 | $Tenant = $Tenant + ".onmicrosoft.com" 16 | } 17 | $url = "https://login.windows.net/$Tenant/v2.0/.well-known/openid-configuration" 18 | $resp = Invoke-RestMethod -Uri $url 19 | $TenantID = $resp.authorization_endpoint.Split("/")[3] 20 | write-output $TenantID 21 | } 22 | 23 | $startTime = Get-Date 24 | 25 | if ( $False -eq $isWinOS -or $True -eq $AzureCli ) { 26 | $ctx = (az login --tenant $Tenant --allow-no-subscriptions | ConvertFrom-json) 27 | $Tenant = $ctx[0].tenantId 28 | $user = $ctx[0].user.name 29 | $type = "CLI" 30 | } else { # Windows 31 | $ctx = Connect-AzureAD -tenantid $TenantID 32 | $Tenant = $ctx.TenantDomain 33 | $user = $ctx.Account.Id 34 | $type = "" 35 | } 36 | 37 | $finishTime = Get-Date 38 | $TotalTime = ($finishTime - $startTime).TotalSeconds 39 | Write-Output "Time: $TotalTime sec(s)" 40 | 41 | write-output $ctx 42 | 43 | $host.ui.RawUI.WindowTitle = "PS AAD $type - $user - $Tenant" 44 | -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-policy-key-create.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][Alias('t')][string]$TenantName = "", 3 | [Parameter(Mandatory=$false)][Alias('a')][string]$AppID = "", # App reg in B2C that has permissions to create policy keys 4 | [Parameter(Mandatory=$false)][Alias('k')][string]$AppKey = "", # 5 | [Parameter(Mandatory=$true)][Alias('n')][string]$KeyContainerName = "", # [B2C_1A_]Name 6 | [Parameter(Mandatory=$true)][Alias('y')][string]$KeyType = "secret", # RSA, secret 7 | [Parameter(Mandatory=$true)][Alias('u')][string]$KeyUse = "sig", # sig, enc 8 | [Parameter(Mandatory=$false)][Alias('s')][string]$Secret = "" # used when $KeyType==secret 9 | ) 10 | 11 | $oauth = $null 12 | if ( "" -eq $AppID ) { $AppID = $env:B2CAppId } 13 | if ( "" -eq $AppKey ) { $AppKey = $env:B2CAppKey } 14 | $KeyType = $KeyType.ToLower() 15 | $KeyUse = $KeyUse.ToLower() 16 | 17 | if ( !("rsa" -eq $KeyType -or "secret" -eq $KeyType ) ) { 18 | write-output "KeyType must be RSA or secret" 19 | exit 1 20 | } 21 | if ( !("sig" -eq $KeyUse -or "enc" -eq $KeyUse ) ) { 22 | write-output "KeyUse must be sig(nature) or enc(ryption)" 23 | exit 1 24 | } 25 | if ( $false -eq $KeyContainerName.StartsWith("B2C_1A_") ) { 26 | $KeyContainerName = "B2C_1A_$KeyContainerName" 27 | } 28 | 29 | if ( "" -eq $TenantName ) { 30 | write-host "Getting Tenant info..." 31 | $tenant = Get-AzureADTenantDetail 32 | if ( $null -eq $tenant ) { 33 | write-host "Not logged in to a B2C tenant" 34 | exit 1 35 | } 36 | $tenantName = $tenant.VerifiedDomains[0].Name 37 | $tenantID = $tenant.ObjectId 38 | } else { 39 | if ( !($TenantName -imatch ".onmicrosoft.com") ) { 40 | $TenantName = $TenantName + ".onmicrosoft.com" 41 | } 42 | $resp = Invoke-RestMethod -Uri "https://login.windows.net/$TenantName/v2.0/.well-known/openid-configuration" 43 | $tenantID = $resp.authorization_endpoint.Split("/")[3] 44 | } 45 | 46 | $oauthBody = @{grant_type="client_credentials";resource="https://graph.microsoft.com/";client_id=$AppID;client_secret=$AppKey;scope="TrustFrameworkKeySet.Read.All,TrustFrameworkKeySet.ReadWrite.All"} 47 | $oauth = Invoke-RestMethod -Method Post -Uri "https://login.microsoft.com/$tenantName/oauth2/token?api-version=1.0" -Body $oauthBody 48 | <##> 49 | $url = "https://graph.microsoft.com/beta/trustFramework/keySets" 50 | 51 | try { 52 | $resp = Invoke-RestMethod -Method GET -Uri "$url/$KeyContainerName" -Headers @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"} -ErrorAction SilentlyContinue 53 | write-output "$($resp.id) already has $($resp.keys.Length) keys" 54 | exit 0 55 | } catch { 56 | } 57 | $body = @" 58 | { 59 | "id": "$KeyContainerName" 60 | } 61 | "@ 62 | $resp = Invoke-RestMethod -Method POST -Uri $url -Headers @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"} -Body $body -ContentType "application/json" -ErrorAction SilentlyContinue 63 | <##> 64 | if ( "secret" -eq $KeyType ) { 65 | $url = "https://graph.microsoft.com/beta/trustFramework/keySets/$KeyContainerName/uploadSecret" 66 | $body = @" 67 | { 68 | "use": "$KeyUse", 69 | "k": "$Secret" 70 | } 71 | "@ 72 | } 73 | if ( "rsa" -eq $KeyType ) { 74 | $url = "https://graph.microsoft.com/beta/trustFramework/keySets/$KeyContainerName/generateKey" 75 | $body = @" 76 | { 77 | "use": "$KeyUse", 78 | "kty": "RSA", 79 | } 80 | "@ 81 | } 82 | 83 | $resp = Invoke-RestMethod -Method POST -Uri $url -Headers @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"} -Body $body -ContentType "application/json" 84 | write-output "key created: $KeyContainerName" -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-prep-starter-pack.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][Alias('t')][string]$TenantName = "", 3 | [Parameter(Mandatory=$false)][Alias('p')][string]$PolicyPath = "", 4 | [Parameter(Mandatory=$false)][Alias('x')][string]$PolicyPrefix = "", 5 | [Parameter(Mandatory=$false)][Alias('b')][string]$PolicyType = "SocialAndLocalAccounts", 6 | [Parameter(Mandatory=$false)][string]$IefAppName = "IdentityExperienceFramework", 7 | [Parameter(Mandatory=$false)][string]$IefProxyAppName = "ProxyIdentityExperienceFramework" 8 | ) 9 | 10 | & $PSScriptRoot\aadb2c-download-starter-pack.ps1 -p $PolicyPath -b $PolicyType 11 | 12 | & $PSScriptRoot\aadb2c-policy-set-tenant.ps1 -t $TenantName -p $PolicyPath -x $PolicyPrefix ` 13 | -IefAppName $IefAppName -IefProxyAppName $IefProxyAppName -ExtAppDisplayName $ExtAppDisplayName 14 | -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-run-policy-saml.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$true)][Alias('p')][string]$PolicyFile, 3 | [Parameter(Mandatory=$true)][Alias('n')][string]$WebAppName = "", 4 | [Parameter(Mandatory=$false)][Alias('i')][string]$Issuer = "", 5 | [Parameter(Mandatory=$false)][boolean]$AzureCli = $False # if to force Azure CLI on Windows 6 | ) 7 | 8 | if (!(Test-Path $PolicyFile -PathType leaf)) { 9 | write-error "File does not exists: $PolicyFile" 10 | exit 1 11 | } 12 | if ( $env:PATH -imatch "/usr/bin" ) { # Mac/Linux 13 | $isWinOS = $false 14 | } else { 15 | $isWinOS = $true 16 | } 17 | 18 | [xml]$xml = Get-Content $PolicyFile 19 | $PolicyId = $xml.TrustFrameworkPolicy.PolicyId 20 | $tenantName = $xml.TrustFrameworkPolicy.TenantId 21 | 22 | if ( "SAML2"-ne $xml.TrustFrameworkPolicy.RelyingParty.TechnicalProfile.Protocol.Name ) { 23 | write-error "This is not a SAML 2 protocol policy" 24 | exit 2 25 | } 26 | 27 | write-host "Getting test app $WebAppName" 28 | if ( $False -eq $isWinOS -or $True -eq $AzureCli ) { 29 | $app = (az ad app list --display-name $WebAppName | ConvertFrom-json) 30 | } else { 31 | $app = Get-AzureADApplication -SearchString $WebAppName -ErrorAction SilentlyContinue 32 | } 33 | 34 | if ( $null -eq $app ) { 35 | write-error "App isn't registered: $WebAppName" 36 | exit 1 37 | } 38 | if ( $app.Count -gt 1 ) { 39 | $app = ($app | where {$_.DisplayName -eq $WebAppName}) 40 | } 41 | if ( $app.Count -gt 1 ) { 42 | write-error "App name isn't unique: $WebAppName" 43 | exit 1 44 | } 45 | 46 | if ( $app.IdentifierUris.Count -gt 1 ) { 47 | $Issuer = ($app.IdentifierUris | where { $_ -imatch $tenantName }) 48 | } else { 49 | $Issuer = $app.IdentifierUris[0] 50 | } 51 | 52 | $url = "https://samltestapp4.azurewebsites.net/SP?Tenant={0}&Policy={1}&Issuer={2}" -f $tenantName, $PolicyId, $Issuer 53 | 54 | write-host "Starting Browser`n$url" 55 | 56 | if ( !$isWinOS) { 57 | $ret = [System.Diagnostics.Process]::Start("/usr/bin/open","$url") 58 | } else { 59 | $pgm = "chrome.exe" 60 | $params = "--incognito --new-window" 61 | # start with Firefox if installed as it has a good extension 'SAML tracer' 62 | if ( Test-Path "$env:ProgramFiles\Mozilla Firefox" ) { 63 | $pgm = "$env:ProgramFiles\Mozilla Firefox\firefox.exe" 64 | $params = "-private -new-window" 65 | } 66 | $ret = [System.Diagnostics.Process]::Start($pgm,"$params $url") 67 | } 68 | -------------------------------------------------------------------------------- /GettingStarted/old/aadb2c-run-policy.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$true)][Alias('p')][string]$PolicyFile, 3 | [Parameter(Mandatory=$true)][Alias('n')][string]$WebAppName = "", 4 | [Parameter(Mandatory=$false)][Alias('r')][string]$redirect_uri = "https://jwt.ms", 5 | [Parameter(Mandatory=$false)][Alias('s')][string]$scopes = "", 6 | [Parameter(Mandatory=$false)][boolean]$AzureCli = $False # if to force Azure CLI on Windows 7 | ) 8 | 9 | if (!(Test-Path $PolicyFile -PathType leaf)) { 10 | write-error "File does not exists: $PolicyFile" 11 | exit 1 12 | } 13 | if ( $env:PATH -imatch "/usr/bin" ) { # Mac/Linux 14 | $isWinOS = $false 15 | } else { 16 | $isWinOS = $true 17 | } 18 | 19 | [xml]$xml = Get-Content $PolicyFile 20 | $PolicyId = $xml.TrustFrameworkPolicy.PolicyId 21 | $tenantName = $xml.TrustFrameworkPolicy.TenantId 22 | 23 | $isSAML = $false 24 | if ( "SAML2"-ne $xml.TrustFrameworkPolicy.RelyingParty.TechnicalProfile.Protocol.Name ) { 25 | $isSAML = $false 26 | } else { 27 | $isSAML = $true 28 | } 29 | 30 | write-host "Getting test app $WebAppName" 31 | if ( $False -eq $isWinOS -or $True -eq $AzureCli ) { 32 | $app = (az ad app list --display-name $WebAppName | ConvertFrom-json) 33 | } else { 34 | $app = Get-AzureADApplication -SearchString $WebAppName -ErrorAction SilentlyContinue 35 | } 36 | 37 | if ( $null -eq $app ) { 38 | write-error "App isn't registered: $WebAppName" 39 | exit 1 40 | } 41 | if ( $app.Count -gt 1 ) { 42 | $app = ($app | where {$_.DisplayName -eq $WebAppName}) 43 | } 44 | if ( $app.Count -gt 1 ) { 45 | write-error "App name isn't unique: $WebAppName" 46 | exit 1 47 | } 48 | 49 | $pgm = "chrome.exe" 50 | $params = "--incognito --new-window" 51 | 52 | if ( $isSAML) { 53 | if ( $app.IdentifierUris.Count -gt 1 ) { 54 | $Issuer = ($app.IdentifierUris | where { $_ -imatch $tenantName }) 55 | } else { 56 | $Issuer = $app.IdentifierUris[0] 57 | } 58 | $url = "https://samltestapp4.azurewebsites.net/SP?Tenant={0}&Policy={1}&Issuer={2}" -f $tenantName, $PolicyId, $Issuer 59 | # start with Firefox if installed as it has a good extension 'SAML tracer' 60 | if ( Test-Path "$env:ProgramFiles\Mozilla Firefox" ) { 61 | $pgm = "$env:ProgramFiles\Mozilla Firefox\firefox.exe" 62 | $params = "-private -new-window" 63 | } 64 | } else { 65 | $scope = "openid" 66 | $response_type = "id_token" 67 | # if extra scopes passed on cmdline, then we will also ask for an access_token 68 | if ( "" -ne $scopes ) { 69 | $scope = "openid offline_access $scopes" 70 | $response_type = "id_token token" 71 | } 72 | $qparams = "client_id={0}&nonce={1}&redirect_uri={2}&scope={3}&response_type={4}&prompt=login&disable_cache=true" ` 73 | -f $app.AppId.ToString(), (New-Guid).Guid, $redirect_uri, $scope, $response_type 74 | # Q&D urlencode 75 | $qparams = $qparams.Replace(":","%3A").Replace("/","%2F").Replace(" ", "%20") 76 | 77 | $url = "https://{0}.b2clogin.com/{1}/{2}/oauth2/v2.0/authorize?{3}" -f $tenantName.Split(".")[0], $tenantName, $PolicyId, $qparams 78 | } 79 | 80 | write-host "Starting Browser`n$url" 81 | 82 | if ( !$isWinOS) { 83 | $ret = [System.Diagnostics.Process]::Start("/usr/bin/open","$url") 84 | } else { 85 | $ret = [System.Diagnostics.Process]::Start($pgm,"$params $url") 86 | } 87 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29709.97 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "B2CIEFSetupWeb", "B2CIEFSetupWeb\B2CIEFSetupWeb.csproj", "{E6B98823-2C3B-480F-A3BF-AEC21B0EEB43}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Identity.Web", "Microsoft.Identity.Web\Microsoft.Identity.Web.csproj", "{E5635F2D-C4FE-401F-A40F-87A2A3A0660C}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {E6B98823-2C3B-480F-A3BF-AEC21B0EEB43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {E6B98823-2C3B-480F-A3BF-AEC21B0EEB43}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {E6B98823-2C3B-480F-A3BF-AEC21B0EEB43}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {E6B98823-2C3B-480F-A3BF-AEC21B0EEB43}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {E5635F2D-C4FE-401F-A40F-87A2A3A0660C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {E5635F2D-C4FE-401F-A40F-87A2A3A0660C}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {E5635F2D-C4FE-401F-A40F-87A2A3A0660C}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {E5635F2D-C4FE-401F-A40F-87A2A3A0660C}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {704BAE5D-5389-4385-A973-F87B730D4721} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/B2CIEFSetupWeb.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | aspnet-B2CIEFSetupWeb-F4FD33E1-7440-427F-9D39-84B82B998693 6 | 0 7 | /subscriptions/b63a13ff-9687-48e5-83bc-81d818f8f12c/resourcegroups/b2ctools/providers/microsoft.insights/components/b2ciefsetupweb 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "16.0.0.0", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" 6 | } 7 | } -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace B2CIEFSetupWeb 7 | { 8 | public static class Constants 9 | { 10 | public static readonly string[] ReadWriteScopes = 11 | { 12 | "TrustFrameworkKeySet.ReadWrite.All", // write keys 13 | "Policy.ReadWrite.TrustFramework", // write IEF policies 14 | "Directory.AccessAsUser.All", // to create apps 15 | }; 16 | 17 | public static readonly string[] ReadOnlyScopes = 18 | { 19 | "TrustFrameworkKeySet.Read.All", 20 | "Policy.Read.All", 21 | "Directory.Read.All" 22 | }; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Models/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace B2CIEFSetupWeb.Models 4 | { 5 | public class ErrorViewModel 6 | { 7 | public string RequestId { get; set; } 8 | 9 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Models/SetupRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace B2CIEFSetupWeb.Models 9 | { 10 | public class SetupRequest 11 | { 12 | [Required] 13 | [MaxLength(256), MinLength(4)] 14 | [RegularExpression("^([a-zA-Z0-9]+)$", ErrorMessage = "Invalid tenant name")] 15 | [DisplayName("Your B2C domain name")] 16 | public string DomainName { get; set; } 17 | 18 | [Required] 19 | [DisplayName("Validate only (do not create)")] 20 | public bool ValidateOnly { get; set; } 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Models/SetupState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace B2CIEFSetupWeb.Models 7 | { 8 | public class SetupState 9 | { 10 | public SetupState() 11 | { 12 | Items = new List(); 13 | } 14 | public string ConsentUrl { get; set; } 15 | public List Items { get; set; } 16 | } 17 | public class ItemSetupState 18 | { 19 | public string Name; 20 | public string Id; 21 | public string Status; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace B2CIEFSetupWeb 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:64619", 7 | "sslPort": 44301 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "B2CIEFSetupWeb": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model SetupRequest 2 | @{ 3 | ViewData["Title"] = "Home Page"; 4 | } 5 | 6 |
7 |

Welcome

8 |
9 |
10 |

11 | This app can be used to populate your AzureAD B2C tenant with objects needed for developing 12 | custom Identity Experience Framework policies. 13 |

14 |

Basic operation:

15 |
    16 |
  1. Enter your B2C domain name
  2. 17 |
  3. You will be asked to signin. Make sure to sign in with an account with admin rights to the B2C tenant. At this stage, do not use an MSA 18 | account to sign in. Use only work/school or local (to the B2C tenant: xyz@tenant.onmicrosoft.com) account.
  4. 19 |
  5. 20 | You will asked to consent to a number of permissions needed to create applications, service principals and security keys in your tenant. 21 | You will need to consent for the app to complete the setup. 22 |
  6. 23 |
  7. The application will verify existence of or create the two applications and signing/encryption keys as per above document
  8. 24 |
  9. The application will display the names, guids and status of the objects once completed.
  10. 25 |
  11. The application will not create the Facebook IdP provider used by some starter policies. Follow this document if you need it.
  12. 26 |
27 |
28 | 29 |

.onmicrosoft.com

30 |

31 |

32 | 33 |
34 |
35 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Home/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Privacy Policy"; 3 | } 4 |

@ViewData["Title"]

5 | 6 |

This application uses authentication tokens and cookies to execute its functionality using 7 | you B2C tenant. No data is persisted beyond that need.

8 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Home/Setup.cshtml: -------------------------------------------------------------------------------- 1 | @model SetupState 2 | @{ 3 | ViewData["Title"] = "Setup results"; 4 | } 5 | 6 |
7 |

Setup results

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | @foreach (var d in Model.Items) 16 | { 17 | 18 | 19 | 20 | 21 | 22 | } 23 |
NameIdStatus
@d.Name@d.Id@d.Status
24 |
25 |
26 |

The above IEF applications (resource: IdentityExperienceFramework and client: ProxyIdentityExperienceFramework) need an admin consent before 27 | they can be used by IEF policies. You can provide this this consent through the Azure portal or by 28 | requesting an OIDC signin to the client app. You will be asked to sign in (make sure to use an admin account) and 29 | then consent to the IEF client app getting a token to the resource app. You will be then redirected to a non-existent page - client app 30 | has no valid reply url. You can ignore that - consent has already been recorded. 31 |

32 | 33 |

Use the following snippets with 34 | the PowerShell policy upload tool.

35 |

Json configuration file

36 |
37 | {
38 |     "ExtAppId": "@Model.Items[4].Id",
39 |     "ExtObjectId": "@Model.Items[5].Id"
40 | }
41 |         
42 |
43 |

Extensions.xml claims provider source

44 |
45 | <DisplayName>Azure Active Directory</DisplayName>
46 |     <TechnicalProfiles>
47 |         <TechnicalProfile Id="AAD-Common">
48 |             <DisplayName>Azure Active Directory</DisplayName>
49 |             <Metadata>
50 |                 <Item Key="ApplicationObjectId">{ExtObjectId}</Item>
51 |                 <Item Key="ClientId">{ExtAppId}</Item>
52 |             </Metadata>
53 | 		</TechnicalProfile>
54 | 	</TechnicalProfiles>			
55 | </ClaimsProvider>
56 |         
57 |
58 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model ErrorViewModel 2 | @{ 3 | ViewData["Title"] = "Error"; 4 | } 5 | 6 |

Error.

7 |

An error occurred while processing your request.

8 | 9 | @if (Model.ShowRequestId) 10 | { 11 |

12 | Request ID: @Model.RequestId 13 |

14 | } 15 | 16 |

Development Mode

17 |

18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

20 |

21 | The Development environment shouldn't be enabled for deployed applications. 22 | It can result in displaying sensitive information from exceptions to end users. 23 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 24 | and restarting the app. 25 |

26 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet 2 | 3 | 4 | 5 | 6 | 7 | @ViewData["Title"] - B2CIEFSetupWeb 8 | 9 | 10 | @Html.Raw(JavaScriptSnippet.FullScript) 11 | 12 | 13 |
14 | 34 |
35 |
36 |
37 | @RenderBody() 38 |
39 |
40 | 41 |
42 |
43 | © 2020 - B2CIEFSetupWeb - Source code 44 |
45 |
46 | 47 | 48 | 49 | @RenderSection("Scripts", required: false) 50 | 51 | 52 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Shared/_LoginPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Security.Principal 2 | 3 | 20 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using B2CIEFSetupWeb 2 | @using B2CIEFSetupWeb.Models 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "AzureAd": { 3 | "Instance": "https://login.microsoftonline.com/", 4 | "Domain": "meraridom.onmicrosoft.com", 5 | "TenantId": "common", 6 | "ClientId": "a1097063-b62a-41be-a0c8-a05cdde50187", 7 | "CallbackPath": "/signin-oidc", 8 | "SignedOutCallbackPath ": "/signout-callback-oidc" 9 | }, 10 | "Logging": { 11 | "LogLevel": { 12 | "Default": "Information", 13 | "Microsoft": "Warning", 14 | "Microsoft.Hosting.Lifetime": "Information" 15 | } 16 | }, 17 | "AllowedHosts": "*" 18 | } -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | /* Provide sufficient contrast against white background */ 11 | a { 12 | color: #0366d6; 13 | } 14 | 15 | .btn-primary { 16 | color: #fff; 17 | background-color: #1b6ec2; 18 | border-color: #1861ac; 19 | } 20 | 21 | .nav-pills .nav-link.active, .nav-pills .show > .nav-link { 22 | color: #fff; 23 | background-color: #1b6ec2; 24 | border-color: #1861ac; 25 | } 26 | 27 | /* Sticky footer styles 28 | -------------------------------------------------- */ 29 | html { 30 | font-size: 14px; 31 | } 32 | @media (min-width: 768px) { 33 | html { 34 | font-size: 16px; 35 | } 36 | } 37 | 38 | .border-top { 39 | border-top: 1px solid #e5e5e5; 40 | } 41 | .border-bottom { 42 | border-bottom: 1px solid #e5e5e5; 43 | } 44 | 45 | .box-shadow { 46 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 47 | } 48 | 49 | button.accept-policy { 50 | font-size: 1rem; 51 | line-height: inherit; 52 | } 53 | 54 | /* Sticky footer styles 55 | -------------------------------------------------- */ 56 | html { 57 | position: relative; 58 | min-height: 100%; 59 | } 60 | 61 | body { 62 | /* Margin bottom by footer height */ 63 | margin-bottom: 60px; 64 | } 65 | .footer { 66 | position: absolute; 67 | bottom: 0; 68 | width: 100%; 69 | white-space: nowrap; 70 | line-height: 60px; /* Vertically center the text there */ 71 | } 72 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azure-ad-b2c/Scripts/ba936150984b5a96e62c83932f3fe82d79172a92/IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/favicon.ico -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/AccountExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Identity.Client; 5 | using System.Security.Claims; 6 | 7 | namespace Microsoft.Identity.Web 8 | { 9 | /// 10 | /// Extension methods dealing with IAccount instances. 11 | /// 12 | public static class AccountExtensions 13 | { 14 | /// 15 | /// Creates the from the values found 16 | /// in an 17 | /// 18 | /// The IAccount instance 19 | /// A built from IAccount 20 | public static ClaimsPrincipal ToClaimsPrincipal(this IAccount account) 21 | { 22 | if (account != null) 23 | { 24 | return new ClaimsPrincipal( 25 | new ClaimsIdentity(new Claim[] 26 | { 27 | new Claim(ClaimConstants.Oid, account.HomeAccountId.ObjectId), 28 | new Claim(ClaimConstants.Tid, account.HomeAccountId.TenantId), 29 | new Claim(ClaimTypes.Upn, account.Username) 30 | }) 31 | ); 32 | } 33 | 34 | return null; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/ClaimConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.Identity.Web 5 | { 6 | /// 7 | /// Constants for claim types. 8 | /// 9 | public static class ClaimConstants 10 | { 11 | public const string Name = "name"; 12 | public const string ObjectId = "http://schemas.microsoft.com/identity/claims/objectidentifier"; 13 | public const string Oid = "oid"; 14 | public const string PreferredUserName = "preferred_username"; 15 | public const string TenantId = "http://schemas.microsoft.com/identity/claims/tenantid"; 16 | public const string Tid = "tid"; 17 | // Older scope claim 18 | public const string Scope = "http://schemas.microsoft.com/identity/claims/scope"; 19 | // Newer scope claim 20 | public const string Scp = "scp"; 21 | public const string Roles = "roles"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/ClaimsPrincipalFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Security.Claims; 5 | 6 | namespace Microsoft.Identity.Web 7 | { 8 | /// 9 | /// Factory class to create ClaimsPrincipal objects. 10 | /// 11 | public static class ClaimsPrincipalFactory 12 | { 13 | /// 14 | /// Instantiate a ClaimsPrincipal from an account objectId and tenantId. This can 15 | /// be useful when the Web app subscribes to another service on behalf of the user 16 | /// and then is called back by a notification where the user is identified by his tenant 17 | /// id and object id (like in Microsoft Graph Web Hooks) 18 | /// 19 | /// Tenant Id of the account 20 | /// Object Id of the account in this tenant ID 21 | /// A ClaimsPrincipal containing these two claims 22 | /// 23 | /// 24 | /// 25 | /// private async Task GetChangedMessagesAsync(IEnumerable<Notification> notifications) 26 | /// { 27 | /// foreach (var notification in notifications) 28 | /// { 29 | /// SubscriptionStore subscription = 30 | /// subscriptionStore.GetSubscriptionInfo(notification.SubscriptionId); 31 | /// HttpContext.User = ClaimsPrincipalExtension.FromTenantIdAndObjectId(subscription.TenantId, 32 | /// subscription.UserId); 33 | /// string accessToken = await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(scopes); 34 | /// 35 | /// 36 | public static ClaimsPrincipal FromTenantIdAndObjectId(string tenantId, string objectId) 37 | { 38 | return new ClaimsPrincipal( 39 | new ClaimsIdentity(new Claim[] 40 | { 41 | new Claim(ClaimConstants.Tid, tenantId), 42 | new Claim(ClaimConstants.Oid, objectId) 43 | }) 44 | ); 45 | } 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Microsoft.Identity.Web 6 | { 7 | /// 8 | /// Extension methods that don't fit in any other class 9 | /// 10 | public static class Extensions 11 | { 12 | /// Determines whether the specified string collection contains any. 13 | /// The search for. 14 | /// The string collection. 15 | /// 16 | /// true if the specified string collection contains any; otherwise, false. 17 | public static bool ContainsAny(this string searchFor, params string[] stringCollection) 18 | { 19 | foreach (string str in stringCollection) 20 | { 21 | if (searchFor.Contains(str)) 22 | return true; 23 | } 24 | 25 | return false; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/HttpContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using System.IdentityModel.Tokens.Jwt; 3 | 4 | namespace Microsoft.Identity.Web 5 | { 6 | public static class HttpContextExtensions 7 | { 8 | /// 9 | /// Keep the validated token associated with the Http request 10 | /// 11 | /// Http context 12 | /// Token to preserve after the token is validated so that 13 | /// it can be used in the actions 14 | public static void StoreTokenUsedToCallWebAPI(this HttpContext httpContext, JwtSecurityToken token) 15 | { 16 | httpContext.Items.Add("JwtSecurityTokenUsedToCallWebAPI", token); 17 | } 18 | 19 | /// 20 | /// Get the parsed information about the token used to call the Web API 21 | /// 22 | /// Http context associated with the current request 23 | /// used to call the Web API 24 | public static JwtSecurityToken GetTokenUsedToCallWebAPI(this HttpContext httpContext) 25 | { 26 | return httpContext.Items["JwtSecurityTokenUsedToCallWebAPI"] as JwtSecurityToken; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/InstanceDiscovery/IssuerConfigurationRetriever.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Microsoft.IdentityModel.Protocols; 8 | using Newtonsoft.Json; 9 | 10 | namespace Microsoft.Identity.Web.InstanceDiscovery 11 | { 12 | /// 13 | /// An implementation of IConfigurationRetriever geared towards Azure AD issuers metadata /> 14 | /// 15 | internal class IssuerConfigurationRetriever : IConfigurationRetriever 16 | { 17 | /// Retrieves a populated configuration given an address and an . 18 | /// Address of the discovery document. 19 | /// The to use to read the discovery document. 20 | /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. . 21 | /// 22 | /// address - Azure AD Issuer metadata address url is required 23 | /// or 24 | /// retriever - No metadata document retriever is provided 25 | public async Task GetConfigurationAsync(string address, IDocumentRetriever retriever, CancellationToken cancel) 26 | { 27 | if (string.IsNullOrEmpty(address)) 28 | throw new ArgumentNullException(nameof(address), $"Azure AD Issuer metadata address url is required"); 29 | 30 | if (retriever == null) 31 | throw new ArgumentNullException(nameof(retriever), $"No metadata document retriever is provided"); 32 | 33 | string doc = await retriever.GetDocumentAsync(address, cancel).ConfigureAwait(false); 34 | return JsonConvert.DeserializeObject(doc); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/InstanceDiscovery/IssuerMetadata.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using Newtonsoft.Json; 6 | 7 | namespace Microsoft.Identity.Web.InstanceDiscovery 8 | { 9 | /// 10 | /// Model class to hold information parsed from the Azure AD issuer endpoint 11 | /// 12 | internal class IssuerMetadata 13 | { 14 | /// 15 | /// Tenant discovery endpoint 16 | /// 17 | [JsonProperty(PropertyName = "tenant_discovery_endpoint")] 18 | public string TenantDiscoveryEndpoint { get; set; } 19 | 20 | /// 21 | /// API Version 22 | /// 23 | [JsonProperty(PropertyName = "api-version")] 24 | public string ApiVersion { get; set; } 25 | 26 | /// 27 | /// List of metadata associated with the endpoint 28 | /// 29 | [JsonProperty(PropertyName = "metadata")] 30 | public List Metadata { get; set; } 31 | } 32 | } -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/InstanceDiscovery/Metadata.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using Newtonsoft.Json; 6 | 7 | namespace Microsoft.Identity.Web.InstanceDiscovery 8 | { 9 | /// 10 | /// Model child class to hold alias information parsed from the Azure AD issuer endpoint. 11 | /// 12 | internal class Metadata 13 | { 14 | /// 15 | /// Preferred alias 16 | /// 17 | [JsonProperty(PropertyName = "preferred_network")] 18 | public string PreferredNetwork { get; set; } 19 | 20 | /// 21 | /// Preferred alias to cache tokens emitted by one of the aliases (to avoid 22 | /// SSO islands) 23 | /// 24 | [JsonProperty(PropertyName = "preferred_cache")] 25 | public string PreferredCache { get; set; } 26 | 27 | /// 28 | /// Aliases of issuer URLs which are equivalent 29 | /// 30 | [JsonProperty(PropertyName = "aliases")] 31 | public List Aliases { get; set; } 32 | } 33 | } -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/InternalsVisibleTo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | [assembly: InternalsVisibleTo("Microsoft.Identity.Web.Test")] 7 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/Microsoft.Identity.Web.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 1.0.0-localbuild 6 | 7 | $(ClientSemVer) 8 | 9 | $(DefineConstants);WEB 10 | true 11 | Microsoft 12 | Microsoft 13 | This package enables ASP.NET Core Web apps and Web APIs to use the Microsoft identity platform (formerly Azure AD v2.0). When they call Web APIs, MSAL.NET is used to acquire tokens 14 | © Microsoft Corporation. All rights reserved. 15 | MIT 16 | https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet 17 | https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet 18 | Microsoft Authentication Library MSAL Azure Active Directory AAD Identity .NET ASP.NET Core 19 | 20 | 21 | 22 | true 23 | true 24 | 25 | true 26 | snupkg 27 | 28 | 29 | 30 | 31 | True 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | netcoreapp3.1 43 | 44 | 45 | 46 | 47 | Microsoft.Identity.Web.ruleset 48 | 49 | 50 | 51 | 52 | Microsoft.Identity.Web.ruleset 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/Microsoft.Identity.Web.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29009.5 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Identity.Web", "Microsoft.Identity.Web.csproj", "{BD795319-75B8-4251-AE92-8DD5A807C28E}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Identity.Web.Test", "..\Microsoft.Identity.Web.Test\Microsoft.Identity.Web.Test.csproj", "{9F00FB40-D67A-4E39-8167-C47922DA96A2}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {BD795319-75B8-4251-AE92-8DD5A807C28E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {BD795319-75B8-4251-AE92-8DD5A807C28E}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {BD795319-75B8-4251-AE92-8DD5A807C28E}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {BD795319-75B8-4251-AE92-8DD5A807C28E}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {9F00FB40-D67A-4E39-8167-C47922DA96A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {9F00FB40-D67A-4E39-8167-C47922DA96A2}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {9F00FB40-D67A-4E39-8167-C47922DA96A2}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {9F00FB40-D67A-4E39-8167-C47922DA96A2}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {F4FA8C4C-3251-41CC-939B-7892F5798549} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/OidcConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.Identity.Web 5 | { 6 | internal static class OidcConstants 7 | { 8 | public const string AdditionalClaims = "claims"; 9 | public const string ScopeOfflineAccess = "offline_access"; 10 | public const string ScopeProfile = "profile"; 11 | public const string ScopeOpenId = "openid"; 12 | } 13 | } -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/Resource/ScopesRequiredHttpContextExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License 3 | 4 | using Microsoft.AspNetCore.Http; 5 | using System; 6 | using System.Linq; 7 | using System.Net; 8 | using System.Net.Http; 9 | using System.Security.Claims; 10 | 11 | namespace Microsoft.Identity.Web.Resource 12 | { 13 | public static class ScopesRequiredHttpContextExtensions 14 | { 15 | /// 16 | /// When applied to an , verifies that the user authenticated in the 17 | /// web API has any of the accepted scopes. 18 | /// If the authentication user does not have any of these , the 19 | /// method throws an HTTP Unauthorized with the message telling which scopes are expected in the token 20 | /// 21 | /// Scopes accepted by this web API 22 | /// with a set to 23 | /// 24 | public static void VerifyUserHasAnyAcceptedScope(this HttpContext context, params string[] acceptedScopes) 25 | { 26 | if (acceptedScopes == null) 27 | { 28 | throw new ArgumentNullException(nameof(acceptedScopes)); 29 | } 30 | Claim scopeClaim = context?.User?.FindFirst("http://schemas.microsoft.com/identity/claims/scope"); 31 | if (scopeClaim == null || !scopeClaim.Value.Split(' ').Intersect(acceptedScopes).Any()) 32 | { 33 | context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 34 | string message = $"The 'scope' claim does not contain scopes '{string.Join(",", acceptedScopes)}' or was not found"; 35 | throw new HttpRequestException(message); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Extensions.DependencyInjection; 5 | using System.Runtime.CompilerServices; 6 | 7 | [assembly: InternalsVisibleTo("TokenCache.Tests.Core")] 8 | 9 | namespace Microsoft.Identity.Web 10 | { 11 | /// 12 | /// Extensions for IServiceCollection for startup initialization of Web APIs. 13 | /// 14 | public static class ServiceCollectionExtensions 15 | { 16 | /// 17 | /// Add the token acquisition service. 18 | /// 19 | /// Service collection 20 | /// the service collection 21 | /// 22 | /// This method is typically called from the Startup.ConfigureServices(IServiceCollection services) 23 | /// Note that the implementation of the token cache can be chosen separately. 24 | /// 25 | /// 26 | /// // Token acquisition service and its cache implementation as a session cache 27 | /// services.AddTokenAcquisition() 28 | /// .AddDistributedMemoryCache() 29 | /// .AddSession() 30 | /// .AddSessionBasedTokenCache() 31 | /// ; 32 | /// 33 | /// 34 | public static IServiceCollection AddTokenAcquisition(this IServiceCollection services) 35 | { 36 | // Token acquisition service 37 | services.AddHttpContextAccessor(); 38 | services.AddScoped(); 39 | return services; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/Distributed/DistributedTokenCacheAdapterExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace Microsoft.Identity.Web.TokenCacheProviders.Distributed 7 | { 8 | /// 9 | /// Extension class used to add an in-memory token cache serializer to MSAL 10 | /// 11 | public static class DistributedTokenCacheAdapterExtension 12 | { 13 | /// Adds both the app and per-user in-memory token caches. 14 | /// The services collection to add to. 15 | /// The MSALMemoryTokenCacheOptions allows the caller to set the token cache expiration 16 | /// 17 | public static IServiceCollection AddDistributedTokenCaches( 18 | this IServiceCollection services) 19 | { 20 | AddDistributedAppTokenCache(services); 21 | AddDistributedUserTokenCache(services); 22 | return services; 23 | } 24 | 25 | /// Adds the in-memory based application token cache to the service collection. 26 | /// The services collection to add to. 27 | /// The MSALMemoryTokenCacheOptions allows the caller to set the token cache expiration 28 | public static IServiceCollection AddDistributedAppTokenCache( 29 | this IServiceCollection services) 30 | { 31 | services.AddDistributedMemoryCache(); 32 | services.AddSingleton(); 33 | return services; 34 | } 35 | 36 | /// Adds the in-memory based per user token cache to the service collection. 37 | /// The services collection to add to. 38 | /// The MSALMemoryTokenCacheOptions allows the caller to set the token cache expiration 39 | /// 40 | public static IServiceCollection AddDistributedUserTokenCache( 41 | this IServiceCollection services) 42 | { 43 | services.AddDistributedMemoryCache(); 44 | services.AddHttpContextAccessor(); 45 | services.AddSingleton(); 46 | return services; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/Distributed/MsalDistributedTokenCacheAdapter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Authentication.AzureAD.UI; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.Extensions.Caching.Distributed; 8 | using Microsoft.Extensions.Caching.Memory; 9 | using Microsoft.Extensions.Options; 10 | 11 | namespace Microsoft.Identity.Web.TokenCacheProviders.Distributed 12 | { 13 | /// 14 | /// An implementation of token cache for both Confidential and Public clients backed by MemoryCache. 15 | /// 16 | /// 17 | public class MsalDistributedTokenCacheAdapter : MsalAbstractTokenCacheProvider 18 | { 19 | /// 20 | /// .NET Core Memory cache 21 | /// 22 | private readonly IDistributedCache _distributedCache; 23 | 24 | /// 25 | /// Msal memory token cache options 26 | /// 27 | private readonly DistributedCacheEntryOptions _cacheOptions; 28 | 29 | /// 30 | /// Constructor 31 | /// 32 | /// 33 | /// 34 | /// 35 | /// 36 | public MsalDistributedTokenCacheAdapter(IOptions azureAdOptions, 37 | IHttpContextAccessor httpContextAccessor, 38 | IDistributedCache memoryCache, 39 | IOptions cacheOptions) : 40 | base(azureAdOptions, httpContextAccessor) 41 | { 42 | _distributedCache = memoryCache; 43 | _cacheOptions = cacheOptions.Value; 44 | } 45 | 46 | protected override async Task RemoveKeyAsync(string cacheKey) 47 | { 48 | await _distributedCache.RemoveAsync(cacheKey).ConfigureAwait(false); 49 | } 50 | 51 | protected override async Task ReadCacheBytesAsync(string cacheKey) 52 | { 53 | return await _distributedCache.GetAsync(cacheKey).ConfigureAwait(false); 54 | } 55 | 56 | protected override async Task WriteCacheBytesAsync(string cacheKey, byte[] bytes) 57 | { 58 | await _distributedCache.SetAsync(cacheKey, bytes, _cacheOptions).ConfigureAwait(false) ; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/IMsalTokenCacheProvider .cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Identity.Client; 5 | using System.Threading.Tasks; 6 | 7 | namespace Microsoft.Identity.Web.TokenCacheProviders 8 | { 9 | /// 10 | /// MSAL token cache provider interface. 11 | /// 12 | public interface IMsalTokenCacheProvider 13 | { 14 | /// 15 | /// Initializes a token cache (which can be a user token cache or an app token cache) 16 | /// 17 | /// Token cache for which to initialize the serialization 18 | /// 19 | Task InitializeAsync(ITokenCache tokenCache); 20 | 21 | /// 22 | /// Clear the cache 23 | /// 24 | /// 25 | Task ClearAsync(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/InMemory/InMemoryTokenCacheProviderExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace Microsoft.Identity.Web.TokenCacheProviders.InMemory 7 | { 8 | /// 9 | /// Extension class used to add an in-memory token cache serializer to MSAL 10 | /// 11 | public static class InMemoryTokenCacheProviderExtension 12 | { 13 | /// Adds both the app and per-user in-memory token caches. 14 | /// The services collection to add to. 15 | /// The MSALMemoryTokenCacheOptions allows the caller to set the token cache expiration 16 | /// 17 | public static IServiceCollection AddInMemoryTokenCaches( 18 | this IServiceCollection services) 19 | { 20 | services.AddMemoryCache(); 21 | services.AddHttpContextAccessor(); 22 | services.AddSingleton(); 23 | return services; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/InMemory/MsalMemoryTokenCacheOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Identity.Web.TokenCacheProviders.InMemory 7 | { 8 | /// 9 | /// MSAL's memory token cache options 10 | /// 11 | public class MsalMemoryTokenCacheOptions 12 | { 13 | /// 14 | /// Gets or sets the value of the duration after which the cache entry will expire unless it's used 15 | /// This is the duration till the tokens are kept in memory cache. 16 | /// In production, a higher value , up-to 90 days is recommended. 17 | /// 18 | /// 19 | /// The SlidingExpiration value. 20 | /// 21 | public TimeSpan SlidingExpiration 22 | { 23 | get; 24 | set; 25 | } 26 | 27 | /// Initializes a new instance of the class. 28 | /// By default, the sliding expiration is set for 14 days. 29 | public MsalMemoryTokenCacheOptions() 30 | { 31 | this.SlidingExpiration = TimeSpan.FromDays(14); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /IEFTenantSetup/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/InMemory/MsalMemoryTokenCacheProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Authentication.AzureAD.UI; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.Extensions.Caching.Memory; 8 | using Microsoft.Extensions.Options; 9 | 10 | namespace Microsoft.Identity.Web.TokenCacheProviders.InMemory 11 | { 12 | /// 13 | /// An implementation of token cache for both Confidential and Public clients backed by MemoryCache. 14 | /// 15 | /// 16 | public class MsalMemoryTokenCacheProvider : MsalAbstractTokenCacheProvider 17 | { 18 | /// 19 | /// .NET Core Memory cache 20 | /// 21 | private readonly IMemoryCache _memoryCache; 22 | 23 | /// 24 | /// Msal memory token cache options 25 | /// 26 | private readonly MsalMemoryTokenCacheOptions _cacheOptions; 27 | 28 | /// 29 | /// Constructor 30 | /// 31 | /// 32 | /// 33 | /// 34 | /// 35 | public MsalMemoryTokenCacheProvider(IOptions azureAdOptions, 36 | IHttpContextAccessor httpContextAccessor, 37 | IMemoryCache memoryCache, 38 | IOptions cacheOptions) : 39 | base(azureAdOptions, httpContextAccessor) 40 | { 41 | _memoryCache = memoryCache; 42 | _cacheOptions = cacheOptions.Value; 43 | } 44 | 45 | protected override Task RemoveKeyAsync(string cacheKey) 46 | { 47 | _memoryCache.Remove(cacheKey); 48 | return Task.CompletedTask; 49 | } 50 | 51 | protected override Task ReadCacheBytesAsync(string cacheKey) 52 | { 53 | byte[] tokenCacheBytes = (byte[])_memoryCache.Get(cacheKey); 54 | return Task.FromResult(tokenCacheBytes); 55 | } 56 | 57 | protected override Task WriteCacheBytesAsync(string cacheKey, byte[] bytes) 58 | { 59 | _memoryCache.Set(cacheKey, bytes, _cacheOptions.SlidingExpiration); 60 | return Task.CompletedTask; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /IEFTenantSetup/README.md: -------------------------------------------------------------------------------- 1 | # B2C Identity Experience Framework - getting started 2 | 3 | ## Purpose 4 | Configures an existing B2C tenant for use with Identity Experience Framework custom policies. Performs all 5 | tasks defined in the [get started](https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-get-started?tabs=applications) 6 | document **except** [creating a Facebook signing key](https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-get-started?tabs=applications#create-the-facebook-key) 7 | required by some [starter policies](https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack). 8 | 9 | ## Usage 10 | The application is [deployed and ready to use](https://b2ciefsetup.azurewebsites.net): 11 | 1. Enter the name of your B2C tenant 12 | 2. Sign-in with an account with admin privileges in that tenant (account that was used to create the tenant has these by defualt) 13 | 3. AzureAD will ask you to consent to the application having the ability to create objects in your tenant (applications, keys) 14 | 4. Once you consent, the application will check whether your tenant has all the objects named in the [*Get started*](https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-get-started?tabs=applications) 15 | 5. If these objects, do not exists, the application will create them (2 applications, 2 service principals and two keys) 16 | 6. The final screen will display the relevant application ids needed in the IEF policies. 17 | 7. If the application did not exist already, the final screen will provide a url link you should use to complete 18 | admin consent for the new applications to use each other [item 9 in the Get started](https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-get-started?tabs=applications#register-the-proxyidentityexperienceframework-application) 19 | 8. You can use the Enterprise Apps option of the Azure portal's AAD blade to remove the B2CIEFSetup service principal 20 | from your tenant (optional). 21 | 22 | Once done, you can use some [PowerShell tools](https://github.com/mrochon/b2cief-upload) to prepare your policies, edit them 23 | using VS Code with the [B2C extension](https://github.com/azure-ad-b2c/vscode-extension) and upload them to the B2C tenant. 24 | 25 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29709.97 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "B2CIEFSetupWeb", "B2CIEFSetupWeb\B2CIEFSetupWeb.csproj", "{E6B98823-2C3B-480F-A3BF-AEC21B0EEB43}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Identity.Web", "Microsoft.Identity.Web\Microsoft.Identity.Web.csproj", "{E5635F2D-C4FE-401F-A40F-87A2A3A0660C}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {E6B98823-2C3B-480F-A3BF-AEC21B0EEB43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {E6B98823-2C3B-480F-A3BF-AEC21B0EEB43}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {E6B98823-2C3B-480F-A3BF-AEC21B0EEB43}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {E6B98823-2C3B-480F-A3BF-AEC21B0EEB43}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {E5635F2D-C4FE-401F-A40F-87A2A3A0660C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {E5635F2D-C4FE-401F-A40F-87A2A3A0660C}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {E5635F2D-C4FE-401F-A40F-87A2A3A0660C}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {E5635F2D-C4FE-401F-A40F-87A2A3A0660C}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {704BAE5D-5389-4385-A973-F87B730D4721} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "5.0.1", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/B2CIEFSetupWeb.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | aspnet-B2CIEFSetupWeb-F4FD33E1-7440-427F-9D39-84B82B998693 6 | 0 7 | /subscriptions/b63a13ff-9687-48e5-83bc-81d818f8f12c/resourcegroups/b2ctools/providers/microsoft.insights/components/b2ciefsetupweb 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "16.0.0.0" 4 | } -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace B2CIEFSetupWeb 7 | { 8 | public static class Constants 9 | { 10 | public static readonly string[] ReadWriteScopes = 11 | { 12 | "TrustFrameworkKeySet.ReadWrite.All", // write keys 13 | "Policy.ReadWrite.TrustFramework", // write IEF policies 14 | "Directory.AccessAsUser.All", // to create apps 15 | }; 16 | 17 | public static readonly string[] ReadOnlyScopes = 18 | { 19 | "TrustFrameworkKeySet.Read.All", 20 | "Policy.Read.All", 21 | "Directory.Read.All" 22 | }; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Models/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace B2CIEFSetupWeb.Models 4 | { 5 | public class ErrorViewModel 6 | { 7 | public string RequestId { get; set; } 8 | 9 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Models/SetupRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace B2CIEFSetupWeb.Models 9 | { 10 | public class SetupRequest 11 | { 12 | [Required] 13 | [MaxLength(256), MinLength(4)] 14 | [RegularExpression("^([a-zA-Z0-9]+)$", ErrorMessage = "Invalid tenant name")] 15 | [DisplayName("Your B2C domain name")] 16 | public string DomainName { get; set; } 17 | 18 | [Required] 19 | [DisplayName("Remove Facebook references")] 20 | public bool RemoveFacebookReferences { get; set; } 21 | [Required] 22 | [DisplayName("Deploy Phone SignIn Journeys")] 23 | public bool InitialisePhoneSignInJourneys{ get; set; } 24 | 25 | 26 | [Required] 27 | [DisplayName("Enable JavaScript")] 28 | public bool EnableJavaScript { get; set; } 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Models/SetupRequestPolicySample.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.ComponentModel.DataAnnotations; 7 | using System.Linq; 8 | using System.Net; 9 | using System.Net.Http; 10 | using System.Threading.Tasks; 11 | 12 | namespace B2CIEFSetupWeb.Models 13 | { 14 | public class SetupRequestPolicySample 15 | { 16 | 17 | 18 | [Required] 19 | [MaxLength(256), MinLength(4)] 20 | [RegularExpression("^([a-zA-Z0-9]+)$", ErrorMessage = "Invalid tenant name")] 21 | [DisplayName("Your B2C domain name")] 22 | public string DomainName { get; set; } 23 | 24 | [Required] 25 | [DisplayName("Sample Folder Name")] 26 | public string SampleName { get; set; } 27 | 28 | [DisplayName("Possible Sample Values")] 29 | public List SampleValues { get; set; } 30 | 31 | public class Samples 32 | { 33 | public string displayName; 34 | public string folderName; 35 | public string description; 36 | } 37 | public SetupRequestPolicySample() 38 | { 39 | SampleValues = new List(); 40 | HttpClient httpToRepoAPI = new HttpClient(); 41 | string urlToFetchPolices = "https://gitrepomanager.azurewebsites.net/api/FetchRepo/all"; //https://localhost:44358/api/FetchRepo/all, "https://gitrepomanager.azurewebsites.net/api/FetchRepo/all" 42 | //string urlToFetchPolices = "https://localhost:44358/api/FetchRepo/all"; 43 | var json = new WebClient().DownloadString(urlToFetchPolices); 44 | //var value = JArray.Parse(json); 45 | //var value = JObject.Parse(json); 46 | //Root myPolicyRows = JsonConvert.DeserializeObject(json); 47 | var myPolicyRows = PolicyRow.FromJson(json); 48 | foreach (var item in myPolicyRows) 49 | { 50 | Samples sample = new Samples(); 51 | sample.displayName = item.DisplayName; 52 | sample.folderName = item.FolderName; 53 | sample.description = item.Description; 54 | SampleValues.Add(sample); 55 | 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Models/SetupState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace B2CIEFSetupWeb.Models 7 | { 8 | public class SetupState 9 | { 10 | public SetupState() 11 | { 12 | Items = new List(); 13 | } 14 | public string ConsentUrl { get; set; } 15 | public string AppConsentUrl { get; set; } 16 | public string LaunchUrl { get; set; } 17 | public List Items { get; set; } 18 | } 19 | public class ItemSetupState 20 | { 21 | public string Name; 22 | public string Id; 23 | public string Status; 24 | public string Reason; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Models/UploadError.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace B2CIEFSetupWeb.Models 7 | { 8 | using System; 9 | using System.Collections.Generic; 10 | 11 | using System.Globalization; 12 | using Newtonsoft.Json; 13 | using Newtonsoft.Json.Converters; 14 | 15 | public class InnerError 16 | { 17 | public string correlationId { get; set; } 18 | public DateTime date { get; set; } 19 | 20 | [JsonProperty("request-id")] 21 | public string RequestId { get; set; } 22 | 23 | [JsonProperty("client-request-id")] 24 | public string ClientRequestId { get; set; } 25 | } 26 | 27 | public class Error 28 | { 29 | public string code { get; set; } 30 | public string message { get; set; } 31 | public InnerError innerError { get; set; } 32 | } 33 | 34 | public class UploadError 35 | { 36 | public Error error { get; set; } 37 | } 38 | 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Models/policyRow.cs: -------------------------------------------------------------------------------- 1 | namespace B2CIEFSetupWeb.Models 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | using System.Globalization; 7 | using Newtonsoft.Json; 8 | using Newtonsoft.Json.Converters; 9 | public partial class PolicyRow 10 | { 11 | public static PolicyRow[] FromJson(string json) => JsonConvert.DeserializeObject(json, B2CIEFSetupWeb.Models.Converter.Settings); 12 | } 13 | public static class Serialize 14 | { 15 | public static string ToJson(this PolicyRow[] self) => JsonConvert.SerializeObject(self, B2CIEFSetupWeb.Models.Converter.Settings); 16 | } 17 | 18 | internal static class Converter 19 | { 20 | public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings 21 | { 22 | MetadataPropertyHandling = MetadataPropertyHandling.Ignore, 23 | DateParseHandling = DateParseHandling.None, 24 | Converters = 25 | { 26 | new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } 27 | }, 28 | }; 29 | } 30 | public partial class PolicyRow 31 | { 32 | [JsonProperty("displayName")] 33 | public string DisplayName { get; set; } 34 | 35 | [JsonProperty("folderName")] 36 | public string FolderName { get; set; } 37 | 38 | [JsonProperty("description")] 39 | public string Description { get; set; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Models/sampleFolderBootstrap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace B2CIEFSetupWeb.Models 7 | { 8 | public class sampleFolderBootstrap 9 | { 10 | public string sampleFolderName { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace B2CIEFSetupWeb 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:64619", 7 | "sslPort": 44301 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "B2CIEFSetupWeb": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Home/Experimental.cshtml: -------------------------------------------------------------------------------- 1 | @model SetupRequestPolicySample 2 | @{ 3 | ViewData["Title"] = "Quick Deploy Samples"; 4 | var data = (sampleFolderBootstrap)ViewData["Message"]; 5 | } 6 |

Quick Deploy Samples

7 | 8 |

9 | This section will deploy a sample policy from the Azure AD B2C Samples GitHub to your Azure AD B2C directory. 10 | All supported samples for quick-deploy are listed in the table below. 11 |

12 | 13 |
    14 |
  • You must have run the initial setup before continuing with this page.
  • 15 | 16 |
  • 17 | You cannot use this to deploy any Policy Sample that relies on Policy Keys (External IdP's/REST API's), unless the Policy Keys already exist within the directory prior to deployment. 18 |
  • 19 |
  • 20 | You cannot use this to deploy any Policy Sample that relies on JavaScript page contracts (unless you've already enabled page contracts manually or via the Initial Setup). 21 |
  • 22 |
23 |

24 | If you believe you attempted to upload a sample which met these conditions, but did not upload successfully, 25 | raise an issue here. 26 |

27 | 28 |
29 | 30 | 31 | 32 | 33 |
34 | 35 |

.onmicrosoft.com

36 | 37 |

38 | 39 |
40 | 41 |
42 |

Possible sample values

43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | @foreach (var item in Model.SampleValues) 55 | { 56 | 57 | 58 | 59 | 60 | 61 | } 62 |
NameSample Folder NameDescription
@item.displayName@item.folderName@item.description
63 |
64 | 65 | 84 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Home/ExperimentalSetup.cshtml: -------------------------------------------------------------------------------- 1 | @model SetupState 2 | @{ 3 | ViewData["Title"] = "Experimental Setup results"; 4 | } 5 |
6 |

Setup results

7 |
8 | 9 | 10 |
11 |
12 |
13 |

Setup Report

14 | 15 |

16 | If you believe you attempted to upload a sample which met these conditions, but did not upload successfully, 17 | raise an issue here. 18 |

19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | @foreach (var d in Model.Items) 28 | { 29 | 30 | 31 | 32 | 33 | 34 | 35 | } 36 |
NameIdStatusReason
@d.Name@d.Id@d.Status@d.Reason
37 |
38 | 39 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Home/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Privacy Policy"; 3 | } 4 |

@ViewData["Title"]

5 | 6 |

This application is provided by Microsoft and uses authentication tokens and cookies to execute its functionality against 7 | your B2C tenant in the context of your user. No data is persisted within this application.

8 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Home/Setup.cshtml: -------------------------------------------------------------------------------- 1 | @model SetupState 2 | @{ 3 | ViewData["Title"] = "Setup results"; 4 | } 5 |
6 |

Setup results

7 |
8 |

To complete the setup

9 |

10 |

    11 |
  1. You must click this link for the setup to complete. It will provide Admin consent to enable your custom policies. You must login with your Global Administrator account. You will be then redirected to a "Page not found" error once it completes.
  2. 12 |
  3. You must click this link for the setup to complete. It will provide Admin consent to enable the IEF Test App. You must login with your Global Administrator account. You will be then redirected to a "Page not found" error once it completes.
  4. 13 |
  5. You can launch your custom policies from the Azure Portal. Test a Sign up and Sign In by running the B2C_1A_signup_signin policy.
  6. 14 |
15 | You can safely run this setup again if anything has failed in the setup report below. 16 |

17 | 18 |
19 |
20 |
21 |

Setup Report

22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | @foreach (var d in Model.Items) 30 | { 31 | 32 | 33 | 34 | 35 | 36 | 37 | } 38 |
NameIdStatusReason
@d.Name@d.Id@d.Status@d.Reason
39 |
40 | 41 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Home/Support.cshtml: -------------------------------------------------------------------------------- 1 |  2 | @{ 3 | ViewData["Title"] = "Support"; 4 | } 5 | 6 |

Support

7 | 8 |

9 | If you have trouble with this application, raise a Github issue here. 10 |

11 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model ErrorViewModel 2 | @{ 3 | ViewData["Title"] = "Error"; 4 | } 5 | 6 |

Error.

7 |

An error occurred while processing your request.

8 | 9 | @if (Model.ShowRequestId) 10 | { 11 |

12 | Request ID: @Model.RequestId 13 |

14 | } 15 | 16 |

Development Mode

17 |

18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

20 |

21 | The Development environment shouldn't be enabled for deployed applications. 22 | It can result in displaying sensitive information from exceptions to end users. 23 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 24 | and restarting the app. 25 |

26 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet 2 | 3 | 4 | 5 | 6 | 7 | @ViewData["Title"] - IEF Setup 8 | 9 | 10 | @Html.Raw(JavaScriptSnippet.FullScript) 11 | 12 | 13 |
14 | 41 |
42 |
43 |
44 | @RenderBody() 45 |
46 |
47 | 48 |
49 |
50 | © 2020 - Deploy AAD B2C Custom policies - Source code 51 |
52 |
53 | 54 | 55 | 56 | @RenderSection("Scripts", required: false) 57 | 58 | 59 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Shared/_LoginPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Security.Principal 2 | 3 | 20 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using B2CIEFSetupWeb 2 | @using B2CIEFSetupWeb.Models 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "AzureAd": { 3 | "Instance": "https://login.microsoftonline.com/", 4 | "Domain": "b2cprod.onmicrosoft.com", 5 | "TenantId": "common", 6 | "ClientId": "bd1556f2-dae2-42fc-862e-3c68787a27c3", 7 | "ClientSecret": "", 8 | "CallbackPath": "/signin-oidc", 9 | "SignedOutCallbackPath ": "/signout-callback-oidc" 10 | }, 11 | "Logging": { 12 | "LogLevel": { 13 | "Default": "Information", 14 | "Microsoft": "Warning", 15 | "Microsoft.Hosting.Lifetime": "Information" 16 | } 17 | }, 18 | "AllowedHosts": "*" 19 | } 20 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | /* Provide sufficient contrast against white background */ 11 | a { 12 | color: #0366d6; 13 | } 14 | 15 | .btn-primary { 16 | color: #fff; 17 | background-color: #1b6ec2; 18 | border-color: #1861ac; 19 | } 20 | 21 | .nav-pills .nav-link.active, .nav-pills .show > .nav-link { 22 | color: #fff; 23 | background-color: #1b6ec2; 24 | border-color: #1861ac; 25 | } 26 | 27 | /* Sticky footer styles 28 | -------------------------------------------------- */ 29 | html { 30 | font-size: 14px; 31 | } 32 | @media (min-width: 768px) { 33 | html { 34 | font-size: 16px; 35 | } 36 | } 37 | 38 | .border-top { 39 | border-top: 1px solid #e5e5e5; 40 | } 41 | .border-bottom { 42 | border-bottom: 1px solid #e5e5e5; 43 | } 44 | 45 | .box-shadow { 46 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 47 | } 48 | 49 | button.accept-policy { 50 | font-size: 1rem; 51 | line-height: inherit; 52 | } 53 | 54 | /* Sticky footer styles 55 | -------------------------------------------------- */ 56 | html { 57 | position: relative; 58 | min-height: 100%; 59 | } 60 | 61 | body { 62 | /* Margin bottom by footer height */ 63 | margin-bottom: 60px; 64 | } 65 | .footer { 66 | position: absolute; 67 | bottom: 0; 68 | width: 100%; 69 | white-space: nowrap; 70 | line-height: 60px; /* Vertically center the text there */ 71 | } 72 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azure-ad-b2c/Scripts/ba936150984b5a96e62c83932f3fe82d79172a92/IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/favicon.ico -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/B2CIEFSetupWeb/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/AccountExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Identity.Client; 5 | using System.Security.Claims; 6 | 7 | namespace Microsoft.Identity.Web 8 | { 9 | /// 10 | /// Extension methods dealing with IAccount instances. 11 | /// 12 | public static class AccountExtensions 13 | { 14 | /// 15 | /// Creates the from the values found 16 | /// in an 17 | /// 18 | /// The IAccount instance 19 | /// A built from IAccount 20 | public static ClaimsPrincipal ToClaimsPrincipal(this IAccount account) 21 | { 22 | if (account != null) 23 | { 24 | return new ClaimsPrincipal( 25 | new ClaimsIdentity(new Claim[] 26 | { 27 | new Claim(ClaimConstants.Oid, account.HomeAccountId.ObjectId), 28 | new Claim(ClaimConstants.Tid, account.HomeAccountId.TenantId), 29 | new Claim(ClaimTypes.Upn, account.Username) 30 | }) 31 | ); 32 | } 33 | 34 | return null; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/ClaimConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.Identity.Web 5 | { 6 | /// 7 | /// Constants for claim types. 8 | /// 9 | public static class ClaimConstants 10 | { 11 | public const string Name = "name"; 12 | public const string ObjectId = "http://schemas.microsoft.com/identity/claims/objectidentifier"; 13 | public const string Oid = "oid"; 14 | public const string PreferredUserName = "preferred_username"; 15 | public const string TenantId = "http://schemas.microsoft.com/identity/claims/tenantid"; 16 | public const string Tid = "tid"; 17 | // Older scope claim 18 | public const string Scope = "http://schemas.microsoft.com/identity/claims/scope"; 19 | // Newer scope claim 20 | public const string Scp = "scp"; 21 | public const string Roles = "roles"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/ClaimsPrincipalFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Security.Claims; 5 | 6 | namespace Microsoft.Identity.Web 7 | { 8 | /// 9 | /// Factory class to create ClaimsPrincipal objects. 10 | /// 11 | public static class ClaimsPrincipalFactory 12 | { 13 | /// 14 | /// Instantiate a ClaimsPrincipal from an account objectId and tenantId. This can 15 | /// be useful when the Web app subscribes to another service on behalf of the user 16 | /// and then is called back by a notification where the user is identified by his tenant 17 | /// id and object id (like in Microsoft Graph Web Hooks) 18 | /// 19 | /// Tenant Id of the account 20 | /// Object Id of the account in this tenant ID 21 | /// A ClaimsPrincipal containing these two claims 22 | /// 23 | /// 24 | /// 25 | /// private async Task GetChangedMessagesAsync(IEnumerable<Notification> notifications) 26 | /// { 27 | /// foreach (var notification in notifications) 28 | /// { 29 | /// SubscriptionStore subscription = 30 | /// subscriptionStore.GetSubscriptionInfo(notification.SubscriptionId); 31 | /// HttpContext.User = ClaimsPrincipalExtension.FromTenantIdAndObjectId(subscription.TenantId, 32 | /// subscription.UserId); 33 | /// string accessToken = await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(scopes); 34 | /// 35 | /// 36 | public static ClaimsPrincipal FromTenantIdAndObjectId(string tenantId, string objectId) 37 | { 38 | return new ClaimsPrincipal( 39 | new ClaimsIdentity(new Claim[] 40 | { 41 | new Claim(ClaimConstants.Tid, tenantId), 42 | new Claim(ClaimConstants.Oid, objectId) 43 | }) 44 | ); 45 | } 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Microsoft.Identity.Web 6 | { 7 | /// 8 | /// Extension methods that don't fit in any other class 9 | /// 10 | public static class Extensions 11 | { 12 | /// Determines whether the specified string collection contains any. 13 | /// The search for. 14 | /// The string collection. 15 | /// 16 | /// true if the specified string collection contains any; otherwise, false. 17 | public static bool ContainsAny(this string searchFor, params string[] stringCollection) 18 | { 19 | foreach (string str in stringCollection) 20 | { 21 | if (searchFor.Contains(str)) 22 | return true; 23 | } 24 | 25 | return false; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/HttpContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using System.IdentityModel.Tokens.Jwt; 3 | 4 | namespace Microsoft.Identity.Web 5 | { 6 | public static class HttpContextExtensions 7 | { 8 | /// 9 | /// Keep the validated token associated with the Http request 10 | /// 11 | /// Http context 12 | /// Token to preserve after the token is validated so that 13 | /// it can be used in the actions 14 | public static void StoreTokenUsedToCallWebAPI(this HttpContext httpContext, JwtSecurityToken token) 15 | { 16 | httpContext.Items.Add("JwtSecurityTokenUsedToCallWebAPI", token); 17 | } 18 | 19 | /// 20 | /// Get the parsed information about the token used to call the Web API 21 | /// 22 | /// Http context associated with the current request 23 | /// used to call the Web API 24 | public static JwtSecurityToken GetTokenUsedToCallWebAPI(this HttpContext httpContext) 25 | { 26 | return httpContext.Items["JwtSecurityTokenUsedToCallWebAPI"] as JwtSecurityToken; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/InstanceDiscovery/IssuerConfigurationRetriever.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Microsoft.IdentityModel.Protocols; 8 | using Newtonsoft.Json; 9 | 10 | namespace Microsoft.Identity.Web.InstanceDiscovery 11 | { 12 | /// 13 | /// An implementation of IConfigurationRetriever geared towards Azure AD issuers metadata /> 14 | /// 15 | internal class IssuerConfigurationRetriever : IConfigurationRetriever 16 | { 17 | /// Retrieves a populated configuration given an address and an . 18 | /// Address of the discovery document. 19 | /// The to use to read the discovery document. 20 | /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. . 21 | /// 22 | /// address - Azure AD Issuer metadata address url is required 23 | /// or 24 | /// retriever - No metadata document retriever is provided 25 | public async Task GetConfigurationAsync(string address, IDocumentRetriever retriever, CancellationToken cancel) 26 | { 27 | if (string.IsNullOrEmpty(address)) 28 | throw new ArgumentNullException(nameof(address), $"Azure AD Issuer metadata address url is required"); 29 | 30 | if (retriever == null) 31 | throw new ArgumentNullException(nameof(retriever), $"No metadata document retriever is provided"); 32 | 33 | string doc = await retriever.GetDocumentAsync(address, cancel).ConfigureAwait(false); 34 | return JsonConvert.DeserializeObject(doc); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/InstanceDiscovery/IssuerMetadata.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using Newtonsoft.Json; 6 | 7 | namespace Microsoft.Identity.Web.InstanceDiscovery 8 | { 9 | /// 10 | /// Model class to hold information parsed from the Azure AD issuer endpoint 11 | /// 12 | internal class IssuerMetadata 13 | { 14 | /// 15 | /// Tenant discovery endpoint 16 | /// 17 | [JsonProperty(PropertyName = "tenant_discovery_endpoint")] 18 | public string TenantDiscoveryEndpoint { get; set; } 19 | 20 | /// 21 | /// API Version 22 | /// 23 | [JsonProperty(PropertyName = "api-version")] 24 | public string ApiVersion { get; set; } 25 | 26 | /// 27 | /// List of metadata associated with the endpoint 28 | /// 29 | [JsonProperty(PropertyName = "metadata")] 30 | public List Metadata { get; set; } 31 | } 32 | } -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/InstanceDiscovery/Metadata.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using Newtonsoft.Json; 6 | 7 | namespace Microsoft.Identity.Web.InstanceDiscovery 8 | { 9 | /// 10 | /// Model child class to hold alias information parsed from the Azure AD issuer endpoint. 11 | /// 12 | internal class Metadata 13 | { 14 | /// 15 | /// Preferred alias 16 | /// 17 | [JsonProperty(PropertyName = "preferred_network")] 18 | public string PreferredNetwork { get; set; } 19 | 20 | /// 21 | /// Preferred alias to cache tokens emitted by one of the aliases (to avoid 22 | /// SSO islands) 23 | /// 24 | [JsonProperty(PropertyName = "preferred_cache")] 25 | public string PreferredCache { get; set; } 26 | 27 | /// 28 | /// Aliases of issuer URLs which are equivalent 29 | /// 30 | [JsonProperty(PropertyName = "aliases")] 31 | public List Aliases { get; set; } 32 | } 33 | } -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/InternalsVisibleTo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | [assembly: InternalsVisibleTo("Microsoft.Identity.Web.Test")] 7 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/Microsoft.Identity.Web.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 1.0.0-localbuild 6 | 7 | $(ClientSemVer) 8 | 9 | $(DefineConstants);WEB 10 | true 11 | Microsoft 12 | Microsoft 13 | This package enables ASP.NET Core Web apps and Web APIs to use the Microsoft identity platform (formerly Azure AD v2.0). When they call Web APIs, MSAL.NET is used to acquire tokens 14 | © Microsoft Corporation. All rights reserved. 15 | MIT 16 | https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet 17 | https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet 18 | Microsoft Authentication Library MSAL Azure Active Directory AAD Identity .NET ASP.NET Core 19 | 20 | 21 | 22 | true 23 | true 24 | 25 | true 26 | snupkg 27 | 28 | 29 | 30 | 31 | True 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | netcoreapp3.1 43 | 44 | 45 | 46 | 47 | Microsoft.Identity.Web.ruleset 48 | 49 | 50 | 51 | 52 | Microsoft.Identity.Web.ruleset 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/Microsoft.Identity.Web.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29009.5 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Identity.Web", "Microsoft.Identity.Web.csproj", "{BD795319-75B8-4251-AE92-8DD5A807C28E}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Identity.Web.Test", "..\Microsoft.Identity.Web.Test\Microsoft.Identity.Web.Test.csproj", "{9F00FB40-D67A-4E39-8167-C47922DA96A2}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {BD795319-75B8-4251-AE92-8DD5A807C28E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {BD795319-75B8-4251-AE92-8DD5A807C28E}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {BD795319-75B8-4251-AE92-8DD5A807C28E}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {BD795319-75B8-4251-AE92-8DD5A807C28E}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {9F00FB40-D67A-4E39-8167-C47922DA96A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {9F00FB40-D67A-4E39-8167-C47922DA96A2}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {9F00FB40-D67A-4E39-8167-C47922DA96A2}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {9F00FB40-D67A-4E39-8167-C47922DA96A2}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {F4FA8C4C-3251-41CC-939B-7892F5798549} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/OidcConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.Identity.Web 5 | { 6 | internal static class OidcConstants 7 | { 8 | public const string AdditionalClaims = "claims"; 9 | public const string ScopeOfflineAccess = "offline_access"; 10 | public const string ScopeProfile = "profile"; 11 | public const string ScopeOpenId = "openid"; 12 | } 13 | } -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/Resource/ScopesRequiredHttpContextExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License 3 | 4 | using Microsoft.AspNetCore.Http; 5 | using System; 6 | using System.Linq; 7 | using System.Net; 8 | using System.Net.Http; 9 | using System.Security.Claims; 10 | 11 | namespace Microsoft.Identity.Web.Resource 12 | { 13 | public static class ScopesRequiredHttpContextExtensions 14 | { 15 | /// 16 | /// When applied to an , verifies that the user authenticated in the 17 | /// web API has any of the accepted scopes. 18 | /// If the authentication user does not have any of these , the 19 | /// method throws an HTTP Unauthorized with the message telling which scopes are expected in the token 20 | /// 21 | /// Scopes accepted by this web API 22 | /// with a set to 23 | /// 24 | public static void VerifyUserHasAnyAcceptedScope(this HttpContext context, params string[] acceptedScopes) 25 | { 26 | if (acceptedScopes == null) 27 | { 28 | throw new ArgumentNullException(nameof(acceptedScopes)); 29 | } 30 | Claim scopeClaim = context?.User?.FindFirst("http://schemas.microsoft.com/identity/claims/scope"); 31 | if (scopeClaim == null || !scopeClaim.Value.Split(' ').Intersect(acceptedScopes).Any()) 32 | { 33 | context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 34 | string message = $"The 'scope' claim does not contain scopes '{string.Join(",", acceptedScopes)}' or was not found"; 35 | throw new HttpRequestException(message); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Extensions.DependencyInjection; 5 | using System.Runtime.CompilerServices; 6 | 7 | [assembly: InternalsVisibleTo("TokenCache.Tests.Core")] 8 | 9 | namespace Microsoft.Identity.Web 10 | { 11 | /// 12 | /// Extensions for IServiceCollection for startup initialization of Web APIs. 13 | /// 14 | public static class ServiceCollectionExtensions 15 | { 16 | /// 17 | /// Add the token acquisition service. 18 | /// 19 | /// Service collection 20 | /// the service collection 21 | /// 22 | /// This method is typically called from the Startup.ConfigureServices(IServiceCollection services) 23 | /// Note that the implementation of the token cache can be chosen separately. 24 | /// 25 | /// 26 | /// // Token acquisition service and its cache implementation as a session cache 27 | /// services.AddTokenAcquisition() 28 | /// .AddDistributedMemoryCache() 29 | /// .AddSession() 30 | /// .AddSessionBasedTokenCache() 31 | /// ; 32 | /// 33 | /// 34 | public static IServiceCollection AddTokenAcquisition(this IServiceCollection services) 35 | { 36 | // Token acquisition service 37 | services.AddHttpContextAccessor(); 38 | services.AddScoped(); 39 | return services; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/Distributed/DistributedTokenCacheAdapterExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace Microsoft.Identity.Web.TokenCacheProviders.Distributed 7 | { 8 | /// 9 | /// Extension class used to add an in-memory token cache serializer to MSAL 10 | /// 11 | public static class DistributedTokenCacheAdapterExtension 12 | { 13 | /// Adds both the app and per-user in-memory token caches. 14 | /// The services collection to add to. 15 | /// The MSALMemoryTokenCacheOptions allows the caller to set the token cache expiration 16 | /// 17 | public static IServiceCollection AddDistributedTokenCaches( 18 | this IServiceCollection services) 19 | { 20 | AddDistributedAppTokenCache(services); 21 | AddDistributedUserTokenCache(services); 22 | return services; 23 | } 24 | 25 | /// Adds the in-memory based application token cache to the service collection. 26 | /// The services collection to add to. 27 | /// The MSALMemoryTokenCacheOptions allows the caller to set the token cache expiration 28 | public static IServiceCollection AddDistributedAppTokenCache( 29 | this IServiceCollection services) 30 | { 31 | services.AddDistributedMemoryCache(); 32 | services.AddSingleton(); 33 | return services; 34 | } 35 | 36 | /// Adds the in-memory based per user token cache to the service collection. 37 | /// The services collection to add to. 38 | /// The MSALMemoryTokenCacheOptions allows the caller to set the token cache expiration 39 | /// 40 | public static IServiceCollection AddDistributedUserTokenCache( 41 | this IServiceCollection services) 42 | { 43 | services.AddDistributedMemoryCache(); 44 | services.AddHttpContextAccessor(); 45 | services.AddSingleton(); 46 | return services; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/Distributed/MsalDistributedTokenCacheAdapter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Authentication.AzureAD.UI; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.Extensions.Caching.Distributed; 8 | using Microsoft.Extensions.Caching.Memory; 9 | using Microsoft.Extensions.Options; 10 | 11 | namespace Microsoft.Identity.Web.TokenCacheProviders.Distributed 12 | { 13 | /// 14 | /// An implementation of token cache for both Confidential and Public clients backed by MemoryCache. 15 | /// 16 | /// 17 | public class MsalDistributedTokenCacheAdapter : MsalAbstractTokenCacheProvider 18 | { 19 | /// 20 | /// .NET Core Memory cache 21 | /// 22 | private readonly IDistributedCache _distributedCache; 23 | 24 | /// 25 | /// Msal memory token cache options 26 | /// 27 | private readonly DistributedCacheEntryOptions _cacheOptions; 28 | 29 | /// 30 | /// Constructor 31 | /// 32 | /// 33 | /// 34 | /// 35 | /// 36 | public MsalDistributedTokenCacheAdapter(IOptions azureAdOptions, 37 | IHttpContextAccessor httpContextAccessor, 38 | IDistributedCache memoryCache, 39 | IOptions cacheOptions) : 40 | base(azureAdOptions, httpContextAccessor) 41 | { 42 | _distributedCache = memoryCache; 43 | _cacheOptions = cacheOptions.Value; 44 | } 45 | 46 | protected override async Task RemoveKeyAsync(string cacheKey) 47 | { 48 | await _distributedCache.RemoveAsync(cacheKey).ConfigureAwait(false); 49 | } 50 | 51 | protected override async Task ReadCacheBytesAsync(string cacheKey) 52 | { 53 | return await _distributedCache.GetAsync(cacheKey).ConfigureAwait(false); 54 | } 55 | 56 | protected override async Task WriteCacheBytesAsync(string cacheKey, byte[] bytes) 57 | { 58 | await _distributedCache.SetAsync(cacheKey, bytes, _cacheOptions).ConfigureAwait(false) ; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/IMsalTokenCacheProvider .cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Identity.Client; 5 | using System.Threading.Tasks; 6 | 7 | namespace Microsoft.Identity.Web.TokenCacheProviders 8 | { 9 | /// 10 | /// MSAL token cache provider interface. 11 | /// 12 | public interface IMsalTokenCacheProvider 13 | { 14 | /// 15 | /// Initializes a token cache (which can be a user token cache or an app token cache) 16 | /// 17 | /// Token cache for which to initialize the serialization 18 | /// 19 | Task InitializeAsync(ITokenCache tokenCache); 20 | 21 | /// 22 | /// Clear the cache 23 | /// 24 | /// 25 | Task ClearAsync(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/InMemory/InMemoryTokenCacheProviderExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace Microsoft.Identity.Web.TokenCacheProviders.InMemory 7 | { 8 | /// 9 | /// Extension class used to add an in-memory token cache serializer to MSAL 10 | /// 11 | public static class InMemoryTokenCacheProviderExtension 12 | { 13 | /// Adds both the app and per-user in-memory token caches. 14 | /// The services collection to add to. 15 | /// The MSALMemoryTokenCacheOptions allows the caller to set the token cache expiration 16 | /// 17 | public static IServiceCollection AddInMemoryTokenCaches( 18 | this IServiceCollection services) 19 | { 20 | services.AddMemoryCache(); 21 | services.AddHttpContextAccessor(); 22 | services.AddSingleton(); 23 | return services; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/InMemory/MsalMemoryTokenCacheOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Identity.Web.TokenCacheProviders.InMemory 7 | { 8 | /// 9 | /// MSAL's memory token cache options 10 | /// 11 | public class MsalMemoryTokenCacheOptions 12 | { 13 | /// 14 | /// Gets or sets the value of the duration after which the cache entry will expire unless it's used 15 | /// This is the duration till the tokens are kept in memory cache. 16 | /// In production, a higher value , up-to 90 days is recommended. 17 | /// 18 | /// 19 | /// The SlidingExpiration value. 20 | /// 21 | public TimeSpan SlidingExpiration 22 | { 23 | get; 24 | set; 25 | } 26 | 27 | /// Initializes a new instance of the class. 28 | /// By default, the sliding expiration is set for 14 days. 29 | public MsalMemoryTokenCacheOptions() 30 | { 31 | this.SlidingExpiration = TimeSpan.FromDays(14); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /IEFTenantSetupV2/B2CIEFSetupWeb/Microsoft.Identity.Web/TokenCacheProviders/InMemory/MsalMemoryTokenCacheProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Authentication.AzureAD.UI; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.Extensions.Caching.Memory; 8 | using Microsoft.Extensions.Options; 9 | 10 | namespace Microsoft.Identity.Web.TokenCacheProviders.InMemory 11 | { 12 | /// 13 | /// An implementation of token cache for both Confidential and Public clients backed by MemoryCache. 14 | /// 15 | /// 16 | public class MsalMemoryTokenCacheProvider : MsalAbstractTokenCacheProvider 17 | { 18 | /// 19 | /// .NET Core Memory cache 20 | /// 21 | private readonly IMemoryCache _memoryCache; 22 | 23 | /// 24 | /// Msal memory token cache options 25 | /// 26 | private readonly MsalMemoryTokenCacheOptions _cacheOptions; 27 | 28 | /// 29 | /// Constructor 30 | /// 31 | /// 32 | /// 33 | /// 34 | /// 35 | public MsalMemoryTokenCacheProvider(IOptions azureAdOptions, 36 | IHttpContextAccessor httpContextAccessor, 37 | IMemoryCache memoryCache, 38 | IOptions cacheOptions) : 39 | base(azureAdOptions, httpContextAccessor) 40 | { 41 | _memoryCache = memoryCache; 42 | _cacheOptions = cacheOptions.Value; 43 | } 44 | 45 | protected override Task RemoveKeyAsync(string cacheKey) 46 | { 47 | _memoryCache.Remove(cacheKey); 48 | return Task.CompletedTask; 49 | } 50 | 51 | protected override Task ReadCacheBytesAsync(string cacheKey) 52 | { 53 | byte[] tokenCacheBytes = (byte[])_memoryCache.Get(cacheKey); 54 | return Task.FromResult(tokenCacheBytes); 55 | } 56 | 57 | protected override Task WriteCacheBytesAsync(string cacheKey, byte[] bytes) 58 | { 59 | _memoryCache.Set(cacheKey, bytes, _cacheOptions.SlidingExpiration); 60 | return Task.CompletedTask; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29806.167 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitRepoManager", "GitRepoManager\GitRepoManager.csproj", "{5DAB9CD2-3843-4BB8-A5D7-97487D8D469F}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {5DAB9CD2-3843-4BB8-A5D7-97487D8D469F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {5DAB9CD2-3843-4BB8-A5D7-97487D8D469F}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {5DAB9CD2-3843-4BB8-A5D7-97487D8D469F}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {5DAB9CD2-3843-4BB8-A5D7-97487D8D469F}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {2C2FD9DB-D5C9-42B1-9D43-AF178C81C16F} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace GitRepoManager.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/GitRepoManager.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/Policies.cs: -------------------------------------------------------------------------------- 1 | namespace GitRepoManager 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | using System.Globalization; 7 | using Newtonsoft.Json; 8 | using Newtonsoft.Json.Converters; 9 | 10 | public partial class Policies 11 | { 12 | [JsonProperty("name")] 13 | public string Name { get; set; } 14 | 15 | [JsonProperty("path")] 16 | public string Path { get; set; } 17 | 18 | [JsonProperty("sha")] 19 | public string Sha { get; set; } 20 | 21 | [JsonProperty("size")] 22 | public long Size { get; set; } 23 | 24 | [JsonProperty("url")] 25 | public Uri Url { get; set; } 26 | 27 | [JsonProperty("html_url")] 28 | public Uri HtmlUrl { get; set; } 29 | 30 | [JsonProperty("git_url")] 31 | public Uri GitUrl { get; set; } 32 | 33 | [JsonProperty("download_url")] 34 | public object DownloadUrl { get; set; } 35 | 36 | [JsonProperty("type")] 37 | public TypeEnum Type { get; set; } 38 | 39 | [JsonProperty("_policylinks")] 40 | public PolicyLinks Links { get; set; } 41 | } 42 | 43 | public partial class PolicyLinks 44 | { 45 | [JsonProperty("self")] 46 | public Uri Self { get; set; } 47 | 48 | [JsonProperty("git")] 49 | public Uri Git { get; set; } 50 | 51 | [JsonProperty("html")] 52 | public Uri Html { get; set; } 53 | } 54 | 55 | public enum TypeEnum { Dir }; 56 | 57 | internal static class Converter 58 | { 59 | public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings 60 | { 61 | MetadataPropertyHandling = MetadataPropertyHandling.Ignore, 62 | DateParseHandling = DateParseHandling.None, 63 | Converters = 64 | { 65 | TypeEnumConverter.Singleton, 66 | new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } 67 | }, 68 | }; 69 | } 70 | 71 | internal class TypeEnumConverter : JsonConverter 72 | { 73 | public override bool CanConvert(Type t) => t == typeof(TypeEnum) || t == typeof(TypeEnum?); 74 | 75 | public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) 76 | { 77 | if (reader.TokenType == JsonToken.Null) return null; 78 | var value = serializer.Deserialize(reader); 79 | if (value == "dir") 80 | { 81 | return TypeEnum.Dir; 82 | } 83 | throw new Exception("Cannot unmarshal type TypeEnum"); 84 | } 85 | 86 | public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) 87 | { 88 | if (untypedValue == null) 89 | { 90 | serializer.Serialize(writer, null); 91 | return; 92 | } 93 | var value = (TypeEnum)untypedValue; 94 | if (value == TypeEnum.Dir) 95 | { 96 | serializer.Serialize(writer, "dir"); 97 | return; 98 | } 99 | throw new Exception("Cannot marshal type TypeEnum"); 100 | } 101 | 102 | public static readonly TypeEnumConverter Singleton = new TypeEnumConverter(); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/PolicyFiles.cs: -------------------------------------------------------------------------------- 1 | namespace GitRepoManager 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | using System.Globalization; 7 | using Newtonsoft.Json; 8 | using Newtonsoft.Json.Converters; 9 | 10 | public partial class PolicyFiles 11 | { 12 | [JsonProperty("name")] 13 | public string Name { get; set; } 14 | 15 | [JsonProperty("path")] 16 | public string Path { get; set; } 17 | 18 | [JsonProperty("sha")] 19 | public string Sha { get; set; } 20 | 21 | [JsonProperty("size")] 22 | public long Size { get; set; } 23 | 24 | [JsonProperty("url")] 25 | public Uri Url { get; set; } 26 | 27 | [JsonProperty("html_url")] 28 | public Uri HtmlUrl { get; set; } 29 | 30 | [JsonProperty("git_url")] 31 | public Uri GitUrl { get; set; } 32 | 33 | [JsonProperty("download_url")] 34 | public Uri DownloadUrl { get; set; } 35 | 36 | [JsonProperty("type")] 37 | public string Type { get; set; } 38 | 39 | [JsonProperty("_links")] 40 | public Links PolicyFilesLinks { get; set; } 41 | } 42 | 43 | public partial class PolicyFilesLinks 44 | { 45 | [JsonProperty("self")] 46 | public Uri Self { get; set; } 47 | 48 | [JsonProperty("git")] 49 | public Uri Git { get; set; } 50 | 51 | [JsonProperty("html")] 52 | public Uri Html { get; set; } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/PolicyRoot.cs: -------------------------------------------------------------------------------- 1 | namespace GitRepoManager 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | using System.Globalization; 7 | using Newtonsoft.Json; 8 | using Newtonsoft.Json.Converters; 9 | 10 | public partial class PolicyRoot 11 | { 12 | [JsonProperty("name")] 13 | public string Name { get; set; } 14 | 15 | [JsonProperty("path")] 16 | public string Path { get; set; } 17 | 18 | [JsonProperty("sha")] 19 | public string Sha { get; set; } 20 | 21 | [JsonProperty("size")] 22 | public long Size { get; set; } 23 | 24 | [JsonProperty("url")] 25 | public Uri Url { get; set; } 26 | 27 | [JsonProperty("html_url")] 28 | public Uri HtmlUrl { get; set; } 29 | 30 | [JsonProperty("git_url")] 31 | public Uri GitUrl { get; set; } 32 | 33 | [JsonProperty("download_url")] 34 | public Uri DownloadUrl { get; set; } 35 | 36 | [JsonProperty("type")] 37 | public string Type { get; set; } 38 | 39 | [JsonProperty("_links")] 40 | public PolicyRootLinks Links { get; set; } 41 | } 42 | 43 | public partial class PolicyRootLinks 44 | { 45 | [JsonProperty("self")] 46 | public Uri Self { get; set; } 47 | 48 | [JsonProperty("git")] 49 | public Uri Git { get; set; } 50 | 51 | [JsonProperty("html")] 52 | public Uri Html { get; set; } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace GitRepoManager 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:55998", 8 | "sslPort": 44358 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "GitRepoManager": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/RepoRoot.cs: -------------------------------------------------------------------------------- 1 | namespace GitRepoManager 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | using System.Globalization; 7 | using Newtonsoft.Json; 8 | using Newtonsoft.Json.Converters; 9 | 10 | public partial class RepoRoot 11 | { 12 | [JsonProperty("name")] 13 | public string Name { get; set; } 14 | 15 | [JsonProperty("path")] 16 | public string Path { get; set; } 17 | 18 | [JsonProperty("sha")] 19 | public string Sha { get; set; } 20 | 21 | [JsonProperty("size")] 22 | public long Size { get; set; } 23 | 24 | [JsonProperty("url")] 25 | public Uri Url { get; set; } 26 | 27 | [JsonProperty("html_url")] 28 | public Uri HtmlUrl { get; set; } 29 | 30 | [JsonProperty("git_url")] 31 | public Uri GitUrl { get; set; } 32 | 33 | [JsonProperty("download_url")] 34 | public Uri DownloadUrl { get; set; } 35 | 36 | [JsonProperty("type")] 37 | public string Type { get; set; } 38 | 39 | [JsonProperty("_links")] 40 | public Links Links { get; set; } 41 | } 42 | 43 | public partial class Links 44 | { 45 | [JsonProperty("self")] 46 | public Uri Self { get; set; } 47 | 48 | [JsonProperty("git")] 49 | public Uri Git { get; set; } 50 | 51 | [JsonProperty("html")] 52 | public Uri Html { get; set; } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.HttpsPolicy; 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Hosting; 12 | using Microsoft.Extensions.Logging; 13 | 14 | namespace GitRepoManager 15 | { 16 | public class Startup 17 | { 18 | public Startup(IConfiguration configuration) 19 | { 20 | Configuration = configuration; 21 | } 22 | 23 | public IConfiguration Configuration { get; } 24 | 25 | // This method gets called by the runtime. Use this method to add services to the container. 26 | public void ConfigureServices(IServiceCollection services) 27 | { 28 | services.AddControllers(); 29 | } 30 | 31 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 32 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 33 | { 34 | if (env.IsDevelopment()) 35 | { 36 | app.UseDeveloperExceptionPage(); 37 | } 38 | 39 | app.UseHttpsRedirection(); 40 | 41 | app.UseRouting(); 42 | 43 | app.UseAuthorization(); 44 | 45 | app.UseEndpoints(endpoints => 46 | { 47 | endpoints.MapControllers(); 48 | }); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GitRepoManager 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/GitRepoManager/GitRepoManager/policyRow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace GitRepoManager.Controllers 7 | { 8 | public class policyRow 9 | { 10 | public string displayName; 11 | public string folderName; 12 | public string description; 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /IEFTenantSetupV2/README.md: -------------------------------------------------------------------------------- 1 | # B2C Identity Experience Framework - Getting Started 2 | 3 | ## Purpose 4 | Configures an existing Azure AD B2C tenant for use with Identity Experience Framework custom policies. Performs all 5 | tasks defined in the [get started](https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-get-started?tabs=applications) 6 | document. 7 | 8 | ## Usage 9 | The application is [deployed and ready to use](https://aka.ms/iefsetup): 10 | 1. Enter the name of your B2C tenant 11 | 2. Sign-in with an account with admin privileges in that tenant (account that was used to create the tenant has these by defualt) 12 | 3. AzureAD will ask you to consent to the application having the ability to create objects in your tenant (applications, keys, policies) 13 | 4. Once you consent, the application will check whether your tenant has all the objects named in the [*Get started*](https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-get-started?tabs=applications) 14 | 5. If these objects, do not exists, the application will create them (2 applications, 2 service principals and two keys, upload all policies and test app registration) 15 | 16 | Once done, you can use can explore all of our [samples](https://github.com/azure-ad-b2c/samples). 17 | 18 | -------------------------------------------------------------------------------- /IEFUploadDownload/.gitignore: -------------------------------------------------------------------------------- 1 | Upload.ps1 2 | -------------------------------------------------------------------------------- /IEFUploadDownload/sampleData/LocalAccounts/PasswordReset.xml: -------------------------------------------------------------------------------- 1 |  2 | 10 | 11 | 12 | yourtenant.onmicrosoft.com 13 | B2C_1A_TrustFrameworkExtensions 14 | 15 | 16 | 17 | 18 | 19 | PolicyProfile 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /IEFUploadDownload/sampleData/LocalAccounts/ProfileEdit.xml: -------------------------------------------------------------------------------- 1 |  2 | 10 | 11 | 12 | yourtenant.onmicrosoft.com 13 | B2C_1A_TrustFrameworkExtensions 14 | 15 | 16 | 17 | 18 | 19 | PolicyProfile 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /IEFUploadDownload/sampleData/LocalAccounts/SignUpOrSignin.xml: -------------------------------------------------------------------------------- 1 |  2 | 10 | 11 | 12 | yourtenant.onmicrosoft.com 13 | B2C_1A_TrustFrameworkExtensions 14 | 15 | 16 | 17 | 18 | 19 | PolicyProfile 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /IEFUploadDownload/sampleData/LocalAccounts/TrustFrameworkExtensions.xml: -------------------------------------------------------------------------------- 1 |  2 | 10 | 11 | 12 | yourtenant.onmicrosoft.com 13 | B2C_1A_TrustFrameworkBase 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Local Account SignIn 24 | 25 | 26 | 27 | ProxyIdentityExperienceFrameworkAppId 28 | IdentityExperienceFrameworkAppId 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | REST APIs 40 | 41 | 42 | Check Player Tag Web Hook Azure Function 43 | 44 | 45 | {CheckPlayerAPIUrl} 46 | Body 47 | 48 | None 49 | 50 | true 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /IEFUploadDownload/sampleData/LocalAccounts/appsettings.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "CheckPlayerAPIUrl": "https://wingtipb2cfuncs.azurewebsites.net/api/CheckPlayerTagWebHook?code=L/05YRSpojU0nECzM4Tp3LjBiA2ZGh3kTwwp1OVV7m0SelnvlRVLCg==" 4 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Azure Active Directory B2C: Sample Scripts 2 | 3 | In this repo, you will find sample scripts related to the administration and use of Azure AD B2c. 4 | 5 | ## Language Customisation 6 | - [Convert Language files using Azure Cognative API](/ConvertLanguage) This sample script uses the [Azure Cognative API](https://www.microsoft.com/en-us/translator/) This sample web test shows how to run tests and monitor results of B2C sign in's, using Azure Application Insights.) to convert Built-In language files form one language to another. 7 | - [Convert from Built-In Language files to IEF](/BultInLangtoCustLang) This script converts the language file format from Built-In to that required for Identitiy Experience Framework policies. 8 | 9 | ## Getting Started 10 | - Scripts to [automate setting up a new B2C tenant](/GettingStarted). These scripts will prepare your B2C tenant to be ready for testing in seconds: 11 | - Create a B2C GraphApp for scripting 12 | - Create the Token Signing and Encryption keys 13 | - Create the IdentityExperienceFramework apps 14 | - Download/Modify/Upload the [B2C Starter Pack](https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack) 15 | - Create a test WebApp so you can test your first signup/signin 16 | 17 | ## Community Help and Support 18 | Use [Stack Overflow](https://stackoverflow.com/questions/tagged/azure-ad-b2c) to get support from the community. Ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before. Make sure that your questions or comments are tagged with [azure-ad-b2c]. 19 | If you find a bug in the sample, please raise the issue on [GitHub Issues](https://github.com/azure-ad-b2c/samples/issues). 20 | To provide product feedback, visit the Azure Active Directory B2C [Feedback page](https://feedback.azure.com/forums/169401-azure-active-directory?category_id=160596). 21 | -------------------------------------------------------------------------------- /custom-domain/images/bash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azure-ad-b2c/Scripts/ba936150984b5a96e62c83932f3fe82d79172a92/custom-domain/images/bash.png -------------------------------------------------------------------------------- /custom-domain/images/powershell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azure-ad-b2c/Scripts/ba936150984b5a96e62c83932f3fe82d79172a92/custom-domain/images/powershell.png -------------------------------------------------------------------------------- /custom-domain/readme.md: -------------------------------------------------------------------------------- 1 | # Handy script which verifies custom domain configuration b/w AFD & Azure AD B2C. 2 | 3 | Details about custom domain feature are available at [Enable custom domains for Azure Active Directory B2C](https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-domain?pivots=b2c-user-flow) 4 | 5 | ## Prerequisite 6 | * Python 3.0 or above. You can easily run the script by using [Azure Cloud Shell](https://shell.azure.com/). 7 | * Azure AD B2C tenant with at least one userflow/custom policy. (e.g. b2c_1_susi). [Create userflow/custom policy](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-user-flow) 8 | * Azure Front Door (AFD) 9 | 10 | ## Installation 11 | ``` 12 | $ git clone https://github.com/azure-ad-b2c/Scripts.git 13 | $ cd ./Scripts/custom-domain/ 14 | ``` 15 | 16 | Install the required packages. 17 | ``` 18 | $ pip install -r requirements.txt 19 | ``` 20 | 21 | ## Run the script 22 | ``` 23 | $ python check_b2cdomain.py -custom-domain "your.domain.name" -policy "b2c_1_policyname" 24 | ``` 25 | 26 | For example, running the script against ```accountuat.contosobank.co.uk``` domain will first verify the presense of CNAME entry to AFD instance. After that, it will make a request to Azure AD B2C endpoint and then examine the headers from the response to ensrue traffic is traveling back via AFD <--> Azure AD B2C. 27 | ``` 28 | $ python check_b2cdomain.py -custom-domain "accountuat.contosobank.co.uk" -policy "b2c_1_susi" 29 | 30 | ⏳ Searching AFD mapping for domain: [accountuat.contosobank.co.uk] 31 | 💯 FOUND! [accountuat.contosobank.co.uk] is mapped to AFD [contosodem.azurefd.net.] 32 | ⏳ Connecting to Azure AD B2C endpoint [https://accountuat.contosobank.co.uk/accountuat.contosobank.co.uk/v2.0/.well-known/openid-configuration?p=b2c_1_susi] 33 | 💯 FOUND! [accountuat.contosobank.co.uk] is configured for Azure AD B2C tenant [e2040e42-94ae-4a26-a7d1-b1825f46de1d] 34 | ✅ AFD Header [X-Azure-Ref] found. Response came through AFD! 35 | ✅ AFD Header [X-Azure-OriginStatusCode] found with HTTP code 200! All good on the connection side from AFD --> Azure AD B2C. 36 | 🚀 Yay! Domain [accountuat.contosobank.co.uk] is configured correctly for AFD & Azure AD B2C usage! [All Good ✅ ] 37 | ``` 38 | ### Powershell 39 | 40 | ![Powershell](./images/powershell.png) 41 | 42 | ### Bash 43 | 44 | ![Bash](./images/bash.png) 45 | 46 | ## Troubleshooting 47 | 48 | To view parameters use ``-h`` or ``--help`` swtich. 49 | ``` 50 | $ python check_b2cdomain.py -h 51 | ``` 52 | To get more verbose information use ``-v`` or ``--verbose`` swtich. 53 | ``` 54 | $ python check_b2cdomain.py -custom-domain "accountuat.contosobank.co.uk" -policy "b2c_1_susi" --verbose 55 | ``` 56 | -------------------------------------------------------------------------------- /custom-domain/requirements.txt: -------------------------------------------------------------------------------- 1 | argparse 2 | pydig 3 | requests 4 | --------------------------------------------------------------------------------