最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot?Security的自定義異常處理

 更新時(shí)間:2021年12月20日 09:30:10   作者:香酥蟹  
這篇文章主要介紹了SpringBoot?Security的自定義異常處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

SpringBoot Security自定義異常

access_denied 方面異常

原異常

{
    "error": "access_denied",
    "error_description": "不允許訪問(wèn)"
}

現(xiàn)異常

{
    "success": false,
    "error": "access_denied",
    "status": 403,
    "message": "不允許訪問(wèn)",
    "path": "/user/get1",
    "timestamp": 1592378892768
}

實(shí)現(xiàn)

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"
}

現(xiàn)異常

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

實(shí)現(xiàn)

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 方面異常(登陸出錯(cuò))

原異常

{
    "error": "invalid_grant",
    "error_description": "用戶名或密碼錯(cuò)誤"
}

現(xiàn)異常

{
    "success": false,
    "error": "invalid_grant",
    "status": 400,
    "message": "用戶名或密碼錯(cuò)誤",
    "path": "/oauth/token",
    "timestamp": 1592384576019
}

實(shí)現(xiàn)

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;
    }
}

補(bǔ)充

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

如果client_secret錯(cuò)誤依然還是報(bào)錯(cuò),如上內(nèi)容,針對(duì)這個(gè)異常需要在如下方法中的addTokenEndpointAuthenticationFilter添加過(guò)濾器處理

  @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
      oauthServer
                // 開啟/oauth/token_key驗(yàn)證端口無(wú)權(quán)限訪問(wèn)
                .tokenKeyAccess("permitAll()")
                // 開啟/oauth/check_token驗(yàn)證端口認(rèn)證權(quán)限訪問(wèn)
                .checkTokenAccess("isAuthenticated()")
                .addTokenEndpointAuthenticationFilter(null)
                .allowFormAuthenticationForClients();
    }

SpringSecurity自定義響應(yīng)異常信息

此處的異常信息設(shè)置的話,其中還是有坑的,比如你想自定義token過(guò)期信息,無(wú)效token這些,如果按照SpringSecurity的設(shè)置是不會(huì)生效的,需要加到資源的配置中。

如果只是SpringSecurity的話,只需要實(shí)現(xiàn)AccessDeniedHandler和AuthenticationEntryPoint這2個(gè)接口就可以了。他們都是在ExceptionTranslationFilter中生效的。

  • AuthenticationEntryPoint 用來(lái)解決匿名用戶訪問(wèn)無(wú)權(quán)限資源時(shí)的異常
  • ruAccessDeineHandler 用來(lái)解決認(rèn)證過(guò)的用戶訪問(wèn)無(wú)權(quán)限資源時(shí)的異常

image-20210823192313538

如果你想自定義token過(guò)期的話,需要實(shí)現(xiàn)AuthenticationEntryPoint這個(gè)接口,因?yàn)閠oken過(guò)期了,訪問(wèn)的話也算是匿名訪問(wèn)。

但是SpringSecurity的過(guò)濾器鏈中其實(shí)是有順序的,校驗(yàn)token的OAuth2AuthenticationProcessingFilter在它前面,導(dǎo)致一直沒(méi)有辦法生效,所有需要添加到資源的配置上,demo如下:

/**
 * @author WGR
 * @create 2021/8/23 -- 16:52
 */
@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", "無(wú)效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

如果想設(shè)置沒(méi)有權(quán)限的自定義異常信息的話:

/**
 * @author WGR
 * @create 2021/8/23 -- 17:09
 */
@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", "無(wú)權(quán)操作");
        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();
        }
    }
}

把它設(shè)置到springsecurity中,添加進(jìn)去就可以了,如果不是想要捕獲token過(guò)期的話,就直接添加進(jìn)去也可以

image-20210823194105642

