Comments (12)
@uxweb Hi, I don't recommend to distribute the password inside idP setting, SAML SSO helps you to do Authn and the response can include other information, not only username and email, that's just the minimal example.
In your case, you need some sort of associations between your drupal side and sso side. So the SAML response might also include the required information that used to request an access token.
Flow:
- SPA App redirects to idP login portal
- Sign in to idP successfully and returns the SAML response
- SAML SSO is kind of OAuth2 app, the idea is like that you can take the
login
from SAML response (i.e. the username or email), then withclient_id
andclient_secret
that stored in your SPA app backend, to initiate the OAuth2 process
The following is the normal flow of OAuth2
- Access the authorize endpoint on your Drupal api side with
login
which is obtained from the SAML response. - Returns a short expiry
code
(i.e. 10 minutes) from the Drupal side - Your SPA App backend sends that
code
withclient_id
andclient_secret
back to Drupal side to obtain the access token - Drupal side returns the access token with that particular user that you are associated with in step 4.
from react-samlify.
Thank you very much for the insight Tony, I really appreciate it!
According with step 3 of the flow:
Once the idP returns a successfully response, the React App must be able to register the user within Drupal using a Client Credentials OAuth2 Grant Type
, this way the only thing I need is an email
coming from the idP and a client_id
and client_secret
from Drupal right?.
And then on step 4:
Then, once the user is registered I will need to start another OAuth flow to obtain an access token for the registered user. It is in this step where a new doubt arises. After the user is registered, the user does not have a password assigned, then I could not start an Authorization Code
grant flow. Is there another OAuth2 grant type that could be suited for this situation?
Please let me know if I'm misunderstanding some point.
Thanks in advance Tony
from react-samlify.
Sorry, I missed something above.
After the idP returns a success response, since it's a new user (assume there is no record in the database) in your application, so that you need to register a new user.
-> I misunderstood it previously.
Let me redeclare it, OAuth2 means to do authorization, not authentication. For user creation, you need to create that with normal flow as a single source of truth.
- Register and create a new user from your application through the current flow
- When a new user is registered, it should have a button to allow user to opt in SSO, then you have to connect to Azure AD and create a new record on AD in order to activate the SSO function for that particular user.
Next time when the user comes back
- SPA App redirects to idP login portal
- Sign in to idP successfully and returns the SAML response
- SAML SSO is kind of OAuth2 app, the idea is like that you can take the login from SAML response (i.e. the username or email), then with client_id and client_secret that stored in your SPA app backend, to initiate the OAuth2 process
- ...
- ...
- ...
- ...
I took github's implementation as example, and they are using grant type Authorization Code
. You will obtain the short expiry code
from step 5 with client_id
, client_secret
and username
from SAML response sent by iDP, then use code
to obtain the access token, so you don't need password throughout the entire process.
Remarks: client_id
and client_secret
are on application level, not user level, but access_token
is on user level.
from react-samlify.
TLDR;
- OAuth2 is not designed for new user creation, it's used for authz of existing users
- SAML SSO does Authn, then Drupal side does Authz, in your use case
from react-samlify.
Thanks for your reply Tony!
Currently, the user registration flow happens to be on the Drupal side. There I have SSO configured as well, so that flow allow users to authenticate with the idP and be registered in Drupal when idP responds back.
But now, with a headless Drupal, users are not interacting with Drupal directly anymore, only administrator users are going to access Drupal to do administrative tasks but that's another story. This is why I mentioned that once the auth flow from the React side is successful, React must be able to register that user through Drupal API.
Here is a more detailed diagram:
The user registration step must be automatic when a user authenticates successfully with SSO in the React side because right now there is no other way I can register them. I might need to code some logic in the React app to verify if the user is already registered in Drupal, if it is not registered then I need to register it, but if it is registered I only need to request an access token.
The step I still don't understand is the momento to obtain a token from Drupal. Currently, Drupal only support: password, client_credentials, authorization_code and implicit grant types, which in this case I think none of them will let the React app ti obtain an access token with only username
, client_id
and client_secret
. Is this a case for a "custom" grant?
Please let me know if I'm bugging you. I really want to understand and get to the best solution for this use case! I am willing to pay you for advisory!
from react-samlify.
@uxweb Nice, so you migrate the authentication completely to the iDP now.
I think it should use authorizatioin_code
? There are two steps.
- Pass
username
,client_id
to the/authorize
endpoint on Drupal side. Drupal side will return acode
to the givenredirect_uri
. - React App would take this
code
, withclient_id
andclient_secret
to the/access_token
endpoint on Drupal side in order to obtain the access token.
from react-samlify.
Yes, authentication is done from the idP only, but it is a SAML2 SSO.
To authorize the React authenticated user with the Drupal Api you suggest to send the username
, client_id
and client_secret
to get a temporary code
that can be used to obtain an access token
right? Then I would need to create a custom endpoint in Drupal to do so because the standard OAuth grant types doesn't allow this kind of flow, is this correct? I think the endpoint could be /oauth/code
.
Then once having that code, I could send a request to my oauth/token
endpoint sending the following fields:
- grant_type:
custom_grant
- client_id:
the client id
- client_secret:
the client secret
- code:
temporary code
I think this endpoint should return a new access token that can be used to consume the Drupal Api, is this correct?
I'm asking this because I'm trying to use any of the standard OAuth flows, but it seems that none of them fit this use case.
Please, let me know if I'm misunderstanding these steps.
Thanks in advance Tony!
from react-samlify.
https://www.drupal.org/node/1958718
https://cxlabs.sap.com/2012/06/01/oauth2-authorization-code-flow/
Which oauth library are you using on drupal side ? I see the authorization code
flow that fits your case. You mentioned none of grant types you see that fits this use case, so I want to know what is the specification of authorization code
that you are currently using, because that's a pretty standard and common way to handle server side OAuth2.
By the way, the example used (the 2nd link) takes the first step as connect oauth2 then to do re-authentication if that user is not logged in, my attempt is to connect iDP as the first step, but I think either one is okay.
from react-samlify.
Thanks for the info Tony!
I am using simple_oauth module for Drupal:
https://www.drupal.org/project/simple_oauth
This module allows me to use authorization code
grant, the issue relies on the third flow depicted in the following diagram:
As you can see, up to step 1 of flow 3 all is great! I can obtain the authorization code
to exchange it for an access token
. But when the user is redirected and asked to login with Drupal credentials, the user will not be able to login because there is no password assigned by Drupal:
A solution to this is that in flow 2 (user registration) I assign a generic password
to the user that is being registered and use the password
grant instead of authorization code
grant in flow 3.
https://oauth2.thephpleague.com/authorization-server/resource-owner-password-credentials-grant/
The password
grant allow me to obtain a token passing the user credentials. User doesn't have to know the password because I am going to assign a generic password for all users. Yes, I know this breaks some security rules, but that's the only way I see to obtain an access token.
Do you think am I overthinking it?
from react-samlify.
@uxweb That could be a way but a generic password is not desirable because of the security concern.
Can we introduce one more step before hitting the /authorize
endpoint ?
- Get back user information from saml response sent by iDP
- Hit another public endpoint to do the following checking
-
If that user is a registered user, redirect to the flow to
/authorize
and go through theauthorization code
flow. -
If that user is not a registered user, register it with a random password but set it to inactive first and send the registration email to user side and let the user complete the last step of registration.
- For the first case, user will get the access token without problem. For the second case, user need to have one more step to complete the registration. (i.e. that user will need to fill the password when they click the link from email).
from react-samlify.
@uxweb Any updates on that ?
from react-samlify.
I will close this issue first since there is no update for 3 months. Feel free to reopen it if needed.
from react-samlify.
Related Issues (4)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-samlify.