Azure B2C (IEF/Custom Policy) - State parameter - azure-ad-b2c

I have the following flow for sign in / sign up, when using sign-up:
Present user with sign up screen, allow them to enter email/password/name
Validate input, then send email (rest api) and set verification attributes in b2c custom extension properties
User then receives email with verification link
User clicks link from email and gets sent to a new user journey for the return trip
New user journey gets parameters from the querystring (email + verif code)
B2C validates the verif code + expiry
IF user is verified, they're set as verified via custom extension attributes, then sent to the (ASP.NET MVC) application.
Here's where I'm stuck - B2C is sending the jwt token back to the app, but the user doesn't get 'signed-in'.
Am I missing something at step 7? I don't have the "state" variable in my querystring, am I expected to build and include it somehow so that B2C and the app can communicate? I'm lost at this point. I'd post some of the b2c policy xml but not sure what would even help...
EDIT: reply to Jas:
Is that the only way (make an app call b2c for an auth request)? We have multiple apps that a user can use to sign up through b2c, so I was hoping to avoid having to make changes to each of them. Instead I was hoping that B2C could tell the app after account verification that "this user is ok".
I did previous look at https://github.com/azure-ad-b2c/samples/tree/master/policies/sign-in-with-magic-link (written by you!), but again, was hoping I could avoid having to do that work inside of each of our apps.
Here's an example of the jwt 'id_token' I'm trying to pass to the app:
id_token
Side note: Is 'id_token' the same as 'id_token_hint'? I couldn't find whether they're the same or different when googling it.

What you need to do is send the invite link in the email as a link to the app, eg https://myapp.com?id_token_hint=value.
Then have your apps account controller make an auth request to the policy to complete the account redemption along with an extra query parameter “id_token_hint=value”. Now a proper auth can happen with your applications openId middleware initialised.

Related

Azure SignUp policy needs to return to a different application

I have an Azure policy which works well for authentication users of different roles. I now need to add a SignUp component to this but there are some requirements that I'm not sure are possible.
I need the policy to return back to a different application than what called it. Say App A has the signup link on it's login page which will invoke the
policy's SignUp userjourney. However, I need it to not return back
to that same App, instead redirect to App B along with those claims
it's gathered. Is this even possible?
If it were possible (above), how can this be set up under the relyingparty
section? I would need to keep what is already there for the
userjourney that authentications users, but now also somehow provide
what's needed for this SignUp flow.
I am sorry if this is vague. I am just looking to get unstuck. If anyone could provide any sort of nudge in the right direction, I'd be very grateful.
This idea will not work. This is because, for at least the MSAL authentication library, it will reject a token response if MSAL was not the one who initiated the request. That is built in protection to most libraries, and uses the state parameter in the authentication request to apply this protection. Only responses that come back with the same state parameter will be accepted by the app.
You need to create a link from App 1 to App 2, and have App 2 initiate the Sign Up B2C policy.
The token response URL is controlled by the redirect_uri parameter in the authentication request. Your app will always require this to be configured within it. Both apps should provide a redirect_uri to send the token back to the respective App.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/openid-connect#send-authentication-requests

DocuSign JWT Grant how to get GUID userId of the user to impersonate?

I am doing service integration with DocuSign platform using JWT Grant auth type. DocuSign account has multiple users setup.
My service is SendEnvelopService and one of the important request param to the service is user email. SendEnvelopService need to impersonate user with given email-id when calling DocuSign and send envelope in behalf of that user. Note that every request to SendEnvelopService will have different value of email request param.
I have following questions around it -
Question#1) Since I need to impersonate different user every time (based on email id in my request), I assume I need to get new JWT auth token every time, before making actual api call. Is that right? Is it usual and ok to request new JWT auth token so frequently before every api call? Does it raise any integration concerns with DocuSign?
Question#2) In my request, I have email id of the user to impersonate. I don't have user's GUID which I need, to get JWT auth token and impersonate it. Is there any api that I can use to get user GUID by email id? I wonder what kind of authentication will be needed for such api because I don't have JWT auth token yet.
One idea I have is may be I need to setup one admin user in DocuSign and keep admin userId (GUID) in application config. Now I have 2 users, one is admin user and another is request user which I have email from the service request. I can following steps -
Do requestJWTUserToken impersonating admin user. We get
oAuthTokenAdmin
Using oAuthTokenAdmin make
https://developers.docusign.com/esign-rest-api/reference/Users/Users/list
api call to get userId (GUID) of request user email.
Now do another requestJWTUserToken impersonating request userId. We
get oAuthTokenUser
Now make actual api call using oAuthTokenUser and to send envelope
Go to:
https://admindemo.docusign.com/
Log in with your demo (sandbox) credentials.
Then you have two options:
If it is only for you, simple thing is to click "API and Keys" page under Integrations on the left nav.
You will see this:
You can also click on "Users" on the left and select the user you want, any user really, doesn't have to be you.
then you'll see it under this:
For your first question, no, you don't have to do that. You can use the same user for all API calls. Especially if this user is an admin, then you can do all API calls under that context.

