I'm looking to use an identity service such as Azure B2C, Auth0 or OKTA to secure my application.
After the user signs up for an account, I need to display a custom registration form in my application in order to complete the registration. This form requires a business process behind the scenes and therefore it can't be part of the Identity Service (IDS are quite limited to capturing static data).
How do I ensure the user has completed the registration form on my application, when they sign in?
I'm thinking of using a claim such as "RegistrationComplete" and setting this to False when the user signs up. After they've signed up I can update this claim to be True.
I can't find any information online about this scenario so I not entirely sure its standard best practice.
Disclaimer: I work at Okta
Okta does have some features which should allow this. You can pull properties from the user's profile in Okta and put those properties on tokens as claims when the user is authenticating. So the user profile holds the state you care about. Your app/service can then read this claim from the token to determine if the form should be shown. Once the form is complete, your backend service can use the Okta APIs to update this user profile state, and then send the user through the authorize flow again to get a new token with the updated claim (specifying to not prompt for re-authentication when going through the authorize flow again).
There is a restful provider feature in azure ad b2c. Using the Rest Apis from any service along with custom policies in b2c, we can get user input and save that user input to any database. The REST apis can be used to orchestrate any step.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-rest-api-step-custom
Related
Our OAuth client application is built with Spring (through JHipster). The OAuth provider only serves the authentication functionality, but not the authorization functionality. Ideally, we should only allow a small group of people to access our OAuth client application, but not all those users who can sign in to the OAuth provider.
A solution I can think of at this moment is to create a custom user role to control the access in the OAuth client application. That, however, only can be done after the user's first sign-in when the user account data is created in the application.
Any better solutions?
Ideally you would apply user access control before creating user account data is created in the application. You could do so by providing an application specific scope or claim in the token that is generated for your application (aka. Client). Upon receiving the token, the application would check for the required attribute in the token before allowing access.
How do I best configure Keycloak so that a user needs to have an account for a client to be able to login into that client?
I have to replace a proprietory SSO-Impl. It deals with users, roles and clients much like Keycloak. However, it also knows about accounts. A user is only allowed to login to a client if he has an account for that client.
In Keycloak, if a user simply exists in a realm he may login to a client of that realm. Nothing else is needed. So no "account" is needed. In the old application, he needs an account as well.
What functionality in Keycloak is best suited to overcome this difference?
I have one idea:
Create a client-role in each client namend "HasAccount" and assign it to users. Then, restrict access if that role is missing.
This is discussed here: "Restrict client access in a single realm with keycloak"
It has at least two drawbacks:
It mixes authentication and authorization in the legacy app. I can understand that. But creating a role was already a workaround. That is why I described my initial problem here.
I have clients in 3+ languages/technologies. Adding functionality there seems like more work than in Keycloak.
Last remark:
Before you ask "This is not single sign on" anymore. It is only for administrative purposes. The admin can allow users to login into a client or not by creating an account or not. The user does not have to login a second time. If he is logged in in App A and has an account for App B, accessing App B works without logging in there.
A user is only allowed to login to a client if he has an account for that client. is really not a task for Identity Provider (IdP). It provides only identity and not authorization.
Of course you can ignore that and implement authorization as well. See: User attribute based web service access control by Keycloak
From the design perspective I would add auth reverse proxy in front of legacy app (but it isn't a best solution for SPA apps). Auth proxy will provide authentication via OIDC protocol and also authorization. Legacy apps may keep own OIDC authentication - it will be seamless auth from the user perspective, because SSO will be used.
Account entity - you can use group entity in the Keycloak instead of original account.
I'm following the React OAuth Implicit example shown here: https://github.com/docusign/eg-02-react-implicit-grant and I'm confused as to how an end user of our React SPA is supposed to be able to create an envelope for themselves without having access to our Admin account password.
As part of our app's sign up process, we have our end users fill out a form which prefills an envelope for them to sign via Docusign. We imagined that our Docusign admin account would authenticate our application on behalf of these users behind the scenes, allowing them to move on immediately to the embedded signing ceremony.
In the linked example, however, an end user is prompted via the Docusign UI to sign into our Admin account in order to continue using Docusign's API methods.
How can we avoid asking the end user to sign in? Or is this not possible when using the implicit grant model?
Thanks in advance.
Excellent question. There are many uses cases for DocuSign-integrated applications:
Use case: The signer is using your app
Signers don't need DocuSign accounts. Only the sender of the signing request needs an account.
Option 1: Use a Powerform
The easiest way to handle this use case is to use a DocuSign PowerForm. A PowerForm is a DocuSign envelope template that is implicitly sent by the DocuSign system. The signer can then fill in the form with their name and other details, and then sign the document(s).
Here's a video that demonstrates the Powerform solution.
You can fill in the form on behalf of the signer via query parameters. See this SO answer. Integrating your app with a PowerForm is easy but there may be some aspects of the envelope that can't be set via the template. See this article for details on how to set the URL the user will be redirected to when they finish signing.
Option 2: Create the envelope yourself, then let your user sign it
A more capable option is for your app to create the envelope yourself. You need an access token for a paid DocuSign user to send the envelope. I wouldn't use a system administrator account, just a regular DocuSign account user.
Something like:
Create a user in your DocuSign account such as "HR#your_company.com"
Set up a backend (server app) to use DocuSign JWT authentication to impersonate the HR#your_company.com "user." See the eg-01 series of code examples available in multiple languages.
Write your SPA to either create the envelope itself (after obtaining the access token from the backend) or use a private API to ask the backend to create the envelope. After the envelope is created, obtain the URL for the Signing Ceremony.
Your SPA now redirects the user to the Signing Ceremony (don't use an iFrame). After the user has signed, she will be redirected back to your SPA along with the event info (that she signed). An example of this is the Embedded Signing Ceremony workflow (the first workflow) in the DocuSign Code Example Launchers, the eg-03 series. Here's the Node.js example.
Notes.
Don't use an iFrame since the Signing Ceremony needs the entire screen. A 100% iFrame is not really needed since the SPA can save state in the session via cookies or local storage.
You can set the DocuSign Signing Ceremony to ping your server (AJAX pings) to keep the session alive, serve as a heartbeat, etc.
If you have your SPA create the envelope then you'll need to setup a CORS gateway to enable the SPA to communicate with the DocuSign cloud. This is detailed in the eg-02 example's write-up.
Creating an envelope for the signer as described above gives you maximum control over the envelope including the potential inclusion of attachment documents, payments, etc.
Use case: Your employee is using your SPA app
In this case, your employee can authenticate with DocuSign via the SPA, and then anything with DocuSign via the SPA and the DocuSign API. Eg:
Sending envelopes
Sending the envelope and then having the signer (in person) sign the envelope. Eg a banking application where the bank employee is enabling the in-person signer to open an account.
Monitoring sent envelopes
Whatever
This is the use case being demonstrated by the eg-02 React example.
How do i get access to the currently authenticated users access token in a Keycloak Service Provider Interface when the user has just logged in?
Current situation:
I am doing a manual Password Grant with Apache HttpClient inside a custom User Federation/Storage Provider when the user is performing a login with username and password.
The users access token is then used to call an internal API with his authentication context. This API call with the users bearer token is required for auditing/GDPR purposes since the user gives multiple consents when logging in.
I am assuming there is no way to get the current users authentication context within a user storage provider since the user is not yet authenticated at that point in time, right?
Is password grant the correct way to obtain a user auth context/token at that time? Another option might be to chain SPIs, e.g. use an Authentication SPI and intercept the token there. But it seems you cannot overwrite an existing Auth flow.
The last and maybe best option would be to create an Event Listener Provider. But do i have access to the access token there?
I would really appreciate some input because this whole endeavour feels a bit off.
Another option (which makes more sense for me) would be to use a client id to authenticate as a service (client authentication), in order to perform the auditing. That way you don't even need the user to be authenticated at that point. I see it as a better solution, since, apart what I have said, auditing is actually a system related chore. If you let any user do auditing, they could script some code with a valid token to perform massive/fake auditings by their own.
It makes more sense to leave it to a concrete client, with a concrete role and request that role for the auditing process.
I have an application that currently integrates into my merchant account using my access token. Early discussion with neighborhood merchants indicates some positive interest. I want to integrate OAuth support so that I can try to get traction with those merchants.
Though https://docs.connect.squareup.com/api/connect/v1/#navsection-oauth has information, I seek some additional clarification.
(i) Access using https redirect-url is denied at Square Connect Authorize has an answer "By default the OAuth flow is disabled for applications which is why you are seeing the "Authorization not allowed" failure. If you wish to enable OAuth flow for your application then you need to contact Square." #SquareConnectSupport: I have sent an email to Developer#Square, please let me know what else do I do.
(ii) Here is how I think it will work - the OAuth integration (Please confirm)
User types in browser say "mysnow.com/square"
The Handler at "mysnow.com/square" allows user to type in an ID this ID is local to mysnow
Then the Handler at "mysnow.com/square" directs the merchant to https://connect.squareup.com/oauth2/authorize along with my application id, permissions and redirect url.
The handler then receives a notification code with AuthZ Code at the redirect URL previously provided.
Next the handler obtains the Access token (using the AuthZ code)
Finally, the handler then saves the ID, the AuthZ code , the relevant Access Token and the date/time stamp (when the token was obtained) as a tuple in a safe data store.
(iii) Using the Access Token
When there is need to access merchant data of given ID, then use the ID to get the Access Token. Use this Access Token to manage the permitted data (based on permission)
Renew the access token periodically.
(iv) For testing purposes, I create few test/dummy merchants? Or do you have dummy merchant accounts that I can use for testing.
You can authorize up to ten merchants through the OAuth flow without approval from Square, which should be enough to get your integration running and tested. If you would like to make it more broadly available, you will need to contact Square about getting the app in the Square App Marketplace.
That looks essentially correct. The best practice for OAuth is something like this:
Merchant visits your landing page (e.g. mysnow.com/square) and clicks an action to start using your square integration.
Merchant's browser is redirected to the OAuth page (https://squareup.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&scope=LIST_OF_OAUTH_SCOPES_YOU_NEED)
Merchant authorizes your application to access their data and is redirected back to your site. In the URL is an authorization code
Your backend makes an API call to Square to exchange the authorization code for an access token. It then uses that access token to look up information about the merchant and pre-populate fields of your signup form (e.g. you can get name, email, etc)
With a partially populated signup form on your site, merchant is prompted to complete their registration with your service.
There isn't really a way to create "dummy" merchants, but you can sign up for multiple merchant accounts with the same identity information, as long as you use a different email for each one. If you have GMail, you can do "you+someword#gmail.com" and the mail will be redirected to "you#gmail.com", so you don't need to create a bunch of email accounts to have unique email addresses.