广告
返回顶部
首页 > 资讯 > 后端开发 > Python >SpringBoot Security的自定义异常处理
  • 888
分享到

SpringBoot Security的自定义异常处理

2024-04-02 19:04:59 888人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录SpringBoot Security自定义异常access_denied 方面异常Invalid access token 方面异常Bad credentials 方面异常(登

SpringBoot Security自定义异常

access_denied 方面异常

原异常


{
    "error": "access_denied",
    "error_description": "不允许访问"
}

现异常


{
    "success": false,
    "error": "access_denied",
    "status": 403,
    "message": "不允许访问",
    "path": "/user/get1",
    "timestamp": 1592378892768
}

实现


public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        // access_denied 方面异常
        OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler = new OAuth2AccessDeniedHandler();
        oAuth2AccessDeniedHandler.setExceptionTranslator(new CustomWEBResponseExceptionTranslator());
        resources.accessDeniedHandler(oAuth2AccessDeniedHandler);
    }
}

Invalid access token 方面异常

原异常


{
    "error": "invalid_token",
    "error_description": "Invalid access token: 4eb58ecf-e66de-4155-9477-64a1c9805cc8"
}

现异常


{
    "success": false,
    "error": "invalid_token",
    "status": 401,
    "message": "Invalid access token: 8cd45925dbf6-4502-bd13-8101bc6e1d4b",
    "path": "/user/get1",
    "timestamp": 1592378949452
}

实现


public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
         // Invalid access token 方面异常
        OAuth2AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
        authenticationEntryPoint.setExceptionTranslator(new CustomWebResponseExceptionTranslator());
        resources.authenticationEntryPoint(authenticationEntryPoint);
    }
}

Bad credentials 方面异常(登陆出错)

原异常


{
    "error": "invalid_grant",
    "error_description": "用户名或密码错误"
}

现异常


{
    "success": false,
    "error": "invalid_grant",
    "status": 400,
    "message": "用户名或密码错误",
    "path": "/oauth/token",
    "timestamp": 1592384576019
}

实现


public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
     @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.userDetailsService(detailsService)
                .tokenStore(memoryTokenStore())
                .exceptionTranslator(new CustomWebResponseExceptionTranslator())
                .authenticationManager(authenticationManager)
                //接收GET和POST
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
    }
}

其他类


@Getter
@JSONSerialize(using = CustomOauthExceptionSerializer.class)
public class CustomOauthException extends OAuth2Exception {
    private String oAuth2ErrorCode;
    private int httpErrorCode;
    public CustomOauthException(String msg, String oAuth2ErrorCode, int httpErrorCode) {
        super(msg);
        this.oAuth2ErrorCode = oAuth2ErrorCode;
        this.httpErrorCode = httpErrorCode;
    }
}

public class CustomOauthExceptionSerializer extends StdSerializer<CustomOauthException> {
    private static final long serialVersionUID = 2652127645704345563L;
    public CustomOauthExceptionSerializer() {
        super(CustomOauthException.class);
    }
    @Override
    public void serialize(CustomOauthException value, jsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartObject();
        httpservletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        gen.writeObjectField("success",false);
        gen.writeObjectField("error",value.getOAuth2ErrorCode());
        gen.writeObjectField("status", value.getHttpErrorCode());
        gen.writeObjectField("message", value.getMessage());
        gen.writeObjectField("path", request.getServletPath());
        gen.writeObjectField("timestamp", (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.writeObjectField(key, add);
            }
        }
        gen.writeEndObject();
    }
}

public class CustomWebResponseExceptionTranslator extends DefaultWebResponseExceptionTranslator {
    @Override
    public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
        ResponseEntity<OAuth2Exception> translate = super.translate(e);
        OAuth2Exception body = translate.getBody();
        CustomOauthException customOauthException = new CustomOauthException(body.getMessage(),body.getOAuth2ErrorCode(),body.getHttpErrorCode());
        ResponseEntity<OAuth2Exception> response = new ResponseEntity<>(customOauthException, translate.getHeaders(),
                translate.getStatusCode());
        return response;
    }
}

