Daniel Benavides
08/01/2024, 10:35 PMTigerJwtAuthProvider
.
We've followed all the steps laid out in the documentation and the API is still giving us a 401 when passed a JWT in the Authorization Bearer header.
These are the steps we've followed so far:
- Added the user client ID and secret to GoodData
- Stored the user pool JWKs in the GoodData JWK store
- Provisioned a user in both the Cognito user pool and in GoodData
- Authenticated the user using the same client ID and secret
- Used the generated JWT in the GoodData API (GET api/v1/layout/organization
for testing purposes)
The result is still the same: 401 Unauthorized. I tested through the TigerJwtAuthProvider
implementation and it didn’t work either.
Is there a step (or steps) we're missing? Should this approach work?
Thanks in advance.Joseph Heun
08/01/2024, 11:10 PMname
user attribute, as it is only required? Check to make sure you have added the name attribute to a Cognito record.
If you are still facing issues, could you please provide a related traceID from the console?Daniel Benavides
08/01/2024, 11:36 PMJoseph Heun
08/02/2024, 12:16 AMDaniel Benavides
08/02/2024, 5:07 PMDaniel Benavides
08/08/2024, 8:32 PMTigerJwtAuthProvider
? is it the accessToken or the IdToken? I've tested with both and the response is 401 and is telling that there are invalid claims. In the case of the accessToken it makes sense because it does not include the name
in the claims but the idToken does and it returns the same error (the image is the response headers when using the idToken, for the access token it was the same but it specified the name
as the invalid claim)Daniel Benavides
08/08/2024, 8:41 PM{
"sub": "xxxx",
"email_verified": true,
"iss": "<https://cognito-idp.us-east-1.amazonaws.com/xxxx>",
"cognito:username": "xxxx",
"origin_jti": "444261ff-552d-41c0-8229-a70375f68242",
"aud": "xxxx",
"event_id": "50abaede-560b-4c6b-9f30-c226d5db4e89",
"token_use": "id",
"auth_time": 1722914505,
"name": "Loc Admin",
"exp": 1722915405,
"iat": 1722914505,
"jti": "6cd78d1c-a0b9-49f4-9357-82f48f87acb4",
"email": "<mailto:example@email.com|example@email.com>"
}
Daniel Benavides
08/09/2024, 3:34 PMJoseph Heun
08/09/2024, 3:45 PMDaniel Benavides
08/09/2024, 4:06 PMMichael Gray
08/11/2024, 4:44 PMMichael Gray
08/12/2024, 3:25 PMRadek Novacek
08/13/2024, 8:28 AMMichael Gray
08/14/2024, 3:05 PMMichael Gray
08/15/2024, 7:11 PMRadek Novacek
08/16/2024, 1:32 PMThe JWT contains invalid claims: [name].
, but under the hood, this is only following Signed JWT rejected: Another algorithm expected, or no matching key(s) found
.Daniel Benavides
08/16/2024, 3:23 PMMichael Gray
08/19/2024, 3:46 PMRadek Novacek
08/20/2024, 8:00 AMMichael Gray
08/20/2024, 11:48 AMRadek Novacek
08/20/2024, 12:02 PM/api/v1/entities/jwks
endpoint so that we can go over these and verify everything is as it should be? Many thanks in advance! 🙂Radek Novacek
08/21/2024, 9:10 AMMichael Gray
08/21/2024, 1:53 PMRadek Novacek
08/22/2024, 12:25 PMThe JWT contains invalid claims: [name].
is trying to report the "name" claim is missing entirely (which makes it invalid)..
I know you mentioned you tried the ID tokens before, however from the logs, I can only find Token is not a valid Jwt
errors. Do you think you could try to test the setup with ID tokens? Worst case, we get another error to follow, and if I get the token used alongside it, we should know exactly where to go next!Daniel Benavides
08/22/2024, 2:54 PMRadek Novacek
08/26/2024, 1:42 PMRadek Novacek
08/26/2024, 3:14 PMMichael Gray
08/26/2024, 3:46 PMRadek Novacek
08/27/2024, 10:19 AMReactDOM.render(
<React.StrictMode>
<AuthProvider>
<App />
</AuthProvider>
</React.StrictMode>,
document.getElementById('root')
);
(the implementation can differ based on your app structure, but this would provide the auth context to the whole app - I found a 3rd party article that describes a seemingly good way to do this for Cognito here)
That way, when you embed the actual GD.UI Dashboard, you can use the GD-provided authentication provider from the documentation. On loading the component, the login flow will recognize that there is no session, attempt to authenticate with Cognito, identify the current session from the parent app, and then load the Dashboard. It's worth keeping in mind that this approach can result in a brief flash of a "no session" error from GoodData, we are currently investigating the login flow implementation and improvements are likely going to arrive soon, but for the time being, it's possible to work around this error by checking for the state of the backend - a simplified example is here:
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(() => {
backend.currentUser().getUser().then(() => setIsLoggedIn(true));
}, []);
return (
<BackendProvider backend={backend}>
<WorkspaceProvider workspace={workspaceId}>
{isLoggedIn ? <Dashboard dashboard={dashboardId} /> : <div>{ a loading screen would go here }</div>}
</WorkspaceProvider>
</BackendProvider>
);
The error mentioned above only shows up for the first load of the Dashboard in the session though, any subsequent switches to the tab should be seamless.
Overall, since this relies on OIDC, it's as secure as any other OIDC flows are, and unless any unexpected issues arise, it's relatively straightforward as well! Please let me know your thoughts, I'd be happy to elaborate 🙂Michael Gray
08/27/2024, 12:35 PMDaniel Benavides
08/28/2024, 12:17 AMDaniel Benavides
08/28/2024, 12:19 AMMichael Gray
08/28/2024, 1:35 AMexport const ReportDashboard = () => {
const authContextValues = useContext(AuthContext)
console.log(authContextValues)
const backend = tigerFactory()
.onHostname(indigoGoodDataDomain)
.withAuthentication(new ContextDeferredAuthProvider(redirectToTigerAuthentication))
return (
<BackendProvider backend={backend}>
<WorkspaceProvider workspace={workspaceId}>
<Dashboard dashboard={idRef(reportId)} />
</WorkspaceProvider>
</BackendProvider>
)
}
The authContextValues
is our stored CognitoUserSession and logs in this component as:
const authContextValues = {
idToken: {
jwtToken: '*****',
payload: {
sub: '*****',
iss: '*****',
'cognito:username': '*****',
origin_jti: '*****',
aud: '*****',
event_id: '*****',
token_use: 'id',
auth_time: 1724806746,
name: '*****',
exp: 1724807646,
iat: 1724806746,
jti: '*****',
},
},
refreshToken: {
token: '*****',
},
accessToken: {
jwtToken: '*****',
payload: {
sub: '*****',
iss: '*****',
client_id: '*****',
origin_jti: '*****',
event_id: '*****',
token_use: 'access',
scope: '*****',
auth_time: 1724806746,
exp: 1724807646,
iat: 1724806746,
jti: '*****',
username: '*****',
},
},
clockDrift: 0,
}
With this set up, the ContextDeferredAuthProvider
still isn’t able to authenticate to Cognito and we are redirected to tiger authentication url every time. After we complete that login flow, we are redirected back to our app and are able to see the dashboard correctly. Are there any other steps we are missing? Or what is the ContextDeferredAuthProvider expecting to consume from our AuthProvider that we are missing?Radek Novacek
08/28/2024, 8:25 AMInvalidBearerTokenException: Token is not a valid Jwt
- I'll double-check the contents internally!Michael Gray
08/28/2024, 5:54 PMInvalidBearerTokenException: Token is not a valid Jwt
- I’ll double-check the contents internally!”
Daniel is wondering if there are any updates around that.
Thanks!Michael Gray
08/28/2024, 5:56 PMMichael Gray
08/28/2024, 5:58 PMRadek Novacek
08/29/2024, 8:36 AMRadek Novacek
08/29/2024, 11:02 AM