mrochon / b2csamples Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Running npm run build
for the React SPA in the multitenancy sample fails because the public folder is missing, specifically public\index.html is expected by react-scripts
. The folder is specifically excluded in the .gitignore file which leads me to believe that this was done on purpose 🤔 I'm not sure what the plan here is.
Workaround for anyone interested: Run npx create-react-app my-app
which creates a new default react app, then copy the public folder to Policies\MultiTenant\source\UI.
I am setting up b2c multi-tenant authentication for my app, I try to follow same steps but stuck with 2 problems
Current xml policies reference both FB and Gmail policy keys and therefore fail to upload if these two keys do not yet exist in the B2C tenant. The upload process needs to handle it more gracefully.
Modify the setup and remove PS to allow users to explicitly specify the AAD and B2C tenants and subscription ids where they want the apps to be deployed.
I have setup azure b2c custom policy for inivation flow, using this sample, it's working fine, but when the invitation link gets expired, and user opens that it shows error page with
"AADB2C90017: The client assertion provided in the request is invalid: 'client_secret' was used as the verification key"
I want to change the error message so user can know that link is expired.
Hello. I am a beginner developer in Azure B2C. I found a link to this example on
https://stackoverflow.com/questions/54973828/azure-ad-b2c-multi-tenant
This script:
https://github.com/mrochon/b2csamples/tree/master/Policies/MultiTenant
perfect for my application. While trying to understand how the example works, I found that I couldn't invite the user. After creating the URL the answer is that the user does not exist. What's my mistake?
Is there a more detailed description of the code? Is it possible to implement the API on a Node JS?
After successfully executing Setup-B2CMultiTenant.ps1 script @
https://github.com/mrochon/b2csamples/tree/master/Scripts/MultiTenant
Fail to create a new Tenant.
it does hit b2c-mt-rest API but then throws 500 internal server error.
Are there any missing steps in the above deployment script?
do we need to configure https://github.com/mrochon/b2c-mt-rest functions app separately?
Could I use IEFPolicies module or its logic to do it from the UI?
I've been trying to figure out how to set this up to use a URL path identifier for the tenant name rather than a query string as it does currently but not having much luck. Is this just not possible as a rule? Is updating the app registration in B2C with reply URLs for each tenant the only way to get this to work?
Basically i'm aiming for urls that look like https://b2cmultitenant.azurewebsites.com/tenant-a/ rather than https://b2cmultitenant.azurewebsites.net?tenant=tenant-a&domain=google.com
Is this possible without modifying the app registration?
When downloading starter pack, make TFB.xml read only to help users not to modify it (they can override this in VS Code anyway). Makes it easier to move policies to other bases if the original is unchanged.
Hi, I've been working through the samples you've provided for creating a multi-tenant B2C application and I was wondering if you have any thoughts on how to handle authorization within this scenario.
Is there a way that I could restrict access to certain endpoints within my application using this model. Preferably is there a way to assign permissions to a user or a group of users that would map to endpoints in my system?
Csx (Azure Function) code using Client Credentials, e.g. in the App Roles sample incorrect compares token expiry time to current time (-5minutes). It will only renew the token 5 minutes after its expiry!
I noticed a warning in the B2C documentation that client assertion is deprecated.
https://github.com/azure-ad-b2c/samples/blob/master/policies/invite_deprecated/Readme.md
Should the invite example be changed to accept an id_token
?
Signing in with a new Work or School account to create a new tenant takes the user straight to the sample with no option to create a new tenant. Then shows a message saying the user does not own a tenant.
The script should ask for the Tenant ID of the tenant where resources are being created instead of defaulting to the root tenant. Say for example users belong to multiple tenants in azure and they want to select the one that is not their home directory.
Redesign to use either with code challenge or implicit
Return error if user assignment required and user is not assigned to a role
Hello and thanks for the useful samples. Also apologies for using this as Q&A but I see no other way to contact you.
Can you suggest how to extend the MultiTenant sample to accommodate more user roles?
Now it supports either an owner or regular member. What if I wanted to have owners and read-only and read-write members?
My problem is I'm not sure where to store this information. For owner vs. regular member you reuse the group ownership, but where would you record if the user is read-only or read-write in a given tenant?
Hi,
this project helped me a lot to understand B2C and try it out, thanks for that.
But there is one Problem. When i try to create the Tenant i get the error Message:
Client certificate specified for 'REST-CreateTenant' is invalid. Check that the certificate is correct, contains a private key and that access has been granted by the resource.
In the RestFunctions API it is failing at
var certHeader = context.Request.Headers["X-ARR-ClientCert"];`
if (!String.IsNullOrEmpty(certHeader))
My policy looks like
<Metadata>
<Item Key="ServiceUrl">https://myrestfunctions.azurewebsites.net/tenant</Item>
<Item Key="AuthenticationType">ClientCertificate</Item>
<Item Key="SendClaimsIn">Body</Item>
</Metadata>
<CryptographicKeys>
<Key Id="ClientCertificate" StorageReferenceId="B2C_1A_RESTClientCert" />
</CryptographicKeys>
i also tried with AllowInsecureAuthInProduction true
and my policy key:
{
"metadata": {
"updatedUtc": "4/2/2020 11:23:32 AM",
"tenantID": "tenant.onmicrosoft.com",
"storageKeyId": "B2C_1A_RESTClientCert"
},
"keys": [
{
"kid": "920...C26",
"exp": 1617362486,
"nbf": 1585825886,
"key_ops": [
"sign"
],
"x5c": [
"MIIDFjCC...tLOb7s="
],
"x5t": "kgh...iLCY",
"kty": "RSA",
"e": "AQAB",
"n": "60s5kVcmN...mN2TRCQ"
}
]
}
I used the following powershell script to generate the certificate:
New-SelfSignedCertificate `
-KeyExportPolicy Exportable `
-Subject "CN=herrenknechtb2ctest" `
-KeyAlgorithm RSA `
-KeyLength 2048 `
-KeyUsage "DigitalSignature","KeyEncipherment" `
-NotAfter (Get-Date).AddMonths(12) `
-CertStoreLocation "Cert:\CurrentUser\My"`
-HashAlgorithm sha1
Would be great if you give me some hints where to look at.
Regards,
Andreas
Hi Marius,
I am working on a SSO project with several multi-tenancy applications and believe this project covers many of the use cases I have. The applications support SAML as some are quite legacy without OIDC support.
Can you confirm if this solution will work using the B2C SAML TechnicalProfile and also if the appTenantId custom attribute can be returned in the SAML Assertion as an attribute? Any guidance on this would be very much appreciated as while I have gotten the SAML B2C integration examples using custom policies working I am not very experienced with Custom Policies at this point.
Kind Regards,
Lastbuilders
It is marked as Readonly in xml but b2C does not seem to obey it. Seems like signin has a hard-coded style to make the signin field writeable (check contract version)
Does not exist?
It should resolve to MSA instead.
I have tried my best to follow the instructions in MultiTenant Sample and I can log in to the SPA application but cannot get the members.
My guess is that the issue lies in the App registrations
in the B2C
.
Could you share more details on how to configure the app registrations? More specifically how the API Permissions, Certificates and Secrets and Authentication sections are configured in the demo application?
The issue is that when I go to members, the /b2c_1a_v2signin/oauth2/v2.0/token
token endpoint returns only id_token
. Therefore the API request /tenant/oauth2/members
fails.
Below is the request for sample React SPA application
NOTE: Body has been formatted for readability
URL https://b2cmultitenant.b2clogin.com/{tenantId}/b2c_1a_v2signin/oauth2/v2.0/token
{
"credentials": "omit",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"content-type": "application/x-www-form-urlencoded;charset=utf-8",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "cross-site",
"Pragma": "no-cache",
"Cache-Control": "no-cache"
},
"referrer": "https://b2cmultitenantv2.z22.web.core.windows.net/",
"body": "
client_id=c84a01bb-4f19-4eef-9941-4ab537922039
scope=openid profile https://b2cmultitenant.onmicrosoft.com/mtrest/User.Invite https://b2cmultitenant.onmicrosoft.com/mtrest/User.ReadAll offline_access
grant_type=refresh_token
client_info=1
x-client-SKU=msal.js.browser
x-client-VER=2.16.0
x-client-OS=
x-client-CPU=
x-ms-lib-capability=retry-after,h429
x-client-current-telemetry=5|61,0,,,|@azure/msal-react,1.0.1
x-client-last-telemetry=5|0|||0,0
client-request-id=184306fa-1441-42aa-92a5-ca1d10c611a1
refresh_token=eyJraWQiOiJ6a0hnRXNIQ0xZVDV2N0dyczRhLUo1WldpZXdoOVpJVzVWTDREODJqWE...
X-AnchorMailbox=Oid:f91f6134-5da3-45d1-b3f1-9dcafecfead1-b2c_1a_v2signin@d06b10f6-c712-40c1-9617-cec9c7d02390",
"method": "POST",
"mode": "cors"
}
And below the response (with tokens truncated...):
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIs...",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"not_before": 1669196431,
"expires_in": 3600,
"expires_on": 1669200031,
"resource": "8c8fefff-0743-499c-a26f-f5cf9f68b197",
"client_info": "eyJ1aWQiOiJmOTFmNjEzNC01ZGEzLTQ1ZDE...",
"scope": "https://b2cmultitenant.onmicrosoft.com/mtrest/User.Invite https://b2cmultitenant.onmicrosoft.com/mtrest/User.ReadAll",
"refresh_token": "eyJraWQiOiJ6a0hnRXNIQ0xZVDV2N0dyczR...",
"refresh_token_expires_in": 86355
}
Request with our application:
URL: https://{tenantName}.b2clogin.com/{tenantId}/b2c_1a_v2signin/oauth2/v2.0/token
{
"credentials": "omit",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"content-type": "application/x-www-form-urlencoded;charset=utf-8",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "cross-site",
"Pragma": "no-cache",
"Cache-Control": "no-cache"
},
"referrer": "http://localhost:3000/",
"body": "
client_id=605b9c05-f7af-4131-9948-1b62a340433f
scope=openid profile https://jamixg6b2cweu.onmicrosoft.com/mtrest/User.Invite https://jamixg6b2cweu.onmicrosoft.com/mtrest/User.ReadAll offline_access
grant_type=refresh_token
client_info=1
x-client-SKU=msal.js.browser
x-client-VER=2.31.0
x-ms-lib-capability=retry-after, h429
x-client-current-telemetry=5|61,0,,,|@azure/msal-react,1.4.10
x-client-last-telemetry=5|0|||0,0
client-request-id=39268f43-0dc4-4477-92c9-b85d41d0273b
refresh_token=eyJraWQiOiJNNzNVVkh5TjBxX19lTUpTcjFDaHpxeWx0em8tNF9WTEdKR3dUY1d...",
"method": "POST",
"mode": "cors"
}
and the response:
{
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUz...",
"token_type": "Bearer",
"not_before": 1669206154,
"client_info": "eyJ1aWQiOiJjNzdkYmNlZS0zNzRiLT...",
"scope": "",
"refresh_token": "eyJraWQiOiJNNzNVVkh5TjBxX19lTU...",
"refresh_token_expires_in": 86274
}
The MultiTenant rest api in Tenant.X509.cs references user.IsInRole("ief") as part of authorization. No where in documentation for the sample is how this role is created or generated. Knowing where and how this done would be helpful.
The readme on MultiTenant sample mentions -allowInit
although it has been obsoleteted by this commit.
Is there a typo here?
When I run the Setup-B2CMultiTenant.ps1
script I receive many errors along the lines of the following. I've also installed all the required modules from https://github.com/mrochon/b2csamples/tree/master/Scripts/MultiTenant#install-required-powershell-modules. It seems like I'm missing another module, or a module needs imported?
Connect-AzureAD: /Users/zach/Desktop/MultiTenantTemp/Setup-B2CMultiTenant.ps1:115
Line |
115 | Connect-AzureAD -TenantId $settings.b2cTenant -AccountId $azure.Accou …
| ~~~~~~~~~~~~~~~
| The term 'Connect-AzureAD' is not recognized as a name of a cmdlet, function, script file, or
| executable program. Check the spelling of the name, or if a path was included, verify that the
| path is correct and try again.
Get-AzureADCurrentSessionInfo: /Users/zach/Desktop/MultiTenantTemp/Setup-B2CMultiTenant.ps1:116
Line |
116 | $b2c = Get-AzureADCurrentSessionInfo -ErrorAction stop
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The term 'Get-AzureADCurrentSessionInfo' is not recognized as a name of a cmdlet, function, script
| file, or executable program. Check the spelling of the name, or if a path was included, verify
| that the path is correct and try again.
...
PS /Users/zach/Desktop/MultiTenantTemp> Get-Module ModuleType Version PreRelease Name ExportedCommands ---------- ------- ---------- ---- ----------------
Script 2.4.0 Az.Accounts {Add-AzEnvironment, Clear-AzContext, Clear-Az…
Script 4.2.0 Az.Resources {Add-AzADGroupMember, Export-AzResourceGroup,…
Script 2.7.0 Az.Websites {Add-AzWebAppAccessRestrictionRule, Add-AzWeb…
Manifest 7.0.0.0 Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear-Item, Clea…
Manifest 7.0.0.0 Microsoft.PowerShell.Security {ConvertFrom-SecureString, ConvertTo-SecureSt…
Manifest 7.0.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compar…
Script 1.4.7 PackageManagement {Find-Package, Find-PackageProvider, Get-Pack…
Script 2.2.5 PowerShellGet {Find-Command, Find-DscResource, Find-Module,…
Script 2.1.0 PSReadLine {Get-PSReadLineKeyHandler, Get-PSReadLineOpti…
Any help would be greatly appreciated!
Thanks for the sample, it's exactly what I am looking for. just wondering if there is more pointers/documentation explaining how to configure this b2c multitenant app. thx!
Only the SignIn flow initiated from website UI should be using no-signup option.
While playing around in the hosted demo app(https://b2cmultitenant.azurewebsites.net/) it redirects to: https://localhost:44369/signin-mtsusint when forgot password is clicked
Unneeded function definition in MFAChoice sample.
Thank you @mrochon for this excellent repo! I had a few observations/issues (sorry if this is a bit long):
Connect-AzAccount -Tenant "mytenantid" -Credential $creds -ErrorAction Stop
Get-AzSubscription -SubscriptionName "mysubscriptionname"|Select-AzSubscription
Upload-IEFPolicies will fail to upload TrustFrameworkBase.xml and TrustFrameworkExtensions.xml due to validation errors, if the IEF does not have policy keys named B2C_1A_GoogleSecret and B2C_1A_FacebookSecret. Maybe these had originally existed when I first created my B2C tenant and I deleted them, not sure. But adding placeholder generated keys fixed the issue, and the keys would be needed regardless if one wishes to implement Google/FB auth.
I notice in the sample app that initially after the "Create Tenant" flow, everything works fine, but after some time (20 mins?) the Members and Tenant tab will no longer work, displaying blank views. I'm guessing some sort of a token timeout to the API, that isn't auto-renewing?
After completing the setup script, on the final setup for granting admin consent to permissions for the client-creds app, pressing Accept on the consent screen will throw a sign in error, owing to the client creds app not having a redirect uri. I assumed this was okay since it doesn't need one? I was also able to manually add the permissions and grant them in the portal.
I can't get the app to work, in both the auto-deployed version, and the .NET core version running locally. Following the Create Tenant journey (policy = susint I believe), I select Work or School on the login screen, choose an account, then get the following:
These are contrived GUIDs, but the first is the ClientId of the AADCommon app in the B2C tenant, and the second I believe is the tenant id of whatever user is trying to create a new tenant. I've tried with a number of users from different tenants.
I would have expected the app registration to auto-appear in the organizational tenant of any user that consents to adding the client app. Much like in Azure AD Multi-Tenancy when using the Admin consent endpoint. Is that not the case here?
Is it possible to omit the invitation process for users coming from Azure AD tenants? i.e. Once an application tenant is "created" (which, as I understand, is just adding the user to a tenant group), is it possible to have all further users using the same Azure Ad tenant added to the same group/app tenant?
Any advice would be greatly appreciated. Thank you again.
Add OTP signin support as an option. When used with corporate domains, ensures user is still a valid member of that corporation.
Hello, my name is Michal Nekvasil, I'm C# developer from the Czech Republic,
I'm sorry to contact you this way, but I did not find any other way to contact you by email or so. I used this code in my project https://mrochon.azurewebsites.net/2009/10/16/displaying-hierarchical-data-in-the-datagrid/ . It was few years back. Now someone claims, this is his code and I stole it.
Only thing I need, can you please make the download link work again? Now it says ResourceNotFound error. It would prove me unguilty.
Thank you very much, again sorry to contact you this way, over github issue. Have a nice day
Michal Nekvasil
Provide an optional setting to specify that members of a specific AAD tenant can automatically join a specific B2C tenant (group), with no need for invitation.
Thank you for this repo @mrochon.
This seems like the exact flow that I needed.
I'm trying to deploy this on my own and learn more from this repo.
I've followed the steps in the Scripts/Multitenant/readme .
When I run the script, I'm getting this error.
Would be great to get some insights from anyone who experienced something similar.
The app-clientcreds app registration currently looks like this
I have to say there had been some trials and errors trying to run the script.
Also, I've made some minor changes to remove Facebook and Google from the policies.
Hi there, and thanks for your repo with many examples, they are great!
I am looking to implement the AppRoles sample, but I want to use my current "user flow" (B2CSignIn_V3) as a base for this custom policy, since it already includes stuff like password change on expiration (in the flow), and MFA. All I want is the app roles customization in there, for the rest it is perfect. I know I need to use a custom flow, so this looks like the best bet.
I understand that I need the REST-GetRoles
ClaimsProviders-part from the TrustFrameworkExtensions.xml
file in your sample.
How would I go about implementing this? Documentation is REALLY thin on this. Can I just add the REST-GetRoles
part to my existing XML file and upload it as a custom policy? Or do I really need to "transcribe" the original user flow (xml) into the TrustFrameworkBase
, TrustFrameworkExtensions
and finally a nearly empty "policy"?
I understand how this all works technically, I just want to know whether its possible to drop this customization in the existing XML file. Thank you - I hope it makes sense.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.