背景 最近我在玩Oauth2和Single Sign-on功能。我已经成功实现了一个带有Spring-Boot,Keycloak的POC。我可以在这里找到:https://github.com/rivu007/sso-springboot-keyclock
这是一个REST服务,我使用keycloak作为OAuth2服务器来保护受保护的端点。该设置适用于访问令牌(clientId和secret)
并发症
我很想用JWT扩展POC。 Keyclock提供签名的JWT作为客户端身份验证器。我生成了密钥和证书(keystore.jks)并相应地更新了application.yml文件:
keycloak:
auth-server-url: http://localhost:18080/auth
realm: sso
resource: product-app
credentials:
jwt:
client-keystore-file: "src/main/resources/keystore.jks"
client-keystore-type: "jks"
client-keystore-password: "storepw"
client-key-password: "keypw"
client-key-alias: "product-app"
token-expiration: 10
confidential-port: 0
use-resource-role-mappings: true
ssl-required: none
SecurityConfiguration.java
看起来像这样:
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
@EnableGlobalMethodSecurity(prePostEnabled = true)
@KeycloakConfiguration
public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public KeycloakClientRequestFactory keycloakClientRequestFactory;
@Autowired
private UserDetailsService userDetailsService;
/**
* Registers the KeycloakAuthenticationProvider with the authentication manager.
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate keycloakRestTemplate() {
return new KeycloakRestTemplate(keycloakClientRequestFactory);
}
/**
* Defines the session authentication strategy.
*/
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Bean
public KeycloakConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
super.configure(http);
http.csrf().disable()
.authorizeRequests()
// Allow anonymous access to "/" path
.antMatchers("/").permitAll()
.antMatchers("/user/protected*").authenticated()
.anyRequest().permitAll().and()
// Custom filter for logging in users at "/login"
.addFilterBefore(new JWTLoginFilter("/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class)
// Custom filter for authenticating users using tokens
.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
// Disable resource caching
.headers().cacheControl();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
//auth.userDetailsService(userDetailsService()).passwordEncoder(new BCryptPasswordEncoder());
}
}
这会抛出异常以下异常:
2018-03-06 23:35:54.766 ERROR 60780 --- [nio-8080-exec-5] o.k.a.rotation.AdapterRSATokenVerifier : Didn't find publicKey for kid: w3Qn-XFRI_1uGaLs8_bJxo_hYmHSs1_-EilRV7y98G4
2018-03-06 23:35:54.778 ERROR 60780 --- [nio-8080-exec-5] o.k.a.BearerTokenRequestAuthenticator : Failed to verify token
知道我做错了什么吗?