Need clarification of Invitation flow in WingTipGames

I'm building an API to support user provisioning for other application teams around my company. I have a decent understanding of custom policies and have reviewed the invitation flow in WingTipGames, however the sample app is at times hard to follow given the sheer amount of functionality it offers. I would appreciate some clarification around what features I can ignore, vs what is required to support my use case.
Use Case:
My API's CreateUser method creates the user in B2C with ADGraph, then should generate an invitation link that includes a signed JWT with the user's email address, and finally email the link to the recipient. The new user will click the link, which should redirect them directly to the Invitation policy to reset their password.
Clarification Needed:
I'm struggling with simple generation of the Invitation link. What's shown in the sample seems overly complex for my API. In general I'm confused about the OIDC setup given that my API itself (while separately requiring callers to authenticate) will not be involved at all when the recipient clicks the invite link. And as this is an API not an MVC app, I wonder if the process can be stripped down vs the invitation flow in WingTipGames.
Why is ChallengeAsync called in the Invitation\Create method? Presumably this is why we then land in the OnRedirectToIdentityProvider event. Is the challenge what is somehow intercepted and translated into the invitation link?
Are the classes in WingTipCommon relevant here? Namely the AspnetCore.Authentication.OpenIdConnect extensions, handler, and middleware. Asking because users should never arrive at the API in response to clicking the invite link so perhaps the extra plumbing is unnecessary.
Users will always be in a new browser and session when the click the redeem the invitation link, and will redirect directly to the policy (if I understand correctly). Do I still need to worry about the skipCorrelation and XSRF handling?
Any other general suggestions around what to pull out of the sample and what to ignore to support my use case are appreciated.
Thanks
Mark
The Wingtip Games application implements the following flows for invitations:
An invitation link to an application endpoint. This invitation link contains the e-mail address of the invited user, an invitation expiration, and a HMAC-based signature. When the invitation link is opened, the application endpoint validates the HMAC-based signature and the invitation expiration and, if they are valid, then it redirects the invited user to the policy endpoint. This policy redirection contains a signed JWT with the email address of the invited user.
An invitation link to the policy endpoint. This invitation links contains a signed JWT with the email address of the invited user.
I prefer and recommend the first flow for invitations because the application endpoint can implement the invitation logic before the invitation policy is run (e.g. the application endpoint can validate the invitation expiration and, if it isn't valid, then it can display an error message) as well as after the invitation policy has run (e.g. the application endpoint can display a success message).
To answer your specific questions:
Why is ChallengeAsync called in the Invitation\Create method?
This is called for the second flow for invitations. It is called so that the authentication middleware can generate the invitation link and send the invitation message. It is implemented like this so that the application logic doesn't have to be aware of the application identifier, the policy identifier, or the redirection URIs that are required for the invitation link.
Are the classes in WingTipCommon relevant here?
They are used to support the second flow for invitations. See the next answer.
Do I still need to worry about the skipCorrelation and XSRF handling?
This is implemented for the second flow for invitations. As result of the invitation policy, Azure AD B2C issues an authentication response to the client application, where this authentication response is processed by the authentication middleware. Because the authentication middleware doesn't invoke the invitation policy (i.e. it is invoked by the invitation link), then the authentication middleware must be configured to disable the built-in checks for correlation of an authentication request with an authentication response.

Docusign Integration with my application with single sign on process

Our web application procedure is like
The docusign account user needs to use his/her own credentials to log in our application and can see the documents in our application sent him by our client.
For this how can we proceed with docusign .
any procedure with restapi will be helpful for us.
Yes this is a common workflow- you need to use OAuth which let's you accomplish this in a secure way so that your application never sees the user's account credentials (instead it gets a valid access token to use on their behalf).
Since you have a web app you should use the Authorization Code Grant flow, the steps for Auth Code grant are:
Request the Authorization Code
Obtain the Access Token
Retrieve User Account Data
NOTES
In Step #1 your app needs to construct the proper authorization URI including query parameters and direct the user there so they can sign in using the standard DocuSign login. Once the user logs in and grants consent they are redirected back to your app along with an authorization code as a query parameter.
In Step #2 you use the authorization code retrieved from the first step to exchange for an access token. This is an actual API call (as opposed to simply redirecting the user like step 1).
Step #3 is another API call your app needs to make to finally get the user's account data and base_uri where you can then start making requests on their behalf.
For more info see the following guide from the DS Dev Center:
Authorization Code Grant

how to get Azure Active Directory B2C working with Bot Framework?

so far I've not been able to get this working with the bot framework. I spent all day but only managed to get .net api example (https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet) working with AD B2C. I'm not sure where it grabs the bearer token that I want to pass to BotUserData...
I've tried following https://azure.microsoft.com/en-us/blog/bot-framework-made-better-with-azure/
but in reality the solution does not build successfully and I've resorted to just taking code from there and into my bot framework sample template....however, when it asks me to login through MS and I do, I am not able to proceed and it doesn't seem like that blog is using the AD B2C policies.
so how do you integrate AD B2C with Bot Framework? Is it possible to call /Account/SignIn URL from bot framework to authenticate the user? Afterwards, how would you capture the token and pass it to BotUserData?
You might want to take a look to the Facebook Auth sample to get an idea of a potential flow for the Auth scenario. For Azure AD, you need to do a similar flow.
Let's say your user send a "Login" message to your bot. The bot should respond with an auth URL and ask the user to login to the service using that URL. You can use the GetAuthorizationRequestURL method of ADAL for that.
Then you will have a Web API which will basically expose an endpoint that will be the reply URL of Azure AD. Once the users completes the login, a message will be posted to your Web API where you will be able to get the authorization code and perform the calls to get the Access Token. After that, you can just do the same they are doing in the Facebook Sample Web API which involves resuming the conversation with the Bot, sending a message with the access token (so it can be persisted in the PerUserInConversationData bag (check this line of code).
After that you have the access token available to perform any call that requires an access token.
Update
There are two new samples that you might want to take a look since they are implementing the workflow being discussed.
GraphBot from the BotBuilder repo.
AuthBot from Mat Velloso
Hope this helps.
Follow this tutorial for Bot side code development, i focus on configuration at B2C and Azure level here:
OAuth Connection
Client id
This is taken from the Application ID field in your B2C app's properties. It's the equivalent of a Microsoft app ID taken from any other AAD app registration.
Client secret
This is generated using the steps in this tutorial.
Select Keys and then click Generate key.
Select Save to view the key. Make note of the App key value. You use the value as the application secret in your application's code.
Use AAD V2 configuration in oAuth settings in bot channel registration - new oauth connection settings.
Fill the above details by following the steps and values we got from them.
Authorization/Token/Refresh URL
I followed on this one with
https://login.microsoftonline.com/tfp///oauth2/v2.0/authorize
for the Authorization URL and
https://login.microsoftonline.com/tfp///oauth2/v2.0/token
for the Token and Refresh URL's.
For I used the URL format (kyleorg.onmicrosoft.com) rather than the GUID format, but using the GUID also seems to work.
is the name of a user flow, like B2C_1_userflow. I created one with this tutorial.
Scopes
Using the scopes openid offline_access I am able to sign in successfully, but to my astonishment the token returned is empty.
Then I found this document which suggests using the client ID itself as a scope.
When I reuse the value from the Client id field in my Scopes field, a token is returned successfully and my bot is able to use the connection.
You can combine this with other scopes as needed, but for the sake of experimentation I highly recommend getting the simplest implementation to work first.
Let me know if these instructions work, and if they don't then we'll see if the difference lies in how we've set up our B2C apps.
As a bonus, I should mention that after you get a token you can paste it into https://jwt.ms/ to decode it and see if it recognized your B2C user correctly. Always refresh the page when pasting a new token to make sure it doesn't keep showing you the information from the last token.
Referred this document.

Resources