千家信息网

SpringCloud Alibaba中Oauth2认证服务器自定义异常怎么办

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章将为大家详细讲解有关SpringCloud Alibaba中Oauth2认证服务器自定义异常怎么办,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言问题:在
千家信息网最后更新 2026年11月01日SpringCloud Alibaba中Oauth2认证服务器自定义异常怎么办

这篇文章将为大家详细讲解有关SpringCloud Alibaba中Oauth2认证服务器自定义异常怎么办,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

前言

问题:在使用 Spring Security OAuth3 时如何自定义认证服务器返回异常。

那么首先我们先以 Password模式为例看看在认证时会出现哪些异常情况。

授权模式错误

这里我们故意将授权模式 password 修改成 password1,认证服务器返回如下所示的异常

{   "error": "unsupported_grant_type",   "error_description": "Unsupported grant type: password1" }

密码错误

在认证时故意输错 username 或 password 会出现如下异常错误:

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

客户端错误

在认证时故意输错 client_id 或 client

{   "error": "invalid_client",   "error_description": "Bad client credentials" } 上面的返回结

上面的返回结果很不友好,而且前端代码也很难判断是什么错误,所以我们需要对返回的错误进行统一的异常处理,让其返回统一的异常格式。

问题剖析

如果只关注解决方案,可以直接跳转到解决方案模块!

OAuth3Exception异常处理

在Oauth3认证服务器中认证逻辑最终调用的是 TokenEndpoint#postAccessToken()方法,而一旦认证出现 OAuth3Exception异常则会被 handleException()捕获到异常。如下图展示的是当出现用户密码异常时debug截图:

认证服务器在捕获到 OAuth3Exception后会调用 WebResponseExceptionTranslator#translate()方法对异常进行翻译处理。

默认的翻译处理实现类是 DefaultWebResponseExceptionTranslator,处理完成后会调用 handleOAuth3Exception()方法将处理后的异常返回给前端,这就是我们之前看到的异常效果。

处理方法熟悉Oauth3套路的同学应该知道了如何处理此类异常,就是「自定义一个异常翻译类让其返回我们需要的自定义格式,然后将其注入到认证服务器中。」

但是这种处理逻辑只能解决 OAuth3Exception异常,即前言部分中的「授权模式异常」和「账号密码类的异常」,并不能解决我们客户端的异常。

客户端异常处理

客户端认证的异常是发生在过滤器 ClientCredentialsTokenEndpointFilter上,其中有后置添加失败处理方法,最后把异常交给 OAuth3AuthenticationEntryPoint这个所谓认证入口处理。执行顺序如下所示:

然后跳转到父类的 AbstractOAuth3SecurityExceptionHandler#doHandle()进行处理:

最终由 DefaultOAuth3ExceptionRenderer#handleHttpEntityResponse()方法将异常输出给客户端

处理方法

通过上面的分析我们得知客户端的认证失败异常是过滤器 ClientCredentialsTokenEndpointFilter转交给 OAuth3AuthenticationEntryPoint得到响应结果的,既然这样我们就可以重写 ClientCredentialsTokenEndpointFilter然后使用自定义的 AuthenticationEntryPoint替换原生的 OAuth3AuthenticationEntryPoint,在自定义 AuthenticationEntryPoint处理得到我们想要的异常数据。

解决方案

为了解决上面这些异常,我们首先需要编写不同异常的错误代码:ReturnCode.java

CLIENT_AUTHENTICATION_FAILED(1001,"客户端认证失败"), USERNAME_OR_PASSWORD_ERROR(1002,"用户名或密码错误"), UNSUPPORTED_GRANT_TYPE(1003, "不支持的认证模式");

OAuth3Exception异常

