[英]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.