Spring Security 如何扩展授权服务器

dfty9e19  于 2023-06-06  发布在  Spring
关注(0)|答案(1)|浏览(202)

当我从authorizationServer1获取令牌并通过内省端点响应401检查资源服务器中的令牌时,我使用k8s扩展授权服务器(2个副本),但authorizationServer2获得成功。
如何处理它或一些指南,以正确的方式为规模授权服务器
public class Uncategorized {

@Autowired
private OAuthConfig authConfig;

@Autowired
PasswordEncoder passwordEncoder;

@Value("${auth.server.issuer}")
private String issuerAuth;

@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authServerSecurityFilterChain(HttpSecurity http) throws Exception {
    OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
    http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
            .oidc(Customizer.withDefaults());    // Enable OpenID Connect 1.0
    return http.build();
}

@Bean
public TokenSettings tokenSettings() {
    // @formatter:off
    return TokenSettings.builder()
            .accessTokenTimeToLive(Duration.ofMinutes(30L))
            .build();
    // @formatter:on
}

@Bean
public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {
    JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);
    RegisteredClient registeredClient = registeredClientRepository.findByClientId(authConfig.getClientId());
    if (Objects.isNull(registeredClient)) {
        registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
                .clientId(authConfig.getClientId())
                .clientSecret(passwordEncoder.encode(authConfig.getClientSecret()))
                .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                .tokenSettings(tokenSettings())
                .scope("read")
                .build();
    }
    registeredClientRepository.save(registeredClient);
    return registeredClientRepository;
}

@Bean
public JWKSource<SecurityContext> jwkSource() throws Exception {

    KeyPair keyPair = generateRsaKey();
    RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
    RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
    RSAKey rsaKey = new RSAKey.Builder(publicKey)
            .privateKey(privateKey)
            .keyID("key-id")
            .build();
    JWKSet jwkSet = new JWKSet(rsaKey);
    System.out.println(jwkSet);
    return new ImmutableJWKSet<>(jwkSet);
}

private static KeyPair generateRsaKey() {
    KeyPair keyPair;
    try {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(3072);
        keyPair = keyPairGenerator.generateKeyPair();
    } catch (Exception ex) {
        throw new IllegalStateException(ex);
    }
    return keyPair;
}

@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
    return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}

@Bean
public AuthorizationServerSettings authorizationServerSettings() {
    return AuthorizationServerSettings.builder().issuer(issuerAuth).build();
}

@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> jwtEncodingContextOAuth2TokenCustomizer() {
    return (context -> {
        Authentication authentication = context.getPrincipal();
        if (authentication.getPrincipal() instanceof String) {
            OAuth2AuthorizationGrantAuthenticationToken tok = (OAuth2AuthorizationGrantAuthenticationToken) context.getAuthorizationGrant();
            context.getClaims().claim("merchantCenterId", tok.getAdditionalParameters().get("merchantCenterId"));
            context.getClaims().claim("roleId", tok.getAdditionalParameters().get("roleId"));
            context.getClaims().claim("username", tok.getAdditionalParameters().get("user_name"));
        }
    });
}

}

kd3sttzy

kd3sttzy1#

我只是重复Marcus在评论中所说的,即您需要在数据库中持久化授权和授权同意,例如OAuth2 AuthorizationService和OAuth2 AuthorizationConsentService的JDBC实现或How-to: Implement core services with JPA演示的指南。或者,如果你选择,你可以将它们存储在像Redis这样的NoSQL数据存储中,但是没有现成的实现。
请注意,您还应该将会话和密钥存储在数据库或NoSQL数据存储(例如Redis)中。Spring Session非常适合将会话卸载到数据存储中,并且可以轻松添加到Sping Boot 应用程序中,但是在JVM外部存储密钥具有not yet been demonstrated
为此,我建议您查看Rob Winch从2023年5月开始在Enterprise Security with Spring Authorization Server上在Spring I/O上的演讲。最后,他的演讲涵盖了插入一个键轮换策略,他提到你可以很容易地用一个数据库支持的实现替换内存中的from his sample repo(例如使用Spring Data JDBC或JPA)。
这些是在生产环境中扩展基于k8s的authz服务器所需的技巧。

相关问题