gpt4 book ai didi

Spring Boot OAuth2 + JWT 和 UserDetailsS​​ervice

转载 作者:行者123 更新时间:2023-12-03 21:29:48 25 4
gpt4 key购买 nike

在我的 Spring Boot 应用程序中,我正在尝试配置 Spring OAuth2 + JWT

这是我的 OAuth2ServerConfig 配置:

@Configuration
public class OAuth2ServerConfig {

private static final String RESOURCE_ID = "restservice";

@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}

@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}

@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;

@Autowired
private TokenStore tokenStore;

@Autowired
private TokenEnhancer tokenEnhancer;

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// @formatter:off
endpoints
.tokenStore(tokenStore)
.tokenEnhancer(tokenEnhancer)
.authenticationManager(this.authenticationManager);
// @formatter:on
}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// @formatter:off
clients
.inMemory()
.withClient("clientapp")
.authorizedGrantTypes("password","refresh_token")
.authorities("ROLE_CLIENT")
.scopes("read", "write")
.resourceIds(RESOURCE_ID)
.secret("123456");
// @formatter:on
}

}

@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

@Autowired
private ResourceServerTokenServices tokenService;

@Override
public void configure(ResourceServerSecurityConfigurer resources) {
// @formatter:off
resources
.resourceId(RESOURCE_ID)
.tokenServices(tokenService);
// @formatter:on
}

@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/profile/*").authenticated()
.and().csrf()
.disable().sessionManagement().sessionCreationPolicy(STATELESS);
// @formatter:on
}

}

}

这是我的 UserDetailsService 实现:
@Service
public class DBUserDetailsService implements UserDetailsService {

@Autowired
private UserService userService;

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userService.findUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User " + username + " not found.");
}

Set<Permission> permissions = userService.getUserPermissions(user);
return new DBUserDetails(user, permissions);
}

}

这是 WebSecurityConfig :
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private SocialAuthenticationSuccessHandler socialAuthenticationSuccessHandler;

@Autowired
private DBUserDetailsService userDetailsService;

@Value("${social.postLogin.url}")
private String postLoginUrl;

@Override
public void configure(WebSecurity web) throws Exception {
// Spring Security ignores request to static resources such as CSS or JS
// files.
web.ignoring().antMatchers("/static/**");
}


@Override
protected void configure(HttpSecurity http) throws Exception {

// @formatter:off
http.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class);

// Set a custom successHandler on the SocialAuthenticationFilter
final SpringSocialConfigurer socialConfigurer = new SpringSocialConfigurer();
socialConfigurer.addObjectPostProcessor(new ObjectPostProcessor<SocialAuthenticationFilter>() {
@Override
public <O extends SocialAuthenticationFilter> O postProcess(O socialAuthenticationFilter) {
socialAuthenticationFilter.setAuthenticationSuccessHandler(socialAuthenticationSuccessHandler);
socialAuthenticationFilter.setPostLoginUrl(postLoginUrl);
return socialAuthenticationFilter;
}
});

http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//Configures url based authorization
.and()
.authorizeRequests()
//Anyone can access the urls
.antMatchers("/auth/**").permitAll()
.antMatchers("/actuator/health").permitAll()
.antMatchers("/actuator/**").hasAuthority("PERMISSION_READ_ACTUATOR_DATA")
//Adds the SocialAuthenticationFilter to Spring Security's filter chain.
.and()
// apply the configuration from the socialConfigurer (adds the SocialAuthenticationFilter)
.apply(socialConfigurer);

// @formatter:on
}

/**
* Configures the authentication manager bean which processes authentication
* requests.
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

}

现在我可以成功地发出 JWT accessToken 但是当我尝试使用它时,我现有的逻辑失败并出现以下错误:
java.lang.String cannot be cast to com.example.domain.model.security.DBUserDetails

由于某种原因,在基于 JWT token 的成功身份验证后不会调用 DBUserDetailsService.loadUserByUsername,而不是在 DBUserDetails 中使用 SecurityContextHolder.getContext().getAuthentication().getPrincipal() 我只有一个带有用户名的字符串,例如“admin”

我究竟做错了什么 ?

最佳答案

在 Spring 源代码调试之后,我找到了如何注入(inject)我的 UserDetailsService 的解决方案。入流。为此,您必须修改 accessTokenConverter()方法:

@Autowired
private DBUserDetailsService userDetailsService;

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");

DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
DefaultUserAuthenticationConverter userTokenConverter = new DefaultUserAuthenticationConverter();
userTokenConverter.setUserDetailsService(userDetailsService);
accessTokenConverter.setUserTokenConverter(userTokenConverter);

converter.setAccessTokenConverter(accessTokenConverter);

return converter;
}

关于Spring Boot OAuth2 + JWT 和 UserDetailsS​​ervice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39647263/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com