Spring Security Oauth2 自定义 OAuth2 Exception

本文介绍了如何在Spring Security Oauth2中自定义登录和Token异常信息,包括新增CustomOauthException、AuthExceptionEntryPoint和CustomAccessDeniedHandler等,以实现与应用统一的错误响应格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

付出就要得到回报,这种想法是错的。

[

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/27/163a194a8f506f26~tplv-t2oaga2asx-image.image

](https://link.juejin.cn/?target=https%3A%2F%2Fp1-jj.byteimg.com%2Ftos-cn-i-t2oaga2asx%2Fgold-user-assets%2F2018%2F5%2F27%2F163a194a8f506f26~tplv-t2oaga2asx-image.image “https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/27/163a194a8f506f26~tplv-t2oaga2asx-image.image”)

前言

在使用Spring Security Oauth2登录和鉴权失败时,默认返回的异常信息如下

{"error": "unauthorized","error_description": "Full authentication is required to access this resource"
} 

。它与我们自定义返回信息不一致,并且描述信息较少。那么如何自定义Spring Security Oauth2异常信息呢,下面我们简单实现以下。格式如下:

 {
"error": "400",
"message": "坏的凭证",
"path": "/oauth/token",
"timestamp": "1527432468717"
} 

自定义登录失败异常信息

新增CustomOauthException
  • 添加自定义异常类,指定json序列化方式
@JsonSerialize(using = CustomOauthExceptionSerializer.class)
public class CustomOauthException extends OAuth2Exception {public CustomOauthException(String msg) {super(msg);}
} 
新增CustomOauthExceptionSerializer
  • 添加CustomOauthException的序列化实现
public class CustomOauthExceptionSerializer extends StdSerializer<CustomOauthException> {public CustomOauthExceptionSerializer() {super(CustomOauthException.class);}@Overridepublic void serialize(CustomOauthException value, JsonGenerator gen, SerializerProvider provider) throws IOException {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();gen.writeStartObject();gen.writeStringField("error", String.valueOf(value.getHttpErrorCode()));gen.writeStringField("message", value.getMessage());
//gen.writeStringField("message", "用户名或密码错误");gen.writeStringField("path", request.getServletPath());gen.writeStringField("timestamp", String.valueOf(new Date().getTime()));if (value.getAdditionalInformation()!=null) {for (Map.Entry<String, String> entry : value.getAdditionalInformation().entrySet()) {String key = entry.getKey();String add = entry.getValue();gen.writeStringField(key, add);}}gen.writeEndObject();}
} 
添加CustomWebResponseExceptionTranslator
  • 添加CustomWebResponseExceptionTranslator,登录发生异常时指定exceptionTranslator
public class CustomOauthExceptionSerializer extends StdSerializer<CustomOauthException> {public CustomOauthExceptionSerializer() {super(CustomOauthException.class);}@Overridepublic void serialize(CustomOauthException value, JsonGenerator gen, SerializerProvider provider) throws IOException {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();gen.writeStartObject();gen.writeStringField("error", String.valueOf(value.getHttpErrorCode()));gen.writeStringField("message", value.getMessage());
//gen.writeStringField("message", "用户名或密码错误");gen.writeStringField("path", request.getServletPath());gen.writeStringField("timestamp", String.valueOf(new Date().getTime()));if (value.getAdditionalInformation()!=null) {for (Map.Entry<String, String> entry : value.getAdditionalInformation().entrySet()) {String key = entry.getKey();String add = entry.getValue();gen.writeStringField(key, add);}}gen.writeEndObject();}
} 
修改MerryyouAuthorizationServerConfig
  • 指定自定义customWebResponseExceptionTranslator
@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.tokenStore(tokenStore).authenticationManager(authenticationManager).userDetailsService(userDetailsService);//扩展token返回结果if (jwtAccessTokenConverter != null && jwtTokenEnhancer != null) {TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();List<TokenEnhancer> enhancerList = new ArrayList();enhancerList.add(jwtTokenEnhancer);enhancerList.add(jwtAccessTokenConverter);tokenEnhancerChain.setTokenEnhancers(enhancerList);//jwtendpoints.tokenEnhancer(tokenEnhancerChain).accessTokenConverter(jwtAccessTokenConverter);}endpoints.exceptionTranslator(customWebResponseExceptionTranslator);} 

自定义Token异常信息

添加AuthExceptionEntryPoint
  • 自定义AuthExceptionEntryPoint用于tokan校验失败返回信息
public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)throwsServletException {Map map = new HashMap();map.put("error", "401");map.put("message", authException.getMessage());map.put("path", request.getServletPath());map.put("timestamp", String.valueOf(new Date().getTime()));response.setContentType("application/json");response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);try {ObjectMapper mapper = new ObjectMapper();mapper.writeValue(response.getOutputStream(), map);} catch (Exception e) {throw new ServletException();}}
} 
添加CustomAccessDeniedHandler
  • 授权失败(forbidden)时返回信息
