我正在尝试通过 Spring Security 6 并设置 oauth2。为了获得令牌,我尝试使用客户端的
client_secret_jwt
身份验证机制。
但经过多次尝试,我还是无法做到。
这是我注册客户的代码:
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient registeredClient =
RegisteredClient
.withId(UUID.randomUUID().toString())
.clientId("client")
.clientSecret("secret_secret_secret_secret_secret")//.tokenSettings()
.clientAuthenticationMethod(
ClientAuthenticationMethod.CLIENT_SECRET_JWT)
.clientSettings(ClientSettings.builder()
.tokenEndpointAuthenticationSigningAlgorithm(SignatureAlgorithm.RS256)
.jwkSetUrl("http://localhost:8080/oauth2/jwks")
.build())
.authorizationGrantType(
AuthorizationGrantType.CLIENT_CREDENTIALS)
.redirectUri("https://www.manning.com/authorized")
//.clientSettings(ClientSettings.builder().build())
.scope("CUSTOM")
.build();
return new InMemoryRegisteredClientRepository(registeredClient);
}
这是我的代码,用于生成使用上面定义的密钥签名的 jwt 令牌。
@Bean
public JWKSource<SecurityContext> jwkSource()
throws NoSuchAlgorithmException {
/* A different method */
JWKSet jwkSet = new JWKSet(rsaKey);
try {
//printing a token at startup
String assertion = getJWTToken("client");
logger.info("Created assertion: "+assertion);
} catch (Exception e) {
logger.info("Error creating assertion: "+e.getLocalizedMessage());
e.printStackTrace();
}
return new ImmutableJWKSet<>(jwkSet);
}
private String getJWTToken(String username) {
//using the secret key
String secretKey = "secret_secret_secret_secret_secret";
String token = Jwts.builder()
.subject(username)
.issuer(username)
.id(UUID.randomUUID().toString())
.audience().add("http://localhost:8080/oauth2/token").and()
.issuedAt(new Date(System.currentTimeMillis()))
.expiration(new Date(System.currentTimeMillis() + 600*1000))
.signWith(Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8))).compact();
return token;
}
我正在使用开始时打印的断言来调用令牌 API,但在尝试了无数种变化后仍无法获取令牌。
这是我认为应该使用的curl 调用
curl -X POST -v\
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJjbGllbnQiLCJpc3MiOiJjbGllbnQiLCJqdGkiOiIxMjI0NmM4ZC0xZmIxLTRkM2UtODI2NC05OWRhNmYzNTA1NGIiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4MDgwL29hdXRoMi90b2tlbiJdLCJpYXQiOjE3MDc2MzM0ODcsImV4cCI6MTcwNzYzNDA4N30.eYk7T67ue4KrqZqf3Rk06HqwEPRRXpYGSzkbWXtv7zo" \
http://localhost:8080/oauth2/token
这是我不断收到的回复
* Trying [::1]:8080...
* Connected to localhost (::1) port 8080
> POST /oauth2/token HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.4.0
> Accept: */*
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 406
>
< HTTP/1.1 400
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 0
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 11 Feb 2024 06:39:31 GMT
< Connection: close
<
{"error":"invalid_request"}* Closing connection
我不确定我错过了什么或做错了什么。在互联网上找不到任何示例。
我已经能够使用基本方法和后秘密方法获得凭据。
编辑--- 进一步挖掘,发现客户端身份验证时出现异常
Caused by: com.nimbusds.jose.proc.BadJOSEException: Signed JWT rejected: Another algorithm expected, or no matching key(s) found
at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:357) ~[nimbus-jose-jwt-9.37.3.jar:9.37.3]
at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:303) ~[nimbus-jose-jwt-9.37.3.jar:9.37.3]
at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.createJwt(NimbusJwtDecoder.java:158) ~[spring-security-oauth2-jose-6.2.1.jar:6.2.1]
... 126 common frames omitted
我肯定缺少一些配置。
所以在花了几乎一整天之后,我能够获得令牌。
2个变化:
.clientSettings(ClientSettings.builder()
.tokenEndpointAuthenticationSigningAlgorithm(MacAlgorithm.HS256)//not rs256
.jwkSetUrl("http://localhost:8080/oauth2/jwks")
.build())
curl -X POST -v -H \
"Content-Type: application/x-www-form-urlencoded"\
-d "client_id=client&grant_type=client_credentials&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJjbGllbnQiLCJpc3MiOiJjbGllbnQiLCJqdGkiOiIxNDdlMTU5YS05YjU3LTQ4NWMtYTM5Ni1hYzAxOGMyOThmZDkiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4MDgwL29hdXRoMi90b2tlbiJdLCJpYXQiOjE3MDc2NDk2OTEsImV4cCI6MTcwNzY1NTY5MX0.J8G_luq7SMCbyaK_ykRtYdc9h-xEJhyi4RRTuH15w7I" \
http://localhost:8080/oauth2/token