I'm trying to use Amplify Auth to implement an OpenID Connect Implicit Flow to provide SSO to a number of React clients.
I've been able to get this working with Cognito Hosted UI, but that requires other apps users to click a button to confirm login in order to authenticate. I'd prefer for it to be seamless ie when a user is logged in on one site and navigate to another they are automatically authenticated if they have a session with the auth provider.
To try and achieve this I've set up a separate Amplify app that uses the React Authenticator Component.
I'm able to authenticate with this and redirect back to the client. However the id_token
doesn't contain the at_hash
or nonce
claim. Presumably, the at_hash
is missing because the authentication provider app is not sending the responseType
of token id_token
when it authenticates with Cognito. The nonce
is missing because I haven't found a way to pass it in.
Is there a way to get Amplify Authenticator SignIn to request an id_token
with the at_hash
claim?
Is it possible to pass a nonce
value through to the id_token
claims?
Note I'm trying to adhere to: https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowSteps Specifically for this part: 3.2.2.10. ID Token
import React from 'react';
import { Authenticator, ConfirmSignIn, SignIn } from 'aws-amplify-react';
import Amplify, { Auth } from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
const getSearchParams = () =>
window.location.search.substr(1);
const getValueFromSearchParam = (key) =>
new URLSearchParams(getSearchParams()).get(key);
const getRedirectUri = () => {
const redirect_uri = getValueFromSearchParam('redirect_uri');
return redirect_uri ? decodeURI(redirect_uri) : null;
};
const Login = () => {
const handleAuthStateChange = (state) => {
if(state === 'signedIn') {
const redirect_uri = getRedirectUri();
const state = getValueFromSearchParam('state');
if(redirect_uri === null) {
throw new Error('No redirect_uri provided');
}
Auth.currentSession().then(currentSession => {
const id_token = currentSession.idToken.jwtToken;
const access_token = currentSession.accessToken.jwtToken;
const redirect = `${redirect_uri}#access_token=${access_token}&id_token=${id_token}&state=${state}`;
window.location.replace(redirect);
}).catch(err => console.error(err));
}
};
return (
<Authenticator
hideDefault={true}
onStateChange={handleAuthStateChange}
>
<SignIn />
<ConfirmSignIn/>
</Authenticator>
);
};
A few points to consider:
If it helps, my blog's introductory code example uses Cognito with the Hosted UI (not the custom UI). I can confirm that you can use SSO across multiple apps without prompts.