Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Spring Security Oauth2 自定义 OAuth2 Exception

Spring Security Oauth2 自定义 OAuth2 Exception

作者头像
java干货
发布于 2021-02-19 03:35:26
发布于 2021-02-19 03:35:26
1.4K00
代码可运行
举报
文章被收录于专栏:java干货java干货
运行总次数:0
代码可运行

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

前言

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "error": "unauthorized",
  "error_description": "Full authentication is required to access this resource"
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
"error": "400",
"message": "坏的凭证",
"path": "/oauth/token",
"timestamp": "1527432468717"
}

自定义登录失败异常信息

新增CustomOauthException
  • 添加自定义异常类,指定json序列化方式
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@JsonSerialize(using = CustomOauthExceptionSerializer.class)
public class CustomOauthException extends OAuth2Exception {
    public CustomOauthException(String msg) {
        super(msg);
    }
}
新增CustomOauthExceptionSerializer
  • 添加CustomOauthException的序列化实现
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class CustomOauthExceptionSerializer extends StdSerializer<CustomOauthException> {
    public CustomOauthExceptionSerializer() {
        super(CustomOauthException.class);
    }

    @Override
    public 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
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class CustomOauthExceptionSerializer extends StdSerializer<CustomOauthException> {
    public CustomOauthExceptionSerializer() {
        super(CustomOauthException.class);
    }

    @Override
    public 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
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
    public 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);
            //jwt
            endpoints.tokenEnhancer(tokenEnhancerChain)
                    .accessTokenConverter(jwtAccessTokenConverter);
        }
        endpoints.exceptionTranslator(customWebResponseExceptionTranslator);
    }

自定义Token异常信息

添加AuthExceptionEntryPoint
  • 自定义AuthExceptionEntryPoint用于tokan校验失败返回信息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {


    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException)
            throws  ServletException {

        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)时返回信息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Slf4j
@Component("customAccessDeniedHandler")
public class CustomAccessDeniedHandler implements AccessDeniedHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public 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
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.authenticationEntryPoint(new AuthExceptionEntryPoint())
        .accessDeniedHandler(CustomAccessDeniedHandler);
    }

效果如下

登录异常
token异常
禁止访问
token失效

代码下载