image-20210823193825241

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringAOP中基于注解實(shí)現(xiàn)通用日志打印方法詳解

    SpringAOP中基于注解實(shí)現(xiàn)通用日志打印方法詳解

    這篇文章主要介紹了SpringAOP中基于注解實(shí)現(xiàn)通用日志打印方法詳解,在日常開發(fā)中,項(xiàng)目里日志是必不可少的,一般有業(yè)務(wù)日志,數(shù)據(jù)庫(kù)日志,異常日志等,主要用于幫助程序猿后期排查一些生產(chǎn)中的bug,需要的朋友可以參考下
    2023-12-12
  • java發(fā)送http get請(qǐng)求的兩種方式

    java發(fā)送http get請(qǐng)求的兩種方式

    這篇文章主要為大家詳細(xì)介紹了java發(fā)送http get請(qǐng)求的兩種方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 詳細(xì)介紹Java函數(shù)式接口

    詳細(xì)介紹Java函數(shù)式接口

    函數(shù)式接口在Java中是指有且僅有一個(gè)抽象方法的接口。當(dāng)然接口中可以包含其他的方法默認(rèn)、靜態(tài)、私有,具體內(nèi)容請(qǐng)參考下面文章內(nèi)容
    2021-09-09
  • 使用自定義參數(shù)解析器同一個(gè)參數(shù)支持多種Content-Type

    使用自定義參數(shù)解析器同一個(gè)參數(shù)支持多種Content-Type

    這篇文章主要介紹了使用自定義參數(shù)解析器同一個(gè)參數(shù)支持多種Content-Type的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 初識(shí)Java8中的Stream

    初識(shí)Java8中的Stream

    lambda表達(dá)式是stream的基礎(chǔ),接下來(lái)通過(guò)實(shí)例代碼給大家詳細(xì)介紹java8中的stream,感興趣的朋友一起看看吧
    2017-08-08
  • 基于Java回顧之I/O的使用詳解

    基于Java回顧之I/O的使用詳解

    我計(jì)劃在接下來(lái)的幾篇文章中快速回顧一下Java,主要是一些基礎(chǔ)的JDK相關(guān)的內(nèi)容
    2013-05-05
  • SpringBoot開發(fā)中的組件和容器詳解

    SpringBoot開發(fā)中的組件和容器詳解

    這篇文章主要介紹了SpringBoot開發(fā)中的組件和容器詳解,SpringBoot 提供了一個(gè)內(nèi)嵌的 Tomcat 容器作為默認(rèn)的 Web 容器,同時(shí)還支持其他 Web 容器和應(yīng)用服務(wù)器,需要的朋友可以參考下
    2023-09-09
  • Spring Data JPA 如何使用QueryDsl查詢并分頁(yè)

    Spring Data JPA 如何使用QueryDsl查詢并分頁(yè)

    這篇文章主要介紹了Spring Data JPA 如何使用QueryDsl查詢并分頁(yè),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java利用策略模式實(shí)現(xiàn)條件判斷,告別if else

    Java利用策略模式實(shí)現(xiàn)條件判斷,告別if else

    策略模式定義了一系列算法,并且將每個(gè)算法封裝起來(lái),使得他們可以相互替換,而且算法的變化不會(huì)影響使用算法的客戶端。本文將通過(guò)案例講解如何利用Java的策略模式實(shí)現(xiàn)條件判斷,告別if----else條件硬編碼,需要的可以參考一下
    2022-02-02
  • 詳解IDEA中MAVEN項(xiàng)目打JAR包的簡(jiǎn)單方法

    詳解IDEA中MAVEN項(xiàng)目打JAR包的簡(jiǎn)單方法

    本篇文章主要介紹了詳解IDEA中MAVEN項(xiàng)目打JAR包的簡(jiǎn)單方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12

最新評(píng)論

安陆市| 浦北县| 元朗区| 鄂托克前旗| 增城市| 康乐县| 肥东县| 长葛市| 宁津县| 平顺县| 沐川县| 长顺县| 嘉义县| 叙永县| 台安县| 吉水县| 柳江县| 聂拉木县| 马鞍山市| 安顺市| 清水河县| 遵义市| 吴江市| 新沂市| 肥西县| 海安县| 金湖县| 怀仁县| 和顺县| 门源| 南开区| 璧山县| 珠海市| 望城县| 汝州市| 随州市| 安国市| 稷山县| 黔东| 阳城县| 昌黎县|