@Slf4j
@Component("customAccessDeniedHandler")
public class CustomAccessDeniedHandler implements AccessDeniedHandler {@Autowiredprivate ObjectMapper objectMapper;@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {response.setContentType("application/json;charset=UTF-8");Map map = new HashMap();map.put("error", "400");map.put("message", accessDeniedException.getMessage());map.put("path", request.getServletPath());map.put("timestamp", String.valueOf(new Date().getTime()));response.setContentType("application/json");response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.getWriter().write(objectMapper.writeValueAsString(map));}
} 
修改MerryyouResourceServerConfig
 @Overridepublic void configure(ResourceServerSecurityConfigurer resources) throws Exception {resources.authenticationEntryPoint(new AuthExceptionEntryPoint()).accessDeniedHandler(CustomAccessDeniedHandler);} 

效果如下

登录异常

[

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/27/163a194a95131f78~tplv-t2oaga2asx-image.image

](https://link.juejin.cn/?target=https%3A%2F%2Fp1-jj.byteimg.com%2Ftos-cn-i-t2oaga2asx%2Fgold-user-assets%2F2018%2F5%2F27%2F163a194a95131f78~tplv-t2oaga2asx-image.image “https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/27/163a194a95131f78~tplv-t2oaga2asx-image.image”)

token异常

[

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/27/163a194a8944f75a~tplv-t2oaga2asx-image.image

](https://link.juejin.cn/?target=https%3A%2F%2Fp1-jj.byteimg.com%2Ftos-cn-i-t2oaga2asx%2Fgold-user-assets%2F2018%2F5%2F27%2F163a194a8944f75a~tplv-t2oaga2asx-image.image “https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/27/163a194a8944f75a~tplv-t2oaga2asx-image.image”)

禁止访问

[

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/27/163a194a88807c3b~tplv-t2oaga2asx-image.image

](https://link.juejin.cn/?target=https%3A%2F%2Fp1-jj.byteimg.com%2Ftos-cn-i-t2oaga2asx%2Fgold-user-assets%2F2018%2F5%2F27%2F163a194a88807c3b~tplv-t2oaga2asx-image.image “https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/27/163a194a88807c3b~tplv-t2oaga2asx-image.image”)

token失效

[

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/27/163a194a8f7dd59d~tplv-t2oaga2asx-image.image

](https://link.juejin.cn/?target=https%3A%2F%2Fp1-jj.byteimg.com%2Ftos-cn-i-t2oaga2asx%2Fgold-user-assets%2F2018%2F5%2F27%2F163a194a8f7dd59d~tplv-t2oaga2asx-image.image “https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/27/163a194a8f7dd59d~tplv-t2oaga2asx-image.image”)

代码下载

推荐文章

1.Java创建区块链系列
2.Spring Security源码分析系列
3.Spring Data Jpa 系列
4.【译】数据结构中关于树的一切(java版)
5.SpringBoot+Docker+Git+Jenkins实现简易的持续集成和持续部署


零基础入门

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

同时每个成长路线对应的板块都有配套的视频提供:

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
视频配套资料&国内外网安书籍、文档&工具
当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料&工具,并且已经帮大家分好类了。
在这里插入图片描述
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值