推荐文章

  1. Java创建区块链系列
  2. Spring Security源码分析系列
  3. Spring Data Jpa 系列
  4. 【译】数据结构中关于树的一切(java版)
  5. SpringBoot+Docker+Git+Jenkins实现简易的持续集成和持续部署
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/05/27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
基于Spring Cloud Oauth2 JWT搭建微服务的安全认证中心
Oauth协议为用户资源的授权提供了一个安全的、开放而又建议的标准。oauth的授权不会是第三方初级到用户的账号信息(如用户名与密码),及第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此oauth是安全的。oauth是Open Authorization的简写
小东啊
2019/06/26
15.7K1
基于Spring Cloud Oauth2 JWT搭建微服务的安全认证中心
spring Cloud微服务 security+oauth2认证授权中心自定义令牌增强,并实现登录和退出
在之前的博客我写了 SpringCloud整合spring security+ oauth2+Redis实现认证授权,本文对返回的token实现自定义增强令牌返回结果,以及对于oauth2存在Redis的数据进行解释。
共饮一杯无
2022/11/28
1.1K0
spring Cloud微服务 security+oauth2认证授权中心自定义令牌增强,并实现登录和退出
零基础学习SpringSecurity OAuth2 四种授权模式(理论铺垫篇)
前段时间有同学私信我,让我讲下Oauth2授权模式,并且还强调是零基础的那种,我也不太理解这个零基础到底是什么程度,但是我觉得任何阶段的同学看完我这个视频,对OAuth2的理解将会有很大的提升,并且也会熟练的使用SpringSecurity OAuth2,轻松搭建认证服务和资源服务。
AI码师
2022/09/19
1.1K0
零基础学习SpringSecurity OAuth2 四种授权模式(理论铺垫篇)
Spring Security OAuth2.0实现
OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容,OAuth2.0是OAuth协议的延续版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0。
兜兜转转
2023/03/29
2.9K0
Spring Security OAuth2.0实现
Spring Security---Oauth2详解
在说明OAuth2需求及使用场景之前,需要先介绍一下OAuth2授权流程中的各种角色:
大忽悠爱学习
2021/12/07
4.7K0
Spring Security---Oauth2详解
【Spring底层原理高级进阶】【SpringCloud整合Spring Security OAuth2】深入了解 Spring Security OAuth2:底层解析+使用方法+实战
OAuth2(Open Authorization 2.0)是一种用于授权的开放标准协议,用于通过第三方应用程序访问用户在某个服务提供商上存储的资源,而无需共享用户的凭证(例如用户名和密码)。它允许用户授权给第三方应用程序访问受保护的资源,同时确保用户的凭证信息不被直接暴露给第三方应用程序。
苏泽
2024/03/01
2.5K0
【Spring底层原理高级进阶】【SpringCloud整合Spring Security OAuth2】深入了解 Spring Security OAuth2:底层解析+使用方法+实战
Spring Cloud Security:Oauth2结合JWT使用
https://github.com/macrozheng/springcloud-learning
macrozheng
2019/11/07
3.5K0
Spring Cloud Security:Oauth2结合JWT使用
Spring security oauth2的认证流程2 原
OAuth2AuthenticationProcessingFilter中作为filter拦截认证会借助tokenExtractor从request中获取token的值,将其转换为Authentication 对象。
用户1499526
2019/08/20
1K0
SpringBoot实现接口限流(Redis版本)
随着前后端分离架构的流⾏,前端页面与后端接口的调⽤关系越来越复杂,后端服务的稳定性越来越重要。在遇到突发的请求量激增,恶意的⽤户访问,亦或请求频率过⾼给下游服务带来较⼤压⼒时,我们常常需要通过缓存、限流、负载均衡等多种⽅式保证后端服务的稳定性。其中,限流是不可或缺的⼀环。
水煮麥楽雞
2022/11/20
9030
springboot第22集:security,Lombok,token,redis
Spring Security是一个基于Spring框架的权限管理框架,用于帮助应用程序实现身份验证和授权功能。它可以为Web应用程序、REST API和方法级安全性提供支持,并支持各种认证方式。
达达前端
2023/10/08
5280
springboot第22集:security,Lombok,token,redis
Spring Security OAUTH2 获取用户信息
作用:二者皆是为了check token,并且顺带返回了用户信息。配置信息位置在资源服务器上。
全栈程序员站长
2022/10/04
1.7K0
Spring Security OAUTH2 获取用户信息
Spring Security入门(二) 基于内存存储的表单登录实战
Spring Security 对Servlet的安全认证是基于包含一系列的过滤器对请求进行层层拦截处理实现的,多个过滤器组成过滤器链。处理单个http 请求的过滤链角色示意图如下所示:
用户3587585
2022/09/21
7850
Spring Security入门(二) 基于内存存储的表单登录实战
Spring Security 系列(2) —— Spring Security OAuth2
OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。
求和小熊猫
2022/06/30
6.2K0
Spring Boot 中关于自定义异常处理的套路!
在 Spring Boot 项目中 ,异常统一处理,可以使用 Spring 中 @ControllerAdvice 来统一处理,也可以自己来定义异常处理方案。Spring Boot 中,对异常的处理有一些默认的策略,我们分别来看。
纯洁的微笑
2019/05/06
1.3K0
Spring Boot 中关于自定义异常处理的套路!
微服务权限终极解决方案,Spring Cloud Gateway + Oauth2 实现统一认证和鉴权!
https://github.com/macrozheng/springcloud-learning/tree/master/micro-oauth2
macrozheng
2020/07/14
24.6K0
微服务权限终极解决方案,Spring Cloud Gateway + Oauth2 实现统一认证和鉴权!
spring security oauth2认证服务器 用户授权确认 流程源码 配置要点
org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint
路过君
2021/12/07
9870
如何让 Spring Security 「少管闲事」
一个应用对外提供 Rest 接口,接口的访问认证通过 Spring Security OAuth2 控制,token 形式为 JWT。因为一些原因,某一特定路径前缀(假设为 /custom/)的接口需要使用另外一种自定义的认证方式,token 是一串无规则的随机字符串。两种认证方式的 token 都是在 Headers 里传递,形式都是 Authorization: bearer xxx。
mzlogin
2023/10/23
3520
如何让 Spring Security 「少管闲事」
Spring Security源码分析十二:Spring Security OAuth2基于JWT实现单点登录
用户的登录状态是由sso-server认证中心来保存的,登录界面和账号密码的验证也是sso-server认证中心来做的(client1和clien2返回token是不同的,但解析出来的用户信息是同一个用户)。
java干货
2021/02/19
1.6K1
Spring Security源码分析十二:Spring Security OAuth2基于JWT实现单点登录
分布式环境中spring cloud oauth2授权服务异常处理
springboot 2.3.7 spring cloud 2.2.6 spring security 2.3.8 分布式部署多个spring security oauth2授权服务器实例,使用redis session同步会话
路过君
2021/12/07
6670
Spring Boot+OAuth2,如何自定义返回的 Token 信息?
在本系列前面的文章中,正常情况下,OAuth2 返回的 access_token 信息一共包含五项:
江南一点雨
2020/04/27
2.9K0
推荐阅读
相关推荐
基于Spring Cloud Oauth2 JWT搭建微服务的安全认证中心
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档