Azure B2C - Use generated temporary password in Signup custom policy - azure-ad-b2c

Is there a way to use the generated random password while creating the account using Signup Custom policies?.
I understand that this is possible using Graph API but we are looking at the possibilities using the policies.

If you are referring to the password a user would use to login to their account, then no. As detailed here the only thing custom policies can do with user passwords is write them to the directory. You cannot read a user's password from custom policies (or from anywhere as far as I am aware).
I'm not sure which random password specifically is being referred to (if you are following an example, posting it may help), but you would have to store it elsewhere (which obviously carries security issues with it) and then retrieve it using an API of some sort during policy execution

Related

How to store external social media account linking in the database?

Let's say we have a backend in ExpressJS. We are using simple BcryptJS to hash and store passwords and emails in the database.
Now I want to add the link social media accounts feature like this:
Now what I was wondering is what should I store in the database? Like lets say I registered using email and password, now I go in settings and add Google login, what should I store with the user's record in the database to use the Google identity in the future when needed? Like should I store the access token? the refresh token? Should I keep refreshing the token? Should I not even store the token?
Sorry if it might sound silly, but I googled around and didn't find the answer I wanted, and I have spent the last hour thinking about this. What do you guys think? And this answer might help a lost developer in the future too.
SOCIAL LOGINS
If this is your starting point, and assuming that the email used from Google or Facebook matches that used when logging in with passwords:
Field
Example Value
User ID
203
Email
john#company.com
Then when you receive the Google or Facebook response you would need to look for an email in it, either by inspecting the ID token or calling their user info endpoint. You can then match to the User ID that makes sense to your business data.
If you store anything from those providers it should be a linked record, something like this. You should only need to store access tokens from the third party provider if your app needs to access the user's Google or Facebook resources with it:
Field
Example Value
User Link ID
1039
User ID
203
Provider
Google
Subject
d2ee68ee-7853-11ec-90d6-0242ac120003
PROBLEM AREAS
The above mechanism is inherently unreliable and can easily result in duplicate users in your business data, eg if the social provider does not give you an email and the user exists already in your business data. A technique to solve this problem can be to involve the user - ask them if they exist already in your app and if so then ask them to authenticate with an existing method (password in your case) as part of onboarding to social logins.
Foreign access tokens, from Google and Facebook, are not designed to be used to secure your own APIs - you may not even be able to validate them in some cases, and you will not be able to control claims and scopes. This leads some people to write custom code to issue their own tokens.
AUTHORIZATION SERVER
For future reference, the preferred architecture is for your UIs and APIs to only talk to your own Authorization Server, which is hosted alongside APIs. This component will then manage the following aspects for you, all of which will keep the security plumbing out of your apps:
Login connections to social providers
Dealing with provider specific differences
Providing account linking capabilities
Storing linked records
Allowing you to return your own customized tokens to your own apps
In more advanced use cases the AS can also hold onto the third party access token for you via the embedded token approach.

AzureB2C - SSO issue between UserFlow and CustomPolicy

I'm facing an issue with AzureB2C and SSO.
I've got a custom policy and a UserFlow, both using SingleSignOn-Scope "tenant" and both use the same federated IdP (AzureAD).
Now, when using the one flow for signing in, SSO is working. But when signed in and switching to another app which is using the other flow, I get "We're having trouble signing you in..."
Regarding the custom policy, I did not change the SSO technical profiles from the starter pack, nor adding any other claims to the relying party. The output token of both flows look the same
Any idea what could be wrong or how I could debug this?
Ok, I found out what's going on here.
In fact, UserFlows use different signing keys then custom policies. UserFlows include some reference to Microsoft-internal keys which cannot be used in custom policies.
Therefore, I guess, the session cookie is encrypted differently and cannot be used accross UserFlows-CustomPolicies.
The same happens if you protect your Api with a UserFlow-Policy and you have your UI use a CustomPolicy. The API will throw an invalid signature exception.
Conclusion:
You either stay with customPolicies or UserFlows throughout your entire infrastructure.
(Somebody should actually address this to Microsoft)

How do I specify a custom policy to only the first time a user signs in?

