Spring Security実戦ドライ商品:カスタム異常処理

5621 ワード

1.はじめに
最近は忙しいので、もっとSpring Securityの実戦商品シリーズを続けるのは難しいです.今日はちょうどプロジェクトの中でSpring Securityが認証認証に異常な処理が必要ですので、分けてください.
2.Spring Securityにおける異常
Spring Securityの異常は主に二つの種類に分けられます.一つは認証異常、もう一つは授権関連の異常です.
2.1 Authentication ExceptionAuthenticationExceptionは、ユーザ認証時にエラーが発生した場合に投げる異常である.主なサブクラスは図のようです.
この図の情報によれば、システムユーザは存在せず、ロックされ、証明書が失効し、パスワードエラーなどの認証過程で発生した異常は全部AuthenticationExceptionによって処理される.
2.2 Access DenieExceptionAccessDeniedExceptionは、保護されたリソースにアクセスする際に、ユーザが拒否されて投げられた異常である.AuthenticationExceptionと同様に、特定のサブクラスも提供されている.次の図のようにAccessDeniedExceptionのサブクラスは少ないです.主にCSRFに関する異常と授権サービス異常です.
3.Http状態の認証に関する規定
Httpプロトコルは認証認証の応答結果にも規定があります.
3.1 401無許可状態
HTTP 401エラー-未承認(Uauthorized)このエラーメッセージは、まずログイン(有効なユーザ名とパスワードを入力)する必要があることを示しています.これらの情報を入力した直後に401のエラーが表示されたとしたら、どのような理由であなたのユーザ名とパスワードの一つまたは両方が無効となります.つまり認証に失敗しました.実は私達の上のAuthenticationExceptionにぴったり対応しています.
3.2 403拒否された状態
HTTP 403エラー-禁止されています.このエラーは制限されたリソースにアクセスする際に許可されていないことを示しています.サーバーは今回の要求を理解しましたが、この要求はサーバに再送信するべきではありません.また、サーバは、特定のリソースにアクセスする権限がない理由をクライアントに知らせたいと考えています.サーバは、返信された情報の中で拒否の理由を説明すべきです.一般的な実践の中で私達は比較的にはっきりしないで原因を表明することができます.このエラーは私たちの上のAccessDeniedExceptionに対応しています.
4.Spring Securityにおける異常処理
私たちはSpring Securityの実戦商品シリーズの文章の中のユーザー定義の配置類の入口WebSecurityConfigrer Adapterの文でHttpSecurityから提供されたexceptionHandling()の方法を言及して異常処理を提供します.この方法は、ExceptionHandlingConfigurer異常処理構成クラスを構成している.この構成クラスは2つの実用インターフェースを提供しています.
  • Authentication EntryPointクラスは、異常AuthenticationExceptionを一括処理するために使用されます.
  • Access DeniedHandlerこのクラスは、統一処理AccessDeniedException異常
  • に使用される.
    この二つの異常処理類を実現して配置すれば、Spring Security認証に関する異常を統一的にカスタマイズすることができます.
    4.1 Authentication EntryPointを実現するjsonで情報に応答する.
     import com.fasterxml.jackson.databind.ObjectMapper;
     import org.springframework.http.MediaType;
     import org.springframework.security.core.AuthenticationException;
     import org.springframework.security.web.AuthenticationEntryPoint;
     
     import javax.servlet.ServletException;
     import javax.servlet.http.HttpServletRequest;
     import javax.servlet.http.HttpServletResponse;
     import java.io.IOException;
     import java.io.PrintWriter;
     import java.util.HashMap;
     
     /**
      * @author dax
      * @since 2019/11/6 22:11
      */
     public class SimpleAuthenticationEntryPoint implements AuthenticationEntryPoint {
         @Override
         public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
     
             //todo your business
             HashMap map = new HashMap<>(2);
             map.put("uri", request.getRequestURI());
             map.put("msg", "    ");
             response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
             response.setCharacterEncoding("utf-8");
             response.setContentType(MediaType.APPLICATION_JSON_VALUE);
             ObjectMapper objectMapper = new ObjectMapper();
             String resBody = objectMapper.writeValueAsString(map);
             PrintWriter printWriter = response.getWriter();
             printWriter.print(resBody);
             printWriter.flush();
             printWriter.close();
         }
     }
    4.2 Access DeniedHandlerを実現する
    同様にjsonで情報に応答する.
     import com.fasterxml.jackson.databind.ObjectMapper;
     import org.springframework.http.MediaType;
     import org.springframework.security.access.AccessDeniedException;
     import org.springframework.security.web.access.AccessDeniedHandler;
     
     import javax.servlet.ServletException;
     import javax.servlet.http.HttpServletRequest;
     import javax.servlet.http.HttpServletResponse;
     import java.io.IOException;
     import java.io.PrintWriter;
     import java.util.HashMap;
     
     /**
      * @author dax
      * @since 2019/11/6 22:19
      */
     public class SimpleAccessDeniedHandler implements AccessDeniedHandler {
         @Override
         public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
             //todo your business
             HashMap map = new HashMap<>(2);
             map.put("uri", request.getRequestURI());
             map.put("msg", "    ");
             response.setStatus(HttpServletResponse.SC_FORBIDDEN);
             response.setCharacterEncoding("utf-8");
             response.setContentType(MediaType.APPLICATION_JSON_VALUE);
             ObjectMapper objectMapper = new ObjectMapper();
             String resBody = objectMapper.writeValueAsString(map);
             PrintWriter printWriter = response.getWriter();
             printWriter.print(resBody);
             printWriter.flush();
             printWriter.close();
         }
     }
    璣璖璖萶4.3個人実践提案
    個人的には、Http状態コードは全部200に戻り、401状態を元情報Mapに戻すことを提案しています.異常状態コードはブラウザ側でerrorで表示されます.私たちは401403を捉えることができれば、認証問題ですか?それとも授権問題ですか?
    4.4配置
    上記2つのインターフェースが実現された後、私たちはWebSecurityConfigurerAdapterconfigure(HttpSecurity http)方法で構成すればいいです.関連するプロファイルは以下の通りです.
     http.exceptionHandling().accessDeniedHandler(new SimpleAccessDeniedHandler()).authenticationEntryPoint(new SimpleAuthenticationEntryPoint())
    5.まとめ
    今日はSpring Securityの異常処理について説明しました.独自の認証異常処理とカスタムのライセンス異常処理をそれぞれ実現しました.関連するDEMOは、WeChat公衆番号に注目することができる.Felordcn応答ss 07は取得する. :Felordcn 個人ブログ:https://felord.cn