我正在研究一个使用OAuth 2身份验证(Spring Boot 1.5)的Spring Boot项目。在我的解决方案中,我将访问令牌存储在表oauth_access_token的Postgresql数据库中。
我将项目从Spring Boot 1.5迁移到Spring Boot2。我没有更改配置,可以验证自己的身份,但是令牌的持久性不起作用,我的表“ oauth_access_token”保持为空。 / p>
这是我的OAuth配置类:
@Configuration
public class OAuth2ServerConfiguration {
private final DataSource dataSource;
public OAuth2ServerConfiguration(DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
public JdbcTokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private final TokenStore tokenStore;
private final Http401UnauthorizedEntryPoint http401UnauthorizedEntryPoint;
private final AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler;
private final CorsFilter corsFilter;
public ResourceServerConfiguration(TokenStore tokenStore, Http401UnauthorizedEntryPoint http401UnauthorizedEntryPoint,
AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler, CorsFilter corsFilter) {
this.tokenStore = tokenStore;
this.http401UnauthorizedEntryPoint = http401UnauthorizedEntryPoint;
this.ajaxLogoutSuccessHandler = ajaxLogoutSuccessHandler;
this.corsFilter = corsFilter;
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint(http401UnauthorizedEntryPoint)
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.and()
.csrf()
.disable()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.headers()
.frameOptions().disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/profile-info").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/v2/api-docs/**").permitAll()
.antMatchers("/swagger-resources/configuration/ui").permitAll()
.antMatchers("/swagger-ui/index.html").hasAuthority(AuthoritiesConstants.ADMIN);
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("res_appli").tokenStore(tokenStore);
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private final AuthenticationManager authenticationManager;
private final TokenStore tokenStore;
private final DataSource dataSource;
public AuthorizationServerConfiguration(@Qualifier("authenticationManagerBean") AuthenticationManager authenticationManager,
TokenStore tokenStore, DataSource dataSource) {
this.authenticationManager = authenticationManager;
this.tokenStore = tokenStore;
this.dataSource = dataSource;
}
@Bean
protected AuthorizationCodeServices authorizationCodeServices() {
return new JdbcAuthorizationCodeServices(dataSource);
}
@Bean
public ApprovalStore approvalStore() {
return new JdbcApprovalStore(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints
.authorizationCodeServices(authorizationCodeServices())
.approvalStore(approvalStore())
.tokenStore(tokenStore)
.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
}
}
我的安全配置类:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final UserDetailsService userDetailsService;
public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService) {
this.authenticationManagerBuilder = authenticationManagerBuilder;
this.userDetailsService = userDetailsService;
}
@PostConstruct
public void init() {
try {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
} catch (Exception e) {
throw new BeanInitializationException("Security configuration failed", e);
}
}
@Bean
public AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler() {
return new AjaxLogoutSuccessHandler();
}
@Bean
public Http401UnauthorizedEntryPoint http401UnauthorizedEntryPoint() {
return new Http401UnauthorizedEntryPoint();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/app/**/*.{js,html}")
.antMatchers("/i18n/**")
.antMatchers("/content/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/api/register")
.antMatchers("/api/activate")
.antMatchers("/api/account/reset-password/init")
.antMatchers("/api/account/reset-password/finish")
.antMatchers("/test/**");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.httpBasic().realmName("yvidya")
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.requestMatchers().antMatchers("/oauth/authorize")
.and()
.authorizeRequests()
.antMatchers("/oauth/authorize").authenticated();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
}
和我的UserDetailService
@Component("userDetailsService")
public class DomainUserDetailsService implements UserDetailsService {
private final Logger log = LoggerFactory.getLogger(DomainUserDetailsService.class);
private final UserRepository userRepository;
public DomainUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
@Transactional
public UserDetails loadUserByUsername(final String login) {
log.debug("Authenticating {}", login);
String lowercaseLogin = login.toLowerCase(Locale.ENGLISH);
Optional<User> userFromDatabase = userRepository.findOneWithAuthoritiesByLogin(lowercaseLogin);
return userFromDatabase.map(user -> {
if (!user.getActivated()) {
throw new UserNotActivatedException("User " + lowercaseLogin + " was not activated");
}
List<GrantedAuthority> grantedAuthorities = user.getAuthorities().stream()
.map(authority -> new SimpleGrantedAuthority(authority.getName()))
.collect(Collectors.toList());
return new CustomUser(user, lowercaseLogin, user.getPassword(), grantedAuthorities);
}).orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the " +
"database"));
}
}
我的文件属性包含:
security:
basic:
enabled: false
oauth2:
resource:
filter-order: 3
我无需更改代码,可以获取访问令牌,但是它不能持久存储在数据库中,我不知道为什么
你有个主意吗?
谢谢