![](/img/trans.png)
[英]Spring security - custom userDetailsService implemenation not getting called
[英]Spring Security 5 - My custom UserDetailsService is not called
我發現了幾個關於類似問題的問題,但沒有一個完全是我的情況。
我正在使用以下 class 在我的應用程序中配置身份驗證/授權(REST API)。
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.authorizeRequests()
.and()
.exceptionHandling(e -> e
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.antMatcher("/application-api/v1/**").authorizeRequests()
.antMatchers("/application-api/v1/non-protected").permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.opaqueToken();
}
@Override
protected UserDetailsService userDetailsService() {
return new ApplicationUserDetailsService();
}
}
無論我嘗試什么,我的自定義 ApplicationUserDetailsService 都不會被使用。 誰能看到這個配置有什么問題?
我還嘗試指定以下 bean:
@Service
public class ApplicationUserDetailsService implements UserDetailsService {
private static final Logger logger = LoggerFactory.getLogger(ApplicationUserDetailsService.class);
public ApplicationUserDetailsService() {
logger.debug("Creating instance of ApplicationUserDetailsService");
}
@Override
public UserDetails loadUserByUsername(String userName) {
logger.debug("Creating user details for {}", userName);
return new ApplicationUser(userName);
}
}
它也沒有工作。
########### 更新 ###########
我已按如下方式修改了我的 SecurityConfiguration:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);
@Qualifier("applicationUserDetailsService")
@Autowired
private UserDetailsService userDetailsService;
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
logger.info("Oauth2 enabled: {}", enabled);
httpSecurity.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.exceptionHandling(e -> e
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.antMatcher("/application-api/v1/**").authorizeRequests()
.antMatchers("/", "/application-api/unprotected").permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.opaqueToken();
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder());
}
@Bean(name="passwordEncoder")
public PasswordEncoder passwordencoder(){
return new BCryptPasswordEncoder();
}
@Override
protected UserDetailsService userDetailsService() {
return userDetailsService;
}
}
我可以看到我的實例已在配置中使用,但它從未被調用。
原因可能是因為您正在使用 new 關鍵字構造ApplicationUserDetailsService
ervice ,使其成為非彈簧依賴項
您有 2 個選項,要么使該方法返回UserDetailsService
ervice 公有,並用@Bean
標記它
@Bean
public UserDetailsService userDetailsService() {
return new ApplicationUserDetailsService();
}
或者
通過@Autowired
或構造函數注入在SecurityConfiguration
中注入ApplicationUserDetailsService
ervice,並在configure
方法中設置HttpSecurity
object 中的安全服務
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);
private ApplicationUserDetailsService applicationUserDetailsService;
// inject via constructor
public SecurityConfig(ApplicationUserDetailsService applicationUserDetailsService) {
this.applicationUserDetailsService = applicationUserDetailsService;
}
@Override
public void configure(HttpSecurity httpSecurity) throws Exception
{
httpSecurity.userDetailsService(applicationUserDetailsService);
.... rest of security config code
}
這可能是 bean 創建順序的情況。 可能是在創建 SecurityConfiguration 時 applicationUserDetailsService bean 不可用於自動裝配。 您可以嘗試在 SecurityConfiguration 上添加@dependson
並查看是否有效。
您正在配置中注入 UserDetailService 。 UserDetailsServiceAutoConfiguration 默認來自 Spring。
@Autowired
private UserDetailsService userDetailsService;
代替 userDetailsService,在 SecurityConfiguration 中自動連接ApplicationUserDetailsS ervice。 例子:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);
//This should work. If not Found it will give error. Might be the case where it is injecting Other UserDetailsService.
@Autowired
private ApplicationUserDetailsService userDetailsService;
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
logger.info("Oauth2 enabled: {}", enabled);
httpSecurity.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.exceptionHandling(e -> e
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.antMatcher("/application-api/v1/**").authorizeRequests()
.antMatchers("/", "/application-api/unprotected").permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.opaqueToken();
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder());
}
@Bean(name="passwordEncoder")
public PasswordEncoder passwordencoder(){
return new BCryptPasswordEncoder();
}
}
問題不在於注入 bean。 鑒於您看到的是預期的 bean 注入,原因可能是未使用該服務。
您需要檢查您使用的身份驗證提供程序。 對於默認提供程序,僅當您的身份驗證提供程序基於用戶名和密碼時才使用該服務。
例如,參見 Spring 文檔:
以下文章介紹了如何自定義用戶詳細信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.