我正在尝试使用Spring Security身份验证来设置身份验证服务器,并且需要有多个用于client_credentials的身份验证提供程序。
我已经做了很多搜索,但是还没有找到如何配置spring security来将我的自定义身份验证提供程序添加到客户端凭证身份验证提供程序列表中。我发现的每种方法都会导致相同的2个提供方进行客户端凭据身份验证。匿名和dao身份验证提供程序。
如果能为多个客户端凭据身份验证提供程序配置spring安全身份验证服务器,我将不胜感激。
AuthorizationServerConfig
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter
{
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(final AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
.passwordEncoder(passwordEncoder())
.allowFormAuthenticationForClients();
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("sampleClientId").authorizedGrantTypes("implicit")
.scopes("read", "write", "foo", "bar")
.autoApprove(false)
.accessTokenValiditySeconds(3600)
.redirectUris("http://localhost:8083/")
.and()
.withClient("fooClientIdPassword")
.secret(passwordEncoder().encode("secret"))
.authorizedGrantTypes("password", "authorization_code", "refresh_token")
.scopes("foo", "read", "write")
.accessTokenValiditySeconds(3600) // 1 hour
.refreshTokenValiditySeconds(2592000) // 30 days
.redirectUris("xxx")
.and()
.withClient("barClientIdPassword")
.secret(passwordEncoder().encode("secret"))
.authorizedGrantTypes("client_credentials", "refresh_token")
.scopes("bar", "read", "write")
.resourceIds("kip-apis")
.accessTokenValiditySeconds(3600) // 1 hour
.refreshTokenValiditySeconds(2592000) // 30 days
.and()
.withClient("testImplicitClientId")
.autoApprove(true)
.authorizedGrantTypes("implicit")
.scopes("read", "write", "foo", "bar")
.redirectUris("xxx");
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain
.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));
endpoints.authenticationManager(authenticationManager)
.tokenServices(tokenServices())
.tokenStore(tokenStore())
.tokenEnhancer(tokenEnhancerChain);
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}
@Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setTokenEnhancer(accessTokenConverter());
return defaultTokenServices;
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
WebSecurityConfig:
@Configuration
@EnableWebSecurity( debug = true ) // turn off the default configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().disable() // disable form authentication
.anonymous().disable() // disable anonymous user
.authorizeRequests().anyRequest().denyAll(); // denying all access
}
@Autowired
public void globalUserDetails(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("john").password(passwordEncoder.encode("123")).roles("USER").and()
.withUser("tom").password(passwordEncoder.encode("111")).roles("ADMIN").and()
.withUser("user1").password(passwordEncoder.encode("pass")).roles("USER").and()
.withUser("admin").password(passwordEncoder.encode("nimda")).roles("ADMIN");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
我尝试了一些选项,尝试为客户端凭据授予添加其他身份验证提供程序。例如在WebSecurityConfig中...
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.authenticationProvider(customDaoAuthenticationProvider);
}
它不起作用,当逐步完成对client_credentials的身份验证时,我没有看到将自定义身份添加到提供程序列表中,只是匿名和dao身份验证提供程序。
答案 0 :(得分:0)
我终于能够将Spring Security身份验证服务器的配置配置到可以为client_credentials添加多个提供程序的地步。
@Configuration
@EnableAuthorizationServer
public class AuthenticationServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.addTokenEndpointAuthenticationFilter(clientCredentialsTokenEndpointFilter());
}
@Bean
protected ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter() {
ClientCredentialsTokenEndpointFilter cctef = new CustomClientCredentialsTokenEndpointFilter();
cctef.setAuthenticationManager(clientAuthenticationManager());
return cctef;
}
@Bean
protected ProviderManager clientAuthenticationManager() {
return new ProviderManager(Arrays.asList(authProvider()));
}
@Bean
protected DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new CustomDaoAuthenticationProvider();
authProvider.setUserDetailsService(clientDetailsUserService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
protected BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
protected UserDetailsService clientDetailsUserService() {
return new ClientDetailsUserDetailsService(clientDetailsService());
}
@Bean
protected ClientDetailsService clientDetailsService() {
return new ClientDetailsService() {
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
BaseClientDetails details = new BaseClientDetails();
details.setClientId("barClientIdPassword");
details.setClientSecret(passwordEncoder().encode("secret"));
details.setAuthorizedGrantTypes(Arrays.asList("client_credentials"));
details.setScope(Arrays.asList("read", "trust"));
details.setResourceIds(Arrays.asList("kip-apis"));
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_CLIENT"));
details.setAuthorities(authorities);
details.setAccessTokenValiditySeconds(3600); //1hr
details.setRegisteredRedirectUri(null);
return details;
}
};
}
@Bean
public AuthenticationEntryPoint oauthAuthenticationEntryPoint() {
OAuth2AuthenticationEntryPoint aep = new OAuth2AuthenticationEntryPoint();
aep.setRealmName("theRealm");
return aep;
}
@Bean
public AuthenticationEntryPoint clientAuthenticationEntryPoint() {
OAuth2AuthenticationEntryPoint aep = new OAuth2AuthenticationEntryPoint();
aep.setRealmName("theRealm/client");
return aep;
}
@Bean
public AccessDeniedHandler oauthAccessDeniedHandler() {
return new OAuth2AccessDeniedHandler();
}
}
在clientAuthenticationManager中,我们现在可以将提供程序添加到提供程序管理器列表中。
我不确定这是否是完全正确的方法,但是它似乎确实可以让我们做自己想做的事情。