在 Spring Boot 中,在配置资源服务器时,我们可以选择设置security.oauth2.resource.jwk.key-set-uri
属性,如果访问令牌将是 JWT,并且颁发者为客户端提供端点以获取公共 RSA 密钥以进行 JWK 格式的验证。
从此 JWK 启动密钥库的预期行为是什么?该属性正在加载,ResourceServerProperties.JWK
但是然后呢。spring boot 应该调用这个 URI 并获取 jwks 然后创建一个商店供我在验证中使用吗?
我正在按照本教程设置密钥库http://www.baeldung.com/spring-security-oauth-jwt的配置
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
Resource resource = new ClassPathResource("public.txt");
String publicKey = null;
try {
publicKey = IOUtils.toString(resource.getInputStream());
} catch (final IOException e) {
throw new RuntimeException(e);
}
converter.setVerifierKey(publicKey);
return converter;
}
Run Code Online (Sandbox Code Playgroud)
但是.pem
我想我想从jwk
.
如果你想使用JWKS,使用JwkTokenStore
到位JwtTokenStore
。
spring-security-oauth2/jwk内部根据auth0规范实现key加载和管理
您还可以查看有关相同自动配置的文档,但是我觉得配置它非常简单(见下文)。
我们不必进行任何验证,因为JwkTokenStore使用JwkDefinitionSource JwkVerifyingJwtAccessTokenConverter使用公开的JWKS设置验证@Value("{jsecurity.oauth2.resource.jwk.key-set-uri}")
但是,spring 的 spring-security-oauth2/jwk类没有任何公共构造函数,我们经常需要并且可以在 AccessTokenConversion 中执行任何自定义步骤,就像一个常见的需求是将 jwt 内容提取到 auth 上下文中,我们可以随时注入JwkTokenStore的自定义转换器
import org.springframework.security.oauth2.provider.token.store.jwk.*;
import org.springframework.security.oauth2.provider.token.store.*
import org.springframework.security.oauth2.provider.token.*;
import java.utl.*;
@Configuration
class JwtConfiguration {
@Bean
public DefaultTokenServices tokenServices(final TokenStore tokenStore) {
final DefaultTokenServices dts = new DefaultTokenServices();
dts.setTokenStore(tokenStore);
dts.setSupportRefreshToken(true);
return dts;
}
@Bean
public TokenStore tokenStore(
@Value("{jsecurity.oauth2.resource.jwk.key-set-uri}") final String jwksUrl,
final JwtAccessTokenConverter jwtAccessTokenConverter) {
return new JwkTokenStore(jwksUrl, jwtAccessTokenConverter, null);
}
@Bean
public JwtAccessTokenConverter createJwtAccessTokenConverter() {
final JwtAccessTokenConverter converter;
converter.setAccessTokenConverter(new DefaultAccessTokenConverter() {
@Override
public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
final OAuth2Authentication auth = super.extractAuthentication(map);
auth.setDetails(map); //this will get spring to copy JWT content into
return auth;
}
}
return conveter;
}
Run Code Online (Sandbox Code Playgroud)
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
@Configuration
@EnableResourceServer
class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private String resourceId;
private TokenStore tokenStore;
public ResourceServerConfig(
@Value("\${jwt.reourceId}") private String resourceId,
private TokenStore tokenStore) {
this.resourceId = resourceId;
this.tokenStore = tokenStore;
}
/**
* Ensures request to all endpoints ore a
@Override
public void configure(final HttpSecurity http) {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/**").authenticated();
}
/**
* Configure resources
* Spring OAuth expects "aud" claim in JWT token. That claim's value should match to the resourceId value
* (if not specified it defaults to "oauth2-resource").
*/
@Override
public void configure(final ResourceServerSecurityConfigurer resources) {
resources.resourceId(resourceId).tokenStore(tokenStore);
}
}
Run Code Online (Sandbox Code Playgroud)
此实现的主要目标是使用相应的 JWK(JSON WEB TOKEN KEY SET)在本地验证 JWT。用于验证的JWK是使用JWT的kid头参数和JWK的kid属性来匹配的。
服务器可以在本地验证此令牌,而无需发出任何网络请求、与数据库通信等。这可能会使会话管理更快,因为您不需要在每个请求上从数据库(或缓存)加载用户,而只需要运行一小部分本地代码。这可能是人们喜欢使用 JWT 的最大原因:它们是无状态的。
归档时间: |
|
查看次数: |
6900 次 |
最近记录: |