spring security 5-my custom userdetailsservice未调用

iqjalb3h  于 2021-07-23  发布在  Java
关注(0)|答案(4)|浏览(474)

关于类似的问题,我发现了几个问题,但没有一个是我的问题。
我使用下面的类在我的应用程序(restapi)中配置身份验证/授权。

@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();
    }
}

无论我尝试什么,我的自定义applicationuserdetails服务都从未使用过。有人看到这个配置有什么问题吗?
我还尝试指定以下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);
    }
}

它也不起作用。

########### 更新###########

我修改了我的安全配置如下:

@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;
    }
}

我可以看到配置中使用了我的示例,但它从未被调用。

jutyujz0

jutyujz01#

问题不在于注入豆子。假设您看到预期的bean被注入,原因可能是服务没有被使用。
您需要检查正在使用的身份验证提供程序。对于默认提供程序,仅当您的身份验证提供程序基于用户名和密码时,才使用该服务。
例如,请参见spring文档:
https://docs.spring.io/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/core/userdetails/userdetailsservice.html
下面的文章描述了如何定制用户详细信息。
https://docs.spring.io/spring-security/site/docs/5.2.x/reference/html/oauth2.html#oauth2login-高级oauth2用户服务

tcomlyy6

tcomlyy62#

原因可能是因为你正在构建 ApplicationUserDetailsService 使用new关键字使其成为非spring依赖项
您有两个选项使方法返回 UserDetailsService 用标记 @Bean ```
@Bean
public UserDetailsService userDetailsService() {
return new ApplicationUserDetailsService();
}

或
注入 `ApplicationUserDetailsService` 在 `SecurityConfiguration` 通过 `@Autowired` 或注入 `configure` 方法中设置安全服务 `HttpSecurity` 对象

@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
}
ktecyv1j

ktecyv1j3#

这可能是bean创建顺序的一个例子。可能是在创建securityconfiguration时,applicationuserdetailsservice bean无法自动连接。你可以尝试添加 @dependson 查看安全配置是否有效。

oyjwcjzk

oyjwcjzk4#

您正在配置中注入userdetailservice。默认情况下,spring提供了userdetailsserviceautoconfiguration。

@Autowired
private UserDetailsService userDetailsService;

在securityconfiguration中使用autowire applicationuserdetailsservice而不是userdetailsservice。例子:

@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();
}

}

相关问题