【问题标题】:Return custom error messages in Spring Security class that implements UserDetailService在实现 UserDetailSservice 的 Spring Security 类中返回自定义错误消息
【发布时间】:2022-11-05 17:34:30
【问题描述】:

在我的授权服务器中,我有一个实现 UserDetailService 并覆盖 loadUserByUsername 的类。我从我的数据库中加载用户并将其交给 spring securtiy。一切正常,因为 spring security 在返回 jwt 令牌之前会检查密码和所​​有这些内容。

现在,在我想让 spring 进行授权之前,我必须对用户进行更多检查。例如,我们要检查 isAccountLocked 或 isEmailVerified 等。如果其中任何一个为真,那么我想抛出一个异常,说明问题是什么,以便前端可以向用户显示适当的消息。这是业务要求。

我试图扩展“UsernameNotFoundException”并抛出它,但问题是无论我抛出什么异常,Spring Security 仍然只返回 400。

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

我还尝试在扩展 WebSecurityConfigurerAdapter 的配置类中添加自定义 authenticationEntryPoint,但它甚至会到达该类中设置的任何断点。我仍然得到邮递员的400。

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

简单地说,当 UsernameNotFoundException 被抛出时,我希望能够放置一个自定义错误消息来说明它被抛出的原因,或者我想抛出一些扩展 UsernameNotFoundException 的自定义异常。

任何帮助将不胜感激

【问题讨论】:

    标签: spring spring-security authorization


    【解决方案1】:

    嗨伙计们只是一个更新,我设法通过以下方式解决了我的问题。

    首先在扩展 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;
                    }
                });
        }
    

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

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

    结果将如下所示

    【讨论】:

      猜你喜欢
      • 2021-01-28
      • 2021-06-06
      • 2017-05-15
      • 2020-10-14
      • 1970-01-01
      • 2013-05-21
      • 2015-07-29
      • 1970-01-01
      • 2019-09-22
      相关资源
      最近更新 更多