Context
We have created a custom policy used when users are invited to our SPA application.
The policy does one time user initialization like creating records in our database by invoking the REST API capabilities. Everything here works as expected: The custom logic is executed and we get and id token back.
The problem starts when we are supposed to get an access token for a protected API when invoking the msal.js method
"acquireTokenSilent".
We now see, that the custom policy is executed again, the REST endpoint is once again executed and it's trying to create the user again.
Question
Isn't it possible to get an access token without executing all business logic defined in a custom policy?
I thought that getting an acccesstoken was completely separate from the policy, since we are already authenticated when we got the id token.
acquireTokenSilent in MSAL.js 1.x uses an iframe that runs through the login with prompt=none.
So in the case of implicit grant flow (which is used here), the answer is that it runs through the login flow every time the token is refreshed.
There are a couple choices here:
Make the API endpoint idempotent, i.e. allow calling it multiple times (but ignore the request if the user already exists)
Set a claim on the user that is stored in session state (SSO) and skip the REST API orchestration step if that claim has a value (or you can use the objectIdFromSession claim, which I think is there in the starter template)
The first option is sort of the simplest, and I assume you've already made it like that since it would be called again also when the user logs out and logs back in.
It might result in a lot of requests to that API though.
To avoid that, you could use the newUser claim or set an extension property on the user after the API call.
When calling acquireTokenSilent(), pass in a new authority for a normal Sign In policy. That Sign In policy needs to have session management (SM-AAD) and the same SM-AAD SM technical profile must be present in a technical profile within your invite policy, such that the user can get SSO via the Sign In policy after using the Invite policy.

How to prevent password reuse using B2C Custom policies

I would like to customize the password policy for my B2C Custom Login Flow. I can see how to change things like password length etc (see Password Polices)
But I also want to prevent the user from using any of the last 8 passwords. How would I do this?
This capability is currently not supported in Azure AD B2C.
Here is the feedback, please go and upvote this.
The best you can do with built in functions is: https://github.com/azure-ad-b2c/samples/tree/master/policies/password-reset-not-last-password
For more than last password history, the only workaround is to store the hashes yourself and use a REST API to examine the hash against the new password being provided. Something that we dont recommend doing, and rather using better techniques such as MFA.

How can we support ADFS if we *require* a shared secret for encryption?

EDIT: (summary): I'm looking first for a way to have a custom, user-specific attribute passed to us as part of the ADFS signon; if that's reasonable, I'll dig into how to secure it.
EDIT: (clarification): I don't want to pass something through AD at time of login -- if the user has to enter their password and then authenticate again against AD, they're going to end up with confusing, mis-matching passwords. Instead I want registration with us to go like this:
user enters details (email, etc)
we generate a long random string, encrypt it, then provide that as part of a unique id to the client's AD
Then at each login:
We redirect the user to the client's AD for auth
Once the user is authorized, they're redirected back to us with user & claim info
That info includes the unique ID we generated -- so we extract a user ID and decrypt the password from that.
This would be lower security than we normally offer, but it's the best I can imagine if AD is involved. Is this possible?
Long version: A customer is asking that we add support for single sign-on to our web application, implementing Microsoft ADFS (Active Directory Federated Services).
The problem is that we rely on the user's password to decrypt their record; their private key is encrypted with their password, so we can't access their record without the password.
I've been digging into the documentation, e.g., http://msdn.microsoft.com/en-us/library/bb897402.aspx -- but currently I don't see way to securely manage some kind of secret encryption key using AD FS.
It wouldn't have to be the password itself, of course -- we implemented OAuth2 by generating random access tokens that have the same properties as a password (can be used to decrypt the user's record)... but an incoming, authenticated user needs to come with some kind of secure, private token.
Any guidance much appreciated!
If you are using ADFS 2.0, you can customize the pages.
So you could e.g. take the password, mangle it, write it to AD before invoking the SignIn and then have a claims rule that passes this. Then reverse the process in your application.
Note - I'm not suggesting that this is a "good" solution - just an example of what you can do.
Obviously security needs to be paramount!
Well there is Two ways to get your problem solved.
Customize the ADFS SignOn page(you should anyways take a backup) to create a form that receives users password. It is an webforms aspx page so you should have no trouble doing it. From there you must build your own STS to issue claims to ADFS so that ADFS can in turn pass these to your relying party. Map the custom STS as attribute store to the ADFS
You are just doing things wrong by taking security in your hand. ADFS uses HTTPS for transport level security and secure encryption with SAML 2.0 to handle your information, so another encryption would be no-brainer.
let me know which way you like going

Resources