angular-auth-oidc-client
angular-auth-oidc-client copied to clipboard
[Bug]: DataError: The required JWK member "kty" was missing
Critical Notes I am working/testing inside of a closed network which prevents me from posting full internal URLs for security purposes. I've kept as much information intact as possible.
Environment: angular-auth-oidc-client: 13.1.0 Angular CLI: 13.0.0 Node: 16.13.1 NPM: 8.3.0 OS: win32 x64 Browser: Chrome v. 96.0.4664.110
Bug Description: After executing a GET on /openid-connect-provider/discovery/keys and receiving the 200 response, I am getting the following error: [Error] 0-{server client id} - DataError: The required JWK member "kty" was missing
Reproduce
- Build project based on the following sample: https://github.com/damienbod/angular-auth-oidc-client/tree/main/projects/sample-code-flow-refresh-tokens
- Run the app.
Expected Behavior With the "kty" member showing in the GET response, I would expect the module to continue on.
Screenshots
The screenshot below is the Chrome Debugger as the login process was occurring.
The screenshot below is a preview of the response from a GET on https://xxxx.xxxx.com/openid-connect-provider/discovery/keys.
Additional context I've compared additional the json return for ../discovery/keys from a couple other providers all examples look the same.
Hi @ngCorey
I need a bit more info, I don't see what is wrong here. Does the JWT URL exist on the well known endpoints and does this match?
In the network tab, does the request to the JWK URL fail? I have not encountered this problem with multiple different STS implementations and different key types.
Greetings Damien
The GET to the jwksUri (https://ixxx.xxx.com/openid-connect-provider/discovery/keys) succeeds and there is JSON response.
Here's the complete cycle from loading the page until the error happens based on the :
- AuthModule import { NgModule } from '@angular/core'; import { AuthModule, LogLevel } from 'angular-auth-oidc-client';
@NgModule({
imports: [
AuthModule.forRoot({
config: {
authority: 'https://xxx.xxx.com/openid-connect-provider',
redirectUrl: ${window.location.origin}
,
postLogoutRedirectUri: ${window.location.origin}
,
clientId: 'd167b564-ca8d-40ab-807b-a222290368d1',
scope: 'openid',
responseType: 'code',
silentRenew: false,
useRefreshToken: false,
logLevel: LogLevel.Debug
}
})
],
exports: [
AuthModule
]
})
export class AuthConfigModule { }
-
App loads.
-
GET on https://xxx.xxx.com/openid-connect-provider/.well-known/openid-configuration called. a. 200 response is received with the following JSON: { "response_types_supported": [ "code", "id_token", "code id_token", "id_token token", "code token", "code id_token token" ], "claims_supported": [ "iss", "sub", "iat", "exp", "unique_name", "azp", "aud", "c_hash", "at_hash", "nonce" ], "jwks_uri": "https://xxx.xxx.com/openid-connect-provider/discovery/keys", "grant_types_supported": ["authorization_code", "refresh_token", "password"], "subject_types_supported": ["public"], "end_session_endpoint": "https://xxx.xxx.com/openid-connect-provider/logout", "id_token_signing_alg_values_supported": ["RS256"], "response_modes_supported": ["query", "fragment", "form_post"], "scopes_supported": ["openid"], "issuer": "https://xxx.xxx.com/openid-connect-provider", "authorization_endpoint": "https://xxx.xxx.com/openid-connect-provider/idp/authorization", "token_endpoint": "https://xxx.xxx.com/openid-connect-provider/idp/token" }
-
The Login button is clicked.
-
AAOCaApp redirected to login of company application.
-
Username/password entered.
-
Redirect with code received: a. https://localhost:40666/? code=b_scbEx5z0P9cXe7744dmwHx.fqd1oLq1pRRSLKbBrLpUyvl8MzmSV_Wz8AX_u0Y.oX54OiEeLmy8xPiG.fflXaSLAmt7CvL0k2Mw3zLjvcEGBbVMU6ZsLjZ449Y3UD_JBkE7KzjDwDy2Emi3ellUMoNBBFwEnvxx2SmyIxZNvLOjSE9463jzGDYTZaSIxxaeAm96hwt4eUVAJ1ETuYP0tM9iK7_ecuDr11_xkYwr.HWAGC_KU69DVaPpAJVyeilp4oACWymRycV4lkKnN.Sv5bB1pVF5wU6tIiinbonL2gK.Yll2C_YzjJeNFQgGmcAztkDE9GruiT6pdz8wtp5lw--&state=67bcb85cf97cea87954c386eb3ce15fb97sSlnORT
-
POST to https://xxx.xxx.com/openid-connect-provider/idp/token called with the following payload: a. Form Data type: grant_type: authorization_code client_id: d167b564-ca8d-40ab-807b-a222290368d1 code_verifier: 482f1568386a98b0341e318b695c649ecee348097879a766c9c1b2aebb1b5yT81YN code: b_scbEx5z0P9cXe7744dmwHx.fqd1oLq1pRRSLKbBrLpUyvl8MzmSV_Wz8AX_u0Y.oX54OiEeLmy8xPiG.fflXaSLAmt7CvL0k2Mw3zLjvcEGBbVMU6ZsLjZ449Y3UD_JBkE7KzjDwDy2Emi3ellUMoNBBFwEnvxx2SmyIxZNvLOjSE9463jzGDYTZaSIxxaeAm96hwt4eUVAJ1ETuYP0tM9iK7_ecuDr11_xkYwr.HWAGC_KU69DVaPpAJVyeilp4oACWymRycV4lkKnN.Sv5bB1pVF5wU6tIiinbonL2gK.Yll2C_YzjJeNFQgGmcAztkDE9GruiT6pdz8wtp5lw-- redirect_uri: https://localhost:40666 b. 200 response received with the following JSON: { "access_token": "Goz5gIUxfGaowHgmzQSMirg6hNqSKC2b", "refresh_token": "KH4Dpe7WaNi4jIZHWFl6dk8wVUiawHqm", "id_token": {valid token}, "token_type": "Bearer", "expires_in": 3600 }
-
GET from https://xxx.xxx.com/openid-connect-provider/discovery/keys called. a. 200 response received with the following JSON: { "keys": [ { "kty": "RSA", "x5t#S256": "3axXI-YVSCwgH1ymjZyyyJmRwmNhn50auUYtmKASuog", "e": "AQAB", "use": "sig", "x5c": [ "{valid data}" ], "alg": "RS256", "n": "{valid data}" } ] }
-
Error appears.
Let me know if there's ANYTHING else I can provide for information. Thank you for all your hard work on this!!
Corey
Getting the same error after upgrading from 11 to 13
https://{domain}/.well-known/jwks:
{
keys: [
{
kty: "RSA",
n: "{valid data}",
e: "AQAB"
}
]
}
Client:
[ERROR] 0-e579832f-8373-46a7-8624-25e5b84b92a8 - DataError: The required JWK member "kty" was missing
@ngCorey @damienbod I can't seem to figure out where this error is thrown. Any pointers on your side?
Can you compare your keys to this?
https://offeringsolutions-sts.azurewebsites.net/.well-known/openid-configuration/jwks
Also check if the URL gets called in the network tab of F12
Greetings Damien
@damienbod It gets called, and here's the two outputs. They both have the "kty" key (at the same position). If you can pinpoint me to where (in the code) this error is thrown, I could see if I can figure it out.
{
keys: [
{
kty: "RSA",
n: "{valid data}",
e: "AQAB"
}
]
}
{
keys: [
{
kty: "RSA",
use: "sig",
kid: "5626CE6A8F4F5FCD79C6642345282CA76D337548RS256",
x5t: "VibOao9PX815xmQjRSgsp20zdUg",
e: "AQAB",
n: "{valid data}",
x5c: [
"{valid data}"
],
alg: "RS256"
}
]
}
@damienbod Any news on this? If you can pinpoint where the exception is thrown, I could take it further.
@ngCorey Did you get anywhere with this?
@andreaslarssen I have not gotten any further on this, but I was forced to move on to other stuff. If I gain traction, I'll post it here.
Any update or workaround on this issue?
@damienbod Anything?
@damienbod I think I found the issue. https://github.com/damienbod/angular-auth-oidc-client/blob/9fc89c8a6ce8af4a2abd528c484326a6f0fa5f64/projects/angular-auth-oidc-client/src/lib/validation/token-validation.service.ts#L343-L357
The code here seems to expect that the kid
parameter exists, while RFC7517 states that it's optional.
The result is that if the jwks endpoint only has a single key, and that key does not have kid
, no key is found, which in turn seems to fail here: https://github.com/damienbod/angular-auth-oidc-client/blob/9fc89c8a6ce8af4a2abd528c484326a6f0fa5f64/projects/angular-auth-oidc-client/src/lib/validation/token-validation.service.ts#L370
You can reproduce the result directly in the browser console by running window.crypto.subtle.importKey('jwk', null, {name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256'}, false, ['verify'])
It also seems like this was fixed in an earlier PR by @andreaslarssen here
@damienbod I added a PR just now: #1517
@ngCorey , @dbrils and @andreaslarssen You're very welcome to test the PR for issues if you have the time.
@damienbod This issue can be closed now. @erichjsonfosse tested the PR and it seems to work as expected