spring - 如何在春季使用 oauth2 中的刷新令牌更新访问令牌?
问题描述
我对spring很陌生,这是我第一次尝试使用oauth2进行spring security。我已经使用 Spring Security 实现了 OAuth2,并且确实获得了访问令牌和刷新令牌。但是,在发送刷新令牌以获取新的访问令牌时,我得到了“ossoprovider.endpoint.TokenEndpoint - IllegalStateException,需要 UserDetailsService”。
其他用户对类似问题的解决方案似乎是将 UserDetailsService 与端点连接。
所以我做了同样的事情,现在当我尝试使用grant_type:refresh_token和refresh_token:THE TOKEN以及客户端ID和秘密发送请求时,我收到一个错误,提示找不到用户。
请参考下面的 WebSecurityConfiguration 类:
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter{
@Autowired
private UserDetailsService customUserDetailsService;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean ();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService)
.passwordEncoder(encoder());
}
@Override
protected void configure (HttpSecurity http) throws Exception {
http.csrf().disable()
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/login**")
.permitAll()
.anyRequest()
.authenticated();
}
public PasswordEncoder encoder() {
return NoOpPasswordEncoder.getInstance();
}
}
请参考下面的 AuthorizationServerConfiguration 类:
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private DataSource dataSource;
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore());
.userDetailsService(userDetailsService);
}
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
}
请参考下面的 ResourceServerConfiguration 类:
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{
@Autowired
DataSource dataSource;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("scout").tokenStore(tokenStore());
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests (). antMatchers ("/oauth/token", "/oauth/authorize **").permitAll();
// .anyRequest (). authenticated ();
http.requestMatchers (). antMatchers ("/api/patients/**") // Deny access to "/ private"
.and (). authorizeRequests ()
.antMatchers ("/api/patients/**"). access ("hasRole ('PATIENT')")
.and (). requestMatchers (). antMatchers ("/api/doctors/**") // Deny access to "/ admin"
.and (). authorizeRequests ()
.antMatchers ("/api/doctors/**"). access ("hasRole ('DOCTOR')");
}
}
如果需要,可参考 CustomUserDetailsService 类:
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UsersRepository userRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
Optional<Users> usersOptional = userRepository.findByEmail(email);
Users user = null;
if(usersOptional.isPresent()) {
System.out.println(usersOptional.isPresent());
user = usersOptional.get();
}else {
throw new RuntimeException("Email is not registered!");
}
return new CustomUserDetails(user);
}
}
我认为,服务器应该只检查刷新令牌的有效性,因为我们不会使用刷新令牌传递用户详细信息。所以我不知道为什么它首先需要 userDetails 。
如果我遗漏了什么,请帮助和指导!提前致谢。
解决方案
我不确定。但正如我在 WebSecurityConfiguration 中看到的您的代码可以连接默认 InMemoryUserDetailsManager UserDetailsService 。这可能是您有 2 个不同提供商的原因。在你写的一个,从另一个你读用户。请尝试更改您的代码,如下所示,如果有帮助,请告诉我:
曾是:
@Autowired
private UserDetailsService customUserDetailsService;
我的愿景应该是:
@Autowired
private CustomUserDetailsService customUserDetailsService;
推荐阅读
- windows - 我可以在一个窗口中拥有多个 Powershell 控制台吗?
- reactjs - 在 React Native 应用程序之间共享数据库
- angular - 以角度显示数据时获取[对象对象]
- php - 添加刀片 php 页面的链接
- php - 想要在 laravel 上返回 Value json
- html - 带顶栏的 Bootstrap 响应式导航
- hyperledger-fabric - 关于hyperledger fabric MSP设置的问题
- sql-server - 收到错误“找不到为 :r 命令指定的文件”
- vbscript - 带有 NL 的 VBScript msgbox
- spacy - 用 spacy 训练一个新的实体类型