@Slf4j public class CustomWebResponseExceptionTranslator implements WebResponseExceptionTranslator {      @Override     public ResponseEntity> translate(Exception e) throws Exception {         log.error("认证服务器异常",e);          ResultData response = resolveException(e);          return new ResponseEntity<>(response, HttpStatus.valueOf(response.getHttpStatus()));     }      /**      * 构建返回异常      * @param e exception      * @return      */     private ResultData resolveException(Exception e) {         // 初始值 500         ReturnCode returnCode = ReturnCode.RC500;         int httpStatus = HttpStatus.UNAUTHORIZED.value();         //不支持的认证方式         if(e instanceof UnsupportedGrantTypeException){             returnCode = ReturnCode.UNSUPPORTED_GRANT_TYPE;         //用户名或密码异常         }else if(e instanceof InvalidGrantException){             returnCode = ReturnCode.USERNAME_OR_PASSWORD_ERROR;         }          ResultData failResponse = ResultData.fail(returnCode.getCode(), returnCode.getMessage());         failResponse.setHttpStatus(httpStatus);          return failResponse;     }  }

然后在认证服务器配置类中注入自定义异常翻译类

@Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {     //如果需要使用refresh_token模式则需要注入userDetailService     endpoints             .authenticationManager(this.authenticationManager)             .userDetailsService(userDetailService) //                注入tokenGranter             .tokenGranter(tokenGranter);             //注入自定义的tokenservice,如果不使用自定义的tokenService那么就需要将tokenServce里的配置移到这里 //                .tokenServices(tokenServices());     // 自定义异常转换类     endpoints.exceptionTranslator(new CustomWebResponseExceptionTranslator()); }

客户端异常

重写客户端认证过滤器,不使用默认的 OAuth3AuthenticationEntryPoint处理异常

public class CustomClientCredentialsTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter {      private final AuthorizationServerSecurityConfigurer configurer;      private AuthenticationEntryPoint authenticationEntryPoint;      public CustomClientCredentialsTokenEndpointFilter(AuthorizationServerSecurityConfigurer configurer) {         this.configurer = configurer;     }      @Override     public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) {         super.setAuthenticationEntryPoint(null);         this.authenticationEntryPoint = authenticationEntryPoint;     }      @Override     protected AuthenticationManager getAuthenticationManager() {         return configurer.and().getSharedObject(AuthenticationManager.class);     }      @Override     public void afterPropertiesSet() {         setAuthenticationFailureHandler((request, response, e) -> authenticationEntryPoint.commence(request, response, e));         setAuthenticationSuccessHandler((request, response, authentication) -> {         });     } }

在认证服务器注入异常处理逻辑,自定义异常返回结果。(代码位于 AuthorizationServerConfig)

@Bean public AuthenticationEntryPoint authenticationEntryPoint() {     return (request, response, e) -> {         response.setStatus(HttpStatus.UNAUTHORIZED.value());         ResultData resultData = ResultData.fail(ReturnCode.CLIENT_AUTHENTICATION_FAILED.getCode(), ReturnCode.CLIENT_AUTHENTICATION_FAILED.getMessage());         WebUtils.writeJson(response,resultData);     }; }

修改认证服务器配置,注入自定义过滤器

@Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {  CustomClientCredentialsTokenEndpointFilter endpointFilter = new CustomClientCredentialsTokenEndpointFilter(security);  endpointFilter.afterPropertiesSet();  endpointFilter.setAuthenticationEntryPoint(authenticationEntryPoint());  security.addTokenEndpointAuthenticationFilter(endpointFilter);   security    .authenticationEntryPoint(authenticationEntryPoint())      /* .allowFormAuthenticationForClients()*/ //如果使用表单认证则需要加上    .tokenKeyAccess("permitAll()")    .checkTokenAccess("isAuthenticated()"); }

此时需要删除 allowFormAuthenticationForClients()配置,否则自定义的过滤器不生效,至于为什么不生效大家看看源码就知道了。

测试

授权模式错误

账号密码错误

客户端错误

关于"SpringCloud Alibaba中Oauth2认证服务器自定义异常怎么办"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

认证 处理 服务器 服务 错误 客户 客户端 方法 模式 密码 过滤器 配置 代码 方案 用户 篇文章 结果 解决方案 逻辑 面的 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 哈尔滨大商圈互联网科技有限公司 互联网科技英文 互联网金融科技创新 奇酷互联网络科技公司 丰台科技园 互联网公司 茂名市互联网科技产业园 互联网金融科技公司干啥的 湖北码尼互联网科技有限公司电话 中国航天科技大学国际工业互联网 互联网科技和信息 燊美集互联网科技有限公司 河南住房之家互联网科技 华夏恒生科技与互联网科技 山东有哪些互联网科技公司 互联网企业科技类企业如何做账 产业互联网科技服务公司 米泉互联网科技专业怎么样 互联网科技创新创业项目 亚光科技低轨卫星互联网 互联网企业和网络科技有限公司 咖啡网 天津市摩尔互联网科技 云信互联网科技有限公司 远拓互联网科技 广州善班互联网科技 互联网科技公司介绍 互联网公司会议桌创意科技软装饰 广州慧亚互联网科技怎么样 山东亿川互联网科技有限责任公司 如何强化互联网金融科技
0