Hi all, my team is building a healthcare React application and we are using Auth0 for authentication. We are required to have SAML integration for healthcare institutions.
I have set up the Assertion Consumer Service endpoint in our application. I have set up a Keycloak instance as our internal test IDP. Right now, it is able to receive SAML responses with the assertion from the test IDP.
From here on, I’m not sure what to do next. I have read that I can request an auth token using the SAML assertion. When I try invoking this command:
curl -X POST “/oauth/token” -H “Content-Type: application/x-www-form-urlencoded” -d "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&assertion=<64 base encoded assertion>
I get " {“error”:“unauthorized_client”,“error_description”:“Grant type ‘urn:ietf:params:oauth:grant-type:saml2-bearer’ not allowed for the client.”,“error_uri”:“”}"
Welcome to the Auth0 Community and thank you for your post!
Even though what you are specifying here is correct when it comes to standard OAuth 2.0 flows, this is not a standard way of processing SAML assertions in Auth0, so that is why the error mentioned shows up. When the assertion is validated in Auth0, a user session is created right away.
The recommended approach would be using one of our SDK’s, such as the Auth0-React in your use case ( you can check out the documentation here ) which handles the SAML response automatically, as well as generating the tokens. Then you can initiate the login using:
Another question. Now I am confused a little by the Assertion Consumer Service endpoint. Is this an endpoint I need to build myself that sits on my app’s backend, or can Auth0 already handle receiving the SAML assertion and redirect back to my app?
There is also no need for you to create the ACS endpoint in your backend, since consuming the Assertion Process is being done automatically within Auth0 since its role is acting as the Service Provider, being sort of the middleman between your React App and the Idp.
Auth0 will also automatically send the user to your configured Allowed Callback URLs once the authentication is complete on the Idp’s side.
Last question - I have reconfigured our application to callback to /login. After logging into the IDP, which is successful, the browser does successfully redirect to our /login, but then gets stuck in a loop. On the login, we call getAccessTokenSilently first and that fails with “Login required”. It feels like I am missing something because like you said, Auth0 is automatically doing all the redirect work.
Firstly I would not recommend setting your callback function to your /login, but to the Root URL directly or a simple /callback route, since that should be the reason why this is causing a loop in your application. A few details on setting the Callback URL in a React app can be checked using this community post.
The “Login required” error is most likely caused by calling getAccessTokenSilently at the wrong moment in time. The SDK might still have to parse the code and state parameters received from the Idp, so it might not have processed the full authentication flow yet and an unauthenticated session is being returned. I can recommend checking the isLoading and isAuthenticated functions from the useAuth0 hook in the React SDK.