补充


{
    "error": "invalid_client",
    "error_description": "Bad client credentials"
}

如果client_secret错误依然还是报错,如上内容,针对这个异常需要在如下方法中的addTokenEndpointAuthenticationFilter添加过滤器处理


  @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
      oauthServer
                // 开启/oauth/token_key验证端口无权限访问
                .tokenKeyAccess("permitAll()")
                // 开启/oauth/check_token验证端口认证权限访问
                .checkTokenAccess("isAuthenticated()")
                .addTokenEndpointAuthenticationFilter(null)
                .allowFormAuthenticationForClients();
    }

SpringSecurity自定义响应异常信息

此处的异常信息设置的话,其中还是有坑的,比如你想自定义token过期信息,无效token这些,如果按照SpringSecurity的设置是不会生效的,需要加到资源的配置中。

如果只是SpringSecurity的话,只需要实现AccessDeniedHandler和AuthenticationEntryPoint这2个接口就可以了。他们都是在ExceptionTranslationFilter中生效的。

  • AuthenticationEntryPoint 用来解决匿名用户访问无权限资源时的异常
  • ruAccessDeineHandler 用来解决认证过的用户访问无权限资源时的异常

image-20210823192313538

如果你想自定义token过期的话,需要实现AuthenticationEntryPoint这个接口,因为token过期了,访问的话也算是匿名访问。

但是SpringSecurity的过滤器链中其实是有顺序的,校验token的OAuth2AuthenticationProcessingFilter在它前面,导致一直没有办法生效,所有需要添加到资源的配置上,demo如下:



@Component
public class SimpleAuthenticationEntryPoint implements AuthenticationEntryPoint {
 
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) throws ServletException {
        Throwable cause = authException.getCause();
        try {
            if (cause instanceof InvalidTokenException) {
                Map map = new HashMap();
                map.put("error", "无效token");
                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();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

image-20210823192757483

则可以生效,返回信息具体如下:

image-20210823192828621

如果想设置没有权限的自定义异常信息的话:



@Component
public class SimpleAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        Map map = new HashMap();
        map.put("message", "无权操作");
        map.put("path", request.getServletPath());
        map.put("timestamp", String.valueOf(new Date().getTime()));
        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.writeValue(response.getOutputStream(), map);
        } catch (Exception e) {
            throw new ServletException();
        }
    }
}

把它设置到springsecurity中,添加进去就可以了,如果不是想要捕获token过期的话,就直接添加进去也可以

image-20210823194105642

image-20210823193825241

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: SpringBoot Security的自定义异常处理

本文链接: https://www.lsjlt.com/news/160311.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • SpringBoot Security的自定义异常处理
    目录SpringBoot Security自定义异常access_denied 方面异常Invalid access token 方面异常Bad credentials 方面异常(登...
    99+
    2022-11-12
  • SpringBoot Security如何自定义异常处理
    这篇文章主要为大家展示了“SpringBoot Security如何自定义异常处理”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“SpringBoot Security如何自定...
    99+
    2023-06-22
  • shiro与spring security用自定义异常处理401错误
    目录shiro与spring security自定义异常处理401背景解决方案SpringBoot整合Shiro自定义filter报错No SecurityManager acces...
    99+
    2022-11-12
  • springboot实现全局异常处理及自定义异常类
    目录全局异常处理及自定义异常类全局异常处理定义一个业务异常的枚举全局异常处理配置springboot Restful使用springboot 返回 ModelAndView全局异常处...
    99+
    2022-11-13
  • shiro与spring security怎么用自定义异常处理401错误
    这篇文章主要介绍shiro与spring security怎么用自定义异常处理401错误,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!shiro与spring security自定义异常处理401背景现在是...
    99+
    2023-06-21
  • springboot如何实现全局异常处理及自定义异常类
    这篇文章主要介绍springboot如何实现全局异常处理及自定义异常类,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!全局异常处理及自定义异常类全局异常处理定义一个处理类,使用@ControllerAdvice注解。@...
    99+
    2023-06-29
  • Springboot项目中如何实现异常处理自定义
    这期内容当中小编将会给大家带来有关Springboot项目中如何实现异常处理自定义,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。背景Springboot 默认把异常的处理集中到一个ModelAndView...
    99+
    2023-05-31
    springboot 异常处理 目中
  • SpringBoot+Hibernate实现自定义数据验证及异常处理
    目录前言Hibernate实现字段校验自定义校验注解使用AOP处理校验异常全局异常类处理异常前言 在进行 SpringBoot 项目开发中,经常会碰到属性合法性问题,而面对这个问题通...
    99+
    2022-11-13
  • SpringBoot详解实现自定义异常处理页面方法
    目录1.相关介绍2.代码实现3.运行测试1.相关介绍 当发生异常时, 跳转到我们自定义的异常处理页面. SpringBoot中只需在静态资源目录下创建一个error文件夹, 并把异常...
    99+
    2022-11-13
  • SpringMVC 异常处理机制与自定义异常处理方式
    目录SpringMVC默认处理的几种异常@ResponseStatus异常处理的顺序自定义异常类(SpringMVC的异常处理)①:自定义异常类②:自定义异常处理器③:配置我们的异常...
    99+
    2022-11-12
  • C#WINFORM自定义异常处理方法
    一个简单的统一异常处理方法。系统底层出现异常,写入记录文件,系统顶层捕获底层异常,显示提示信息。  /// <summary> /// 自定义异常类 ...
    99+
    2022-11-12
  • 自定义注解和springAOP捕获Service层异常,并处理自定义异常操作
    一 自定义异常 public class NoParamsException extends Exception { //用详细信息指定一个异常 public ...
    99+
    2022-11-12
  • PHP中怎么自定义异常处理器
    本篇文章为大家展示了PHP中怎么自定义异常处理器,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1、异常类的层级关系:class NotFoundException extends...
    99+
    2023-06-17
  • Spring Boot 中自定义异常怎么处理
    这篇文章将为大家详细讲解有关Spring Boot 中自定义异常怎么处理,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在 Spring Boot 项目中 ,异常统一处理,可以使用 Spring 中 @Co...
    99+
    2023-06-02
  • 自定义注解和springAOP捕获Service层异常并处理自定义异常的示例分析
    这篇文章主要为大家展示了“自定义注解和springAOP捕获Service层异常并处理自定义异常的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“自定义注解和springAOP捕获Serv...
    99+
    2023-06-15
  • SpringMVC异常处理机制与自定义异常处理方式的示例分析
    这篇文章主要介绍SpringMVC异常处理机制与自定义异常处理方式的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!提到异常处理,就不得不提HandlerExceptionResolvers,我们的Dispat...
    99+
    2023-06-25
  • springboot如何自定义异常并捕获异常返给前端
    小编给大家分享一下springboot如何自定义异常并捕获异常返给前端,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!背景在开发中,如果用try catch的方式,...
    99+
    2023-06-25
  • 浅谈几种Java自定义异常处理方式
    目录自定义异常类错误编码处理断言处理应用日志处理异常消息模板和格式化处理总结在Java中,异常是一种常见的处理机制。当程序运行出现错误时,Java会默认抛出一个异常,并通过栈回溯信息...
    99+
    2023-05-19
    Java自定义异常 Java 异常
  • RestTemplate自定义请求失败异常如何处理
    今天小编给大家分享一下RestTemplate自定义请求失败异常如何处理的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、异...
    99+
    2023-06-29
  • springboot集成shiro遭遇自定义filter异常的解决
    目录springboot集成shiro遭遇自定义filter异常1、用maven添加shiro2、配置shiro3、实现自定义的Realm、filter、SubjectFactory...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作