我有一个关于spring-security-oauth2 2.0.7配置的问题。我正在通过GlobalAuthenticationConfigurerAdapter使用LDAP进行身份验证:
@SpringBootApplication
@Controller
@SessionAttributes("authorizationRequest")
public class AuthorizationServer extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(AuthorizationServer.class, args);
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/oauth/confirm_access").setViewName("authorize");
}
@Configuration
public static class JwtConfiguration {
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyPair keyPair = new KeyStoreKeyFactory(
new ClassPathResource("keystore.jks"), "foobar".toCharArray())
.getKeyPair("test");
converter.setKeyPair(keyPair);
return converter;
}
@Bean
public JwtTokenStore jwtTokenStore(){
return new JwtTokenStore(jwtAccessTokenConverter());
}
}
@Configuration
@EnableAuthorizationServer
public static class OAuth2Config extends AuthorizationServerConfigurerAdapter implements EnvironmentAware {
private static final String ENV_OAUTH = "authentication.oauth.";
private static final String PROP_CLIENTID = "clientid";
private static final String PROP_SECRET = "secret";
private static final String PROP_TOKEN_VALIDITY_SECONDS = "tokenValidityInSeconds";
private RelaxedPropertyResolver propertyResolver;
@Inject
private AuthenticationManager authenticationManager;
@Inject
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Inject
private JwtTokenStore jwtTokenStore;
@Inject
private UserDetailsService userDetailsService;
@Override
public void setEnvironment(Environment environment) {
this.propertyResolver = new RelaxedPropertyResolver(environment, ENV_OAUTH);
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(jwtTokenStore);
tokenServices.setAuthenticationManager(authenticationManager);
return tokenServices;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).tokenStore(jwtTokenStore).accessTokenConverter(
jwtAccessTokenConverter).userDetailsService(userDetailsService);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess(
"isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(propertyResolver.getProperty(PROP_CLIENTID))
.scopes("read", "write")
.authorities(AuthoritiesConstants.ADMIN, AuthoritiesConstants.USER)
.authorizedGrantTypes("authorization_code", "refresh_token", "password")
.secret(propertyResolver.getProperty(PROP_SECRET))
.accessTokenValiditySeconds(propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800));
}
}
@Configuration
@Order(-10)
protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().loginPage("/login").permitAll()
.and()
.requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
.and()
.authorizeRequests().anyRequest().authenticated();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
}
@Configuration
protected static class AuthenticationConfiguration extends
GlobalAuthenticationConfigurerAdapter {
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("uid={0},ou=people")
.groupSearchBase("ou=groups")
.contextSource().ldif("classpath:test-server.ldif");
}
}
}
虽然refresh令牌在spring-security-oauth2的2.0.6版中运行良好,但在2.0.7版中就不再运行了。正如这里所读的,应该设置authenticationmanager
以便在刷新期间尝试获取新的访问令牌时使用。
据我理解,这与Spring-Security-Oauth2的以下更改有关。
不幸的是,我没有设法把它设置好。
org.springframework.security.oauth2.provider.token.DefaultTokenServices#setAuthenticationManager
调用并获取注入的authenticationManager
。我不知道如何注入ldapuserdetailsservice
。我唯一看到的是,在令牌刷新调用过程中尝试重新验证用户身份时,将调用preauthenticatedauthenticationprovider
。
有谁能告诉我怎么做吗?
PS:我得到的例外情况如下:
p.PreAuthenticatedAuthenticationProvider : PreAuthenticated authentication request: org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken@5775: Principal: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@441d5545: Principal: bob; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
o.s.s.o.provider.endpoint.TokenEndpoint : Handling error: IllegalStateException, UserDetailsService is required.
当我使用自定义的authenticationprovider
而不是userdetailsservice
实现来解决登录身份验证时,我遇到了类似的问题。
但最近我发现,如果您希望refresh_token
正常工作,那么Spring引发的错误是正确的。因为authenticationprovider
实现不可能用refresh_token
刷新令牌,因为在这种实现中,您必须解析密码是否正确,但刷新令牌不具有该信息。但是,userdetailsservice
不知道密码。
spring-security-oauth2
2.0.6版本的工作是因为从不检查用户授权,只检查刷新令牌是否有效(使用私钥签名),但是,如果用户在第一次登录后从系统中删除,则使用刷新令牌,被删除的用户将有无限时间访问您的系统,这是一个很大的安全问题。
看看我报告的问题:https://github.com/spring-projects/spring-security-oauth/issues/813
登录时,将从服务器发送JWT访问令牌,并保存在RN中的AsyncStorage中。 现在,我希望用户保持登录5年,直到他们: > < li> 注销 管理员撤销了他们的令牌 他们在3台设备上登录,在其中一台设备上更改密码,这应该从其他2台设备上注销他们,直到他们在这些设备上再次登录 丢失他们的电话,并从另一个设备登录以从所有设备注销 看起来我不得不在数据库中存储JWT令牌(我知道这不是JWT令牌的重
我使用的是Spring Security 3.2.0。带有Java配置的RC2。我设置了一个简单的HttpSecurity配置,要求在/v1/**上进行基本身份验证。GET请求正常,但POST请求失败: 我的安全配置如下所示: 对此有任何帮助,非常感谢。
试图了解使用Spring Security实现OpenID身份验证的正确方法。 我正在考虑用户尚未在我的应用程序中注册的情况。要注册用户,我需要知道它的OpenID和电子邮件。 当OpenID提供者将用户重定向回我的应用程序时,将调用,但在这种情况下,我只知道用户的OpenID。因此,我抛出,然后,因此无法注册用户。 这里常见的解决办法是什么?如果从返回类似,然后在调用时注册用户,然后返回真正的呢
我是Spring Security的新手,我试图实现自定义的身份验证。令我困扰的是,这个接口只包含一个方法,它只将用户名作为参数并返回。 我想知道为什么这个方法不接受任何密码作为参数。 Spring是如何只根据用户名对用户进行身份验证的?
} 要获取令牌,我执行以下步骤: > 使用浏览器转到:http://localhost:9000/oauth/authorize?response_type=code&client_id=test&redirect_uri=http%3a%2f%2flocalhost%3a8080%2f&scope=write 首先,它将我重定向到一个登录表单,在那里我输入用户名和密码:admin abc 请帮我