spring-security 在实现UserDetailService的Spring安全类中返回自定义错误消息

qxgroojn  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(280)

在我的授权服务器中,我有一个实现UserDetailService并覆盖loadUserByUsername的类。我从我的数据库中加载用户并将其交给spring securtiy。一切都运行良好,因为spring security在返回jwt令牌之前会检查口令和所有其他东西。
现在,在我希望spring进行授权之前,我必须对用户进行更多的检查。例如,我们希望检查isAccountLocked或isEmailVerified等。如果其中任何一个为真,那么我希望抛出一个异常,说明问题所在,以便前端可以向用户显示适当的消息。这是业务需求。
我尝试扩展“UsernameNotFoundException”并抛出该异常,但问题是,无论抛出什么异常,SpringSecurity仍然只返回400。

{
    "error": "invalid_grant",
    "error_description": "Bad credentials"
}

我还尝试在我的config类中添加自定义authenticationEntryPoint,扩展WebSecurityConfigurerAdapter,但它甚至到达了该类中设置的任何断点。

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().disable()
            .csrf().disable()
            .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint());
    }

简单地说,当抛出UsernameNotFoundException时,我希望能够放置一个自定义错误消息,说明抛出该异常的原因,或者我希望抛出一些扩展UsernameNotFoundException的自定义异常。
任何帮助都将不胜感激

vq8itlhq

vq8itlhq1#

嗨,伙计们,只是一个更新,我设法解决了我的问题与followig。
首先在扩展WebSecurityConfigurerAdapter的类中禁用隐藏“找不到用户名”异常。

@Override
    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
        daoAuthenticationProvider.setUserDetailsService(ctnwUserDetailsService);
        auth.authenticationProvider(daoAuthenticationProvider);
    }

然后配置异常转换器以捕获UsernameNotFound异常,并返回ResponseEntity,其中自定义异常作为主体这位于扩展AuthorizationServerConfigurerAdapter类中

@Override
    public void configure(AuthorizationServerEndpointsConfigurer endPoints) throws Exception {
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(new 
   CustomTokenEnhancer(userBean), accessTokenConverter()));
        endPoints.tokenStore(tokenStore())
            .accessTokenConverter(accessTokenConverter())
            .authenticationManager(authenticationManager)
            .userDetailsService(ctnwUserDetailsService)
            .tokenEnhancer(tokenEnhancerChain)
            .exceptionTranslator(exception -> {
                if (exception instanceof UsernameNotFoundException) {
                    return ResponseEntity
                        .status(HttpStatus.BAD_REQUEST)
                        .body(new CustomOauthException(exception.getMessage()));
                } else {
                    throw exception;
                }
            });
    }

最后,可以在实现UserDetailService的类中抛出UsernameNotFoundException。

public UserDetails loadUserByUsername(String username) throws 
UsernameNotFoundException {
        WebUser webUser = webUserRepository.findOneByUsername(username);                
        if(!webUser.getIsEmailVerified()) throw new  UsernameNotFoundException("User email not verified");
}

结果将如下所示

相关问题