我在 Micronaut 中使用 ASP.NET Identity server 4 作为授权服务器,并具有以下配置application.yml
micronaut:
security:
enabled: true
token:
jwt:
enabled: true
signatures:
jwks:
IdentityServer:
url: 'https://localhost:5001/.well-known/openid-configuration/jwks'
我写了AuthenticationProvider
如下
@Singleton
@Requires(env = Environment.TEST)
public record AuthenticationProviderUserPassword() implements AuthenticationProvider {
@Override
public Publisher<AuthenticationResponse> authenticate(HttpRequest<?> httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
return Flowable.create(emitter -> {
if (authenticationRequest.getIdentity().equals("xxxx@local.com") &&
authenticationRequest.getSecret().equals("xxxxx.x")) {
emitter.onNext(new UserDetails((String) authenticationRequest.getIdentity(), List.of()));
emitter.onComplete();
} else {
emitter.onError(new AuthenticationException(new AuthenticationFailed()));
}
}, BackpressureStrategy.ERROR);
}
}
应用程序-test.yml
micronaut:
security:
authentication: bearer
token:
jwt:
signatures:
secret:
generator:
secret: '"${JWT_GENERATOR_SIGNATURE_SECRET:pleaseChangeThisSecretForANewOne}"'
我有一个集成测试,它生成令牌并根据 JWT 的签名进行验证
@Test
@DisplayName("Should authorized the end point")
void shouldAuthorizedTheEndPoint() throws ParseException {
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("xxxx@local.com", "xxxxx.x");
HttpRequest request = HttpRequest.POST("/login", creds);
HttpResponse<BearerAccessRefreshToken> rsp = client.toBlocking().exchange(request, BearerAccessRefreshToken.class);
assertEquals(HttpStatus.OK, rsp.getStatus());
BearerAccessRefreshToken bearerAccessRefreshToken = rsp.body();
assertEquals("admin@local.com", bearerAccessRefreshToken.getUsername());
assertNotNull(bearerAccessRefreshToken.getAccessToken());
assertTrue(JWTParser.parse(bearerAccessRefreshToken.getAccessToken()) instanceof SignedJWT);
String accessToken = bearerAccessRefreshToken.getAccessToken();
HttpRequest requestWithAuthorization = HttpRequest.DELETE(String.format("/category/%s", UUID.randomUUID().toString()))
.accept(MediaType.TEXT_PLAIN)
.bearerAuth(accessToken);
HttpResponse<String> response = client.toBlocking().exchange(requestWithAuthorization, String.class);
assertEquals(HttpStatus.OK, rsp.getStatus());
assertEquals("sherlock", response.body());
}
当我运行集成测试时,它会尝试从 https://localhost:5001/.well-known/openid-configuration/jwks 获取 jwks 并且签名验证失败。
ERROR i.m.s.t.j.s.jwks.JwksSignature - Exception loading JWK from https://localhost:5001/.well-known/openid-configuration/jwks. The JwksSignature will not be used to verify a JWT if further refresh attempts fail
日志
DEBUG i.m.h.client.netty.DefaultHttpClient - Sending HTTP DELETE to http://localhost:43903/category/ba3402df-05fa-4825-9989-fd8e578632cc
21:21:52.509 [default-nioEventLoopGroup-1-5] TRACE i.m.h.client.netty.DefaultHttpClient - Accept: text/plain
21:21:52.509 [default-nioEventLoopGroup-1-5] TRACE i.m.h.client.netty.DefaultHttpClient - Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbkBsb2NhbC5jb20iLCJuYmYiOjE2MjkzNzIxMTIsInJvbGVzIjpbXSwiaXNzIjoiZmV0ZS1iaXJkLXByb2R1Y3QiLCJleHAiOjE2MjkzNzU3MTIsImlhdCI6MTYyOTM3MjExMn0.51D8t8Nk_Ry_YfdAIsRrHiIptTRBSTumrFrk2ykkfXM
21:21:52.509 [default-nioEventLoopGroup-1-5] TRACE i.m.h.client.netty.DefaultHttpClient - host: localhost:43903
21:21:52.509 [default-nioEventLoopGroup-1-5] TRACE i.m.h.client.netty.DefaultHttpClient - connection: close
21:21:52.510 [default-nioEventLoopGroup-1-5] TRACE i.m.h.client.netty.DefaultHttpClient - content-length: 0
21:21:52.628 [default-nioEventLoopGroup-1-6] ERROR i.m.s.t.j.s.jwks.JwksSignature - Exception loading JWK from https://localhost:5001/.well-known/openid-configuration/jwks. The JwksSignature will not be used to verify a JWT if further refresh attempts fail
使用 OpenID Connect 进行集成测试的推荐方法是什么