ホームページ > Java > &#&チュートリアル > Spring AOP を使用して SpringBoot にインターフェイス認証を実装する方法

Spring AOP を使用して SpringBoot にインターフェイス認証を実装する方法

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
リリース: 2023-05-19 18:13:12
転載
1349 人が閲覧しました

アスペクト指向プログラミング

アスペクト指向プログラミングは、ビジネスとは関係がないが、さまざまなビジネス モジュールから共同で呼び出す必要があるロジックを抽出し、それをアスペクトの形式でコードに切り込むことができます。これにより、システム内のコードの結合が軽減され、重複コードが削減されます。

Spring AOP は、実行時のプリコンパイルと動的プロキシを通じてアスペクト指向プログラミングを実装します

AOP の基礎となる原理が実装されます

基礎となる使用法AOP は動的です プロキシは要件を満たし、拡張が必要な​​クラスのプロキシ クラスを生成します。プロキシ クラスを生成するには 2 つの方法があります。プロキシ クラス (つまり、拡張が必要な​​クラス) の場合、

  • #インターフェースが実装されており、JDK 動的プロキシが使用されている場合、生成されたプロキシ クラスはそのインターフェースを使用します。インターフェースが実装されていない場合、

  • CGlib ダイナミック プロキシが使用されている場合、生成されるプロキシ クラスは統合プロキシ クラスになります

AOP 関連用語

  • 接続ポイント:プロキシされた (拡張された) クラスのメソッド

  • エントリ ポイント:実際に拡張する必要があるメソッド

  • 通知: 強化されるロジック コード

    • 事前通知: 実行前に実行されます。メイン関数

    • 投稿通知: テーマ関数の実行後に実行

    • ## サラウンド通知:

      メイン関数の実行前後に実行されます

    • 例外通知:

      テーマ関数の実行で例外が発生した場合に実行されます

    • #最終通知:
    • main 関数は、実行が成功したかどうかに関係なく実行されます

    • #アスペクト:
    エントリ ポイントとアスペクトの組み合わせ、つまりアスペクトを形成する拡張メソッドと拡張関数
  • 関連コメントとポイントカット式

注釈:

@Aspect:
    特定のクラスがアスペクトであることを宣言し、通知とエントリ ポイントを記述します
  • @Before:
  • 対応する事前通知
  • @AfterReturning:
  • 事後通知に対応
  • @Around:
  • 周囲の通知に対応
  • #@AfterThrowing:
  • 例外通知に対応
  • #@変更後:
  • 最終通知に対応
  • @ポイントカット:
  • ステートメントのポイントカットをメソッド上でマークすると、式がより簡潔になります
  • ポイントカット式を使用してポイントカットを宣言します

execution([権限修飾子][戻り値の型][完全なクラス パス]。 [メソッド名][パラメータリストの種類])

  • execution(* com.xxx.ABC.add())、ABCクラスのメソッドを拡張

  • インターフェースを実装認証

1. yml ファイルの構成

インターフェイス認証アカウントの構成

account:
  infos:
    - account: xinchao
      secret: admin
ログイン後にコピー
2. アカウントとパスワードの構成の読み取り

@Data
public class SecretInfo {
    private String account;
    private String secret;
}
ログイン後にコピー

3. インターフェース認証メソッドを記述します
@Configuration
@ConfigurationProperties("account")
public class SecretConfig {
    private List<SecretInfo> infos;

    private Map<String, SecretInfo> map;

    private Map<String, TokenInfo> tokenMap = new HashMap<>();

    public void setInfos(List<SecretInfo> infos) {
        this.infos = infos;
        map = infos.stream().collect(Collectors.toMap(SecretInfo::getAccount, Function.identity()));
    }

    public synchronized String getToken(String account, String secret) {
        SecretInfo info = map.get(account);
        if (info == null) {
            throw new BusinessException("无效账号");
        }
        if (!StringUtils.equals(info.getSecret(), secret)) {
            throw new BusinessException("无效密码");
        }
        TokenInfo tokenInfo = tokenMap.get(account);
        if (tokenInfo != null && tokenInfo.getToken() != null) {
            return tokenInfo.getToken();
        }
        tokenInfo = new TokenInfo();
        String uuid = UUID.randomUUID().toString();
        tokenInfo.setToken(uuid);
        tokenInfo.setCreateDate(LocalDateTime.now());
        tokenInfo.setExpireDate(LocalDateTime.now().plusHours(2));
        tokenMap.put(account,tokenInfo);
        return tokenInfo.getToken();
    }

    public boolean checkCaptcha(String captcha) {
        return tokenMap.values().stream().anyMatch(e->StringUtils.equals(e.getToken(),captcha));
    }
}
ログイン後にコピー
@Data
public class TokenInfo {
    private LocalDateTime createDate;
    private LocalDateTime expireDate;
    private String token;

    public String getToken() {
        if (LocalDateTime.now().isBefore(expireDate)) {
            return token;
        }
        return null;
    }

    public boolean verification(String token) {
        return Objects.equals(this.token, token);
    }
}
ログイン後にコピー

4. AOP を記述します

最初に、認証が必要ないことを示すアノテーションを記述します

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CaptchaIgnoreAop {
}
ログイン後にコピー
@Slf4j
@Aspect
@Component
@Order(2)
public class CaptchaAop {

    @Value("${spring.profiles.active:dev}")
    private String env;

    @Autowired
    private SecretConfig config;

    @Pointcut("execution(public * com.herenit.phsswitch.controller.impl..*.*(..))" +
            "&&@annotation(org.springframework.web.bind.annotation.PostMapping)" +
            "&&!@annotation(com.herenit.phsswitch.aop.CaptchaIgnoreAop)")
    public void tokenAop() {
    }

    @Around("tokenAop()")
    public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        if (args.length == 0 || !(args[0] instanceof RequestWrapper)
                || "test,dev".contains(env)) {
            log.info("当前环境无需校验token");
            return joinPoint.proceed();
        }
        String captcha = ((RequestWrapper) joinPoint.getArgs()[0]).getCaptcha();
        if (!config.checkCaptcha(captcha)) {
            throw new BusinessException("captcha无效");
        }
        return joinPoint.proceed();
    }

}
ログイン後にコピー
5. インターフェイス test

@PostMapping("/login")
@CaptchaIgnoreAop
public ResponseWrapper login(@RequestBody JSONObject userInfo) {
    String token = config.getToken(userInfo.getString("loginName")
            , userInfo.getString("password"));
    JSONObject result = new JSONObject();
    result.put("platformAccessToken", token);
    return ResponseWrapper.success(result);
}
ログイン後にコピー

を作成します。このインターフェイスを使用してメモリ内にトークンを作成し、それをフロントエンドに返します。後で、他のインターフェイスを調整するときに、認証のためにこのトークンを渡すことができます。渡される場所はキャプチャフィールドです
public class RequestWrapper<T> implements Serializable {

    private static final long serialVersionUID = 8988706670118918321L;
    public RequestWrapper() {
        super();
    }

    private T args;

    private String captcha;

    private String funcode;

    public T getArgs() {
        return args;
    }

    public void setArgs(T args) {
        this.args = args;
    }

    public String getCaptcha() {
        return captcha;
    }

    public void setCaptcha(String captcha) {
        this.captcha = captcha;
    }

    public String getFuncode() {
        return funcode;
    }

    public void setFuncode(String funcode) {
        this.funcode = funcode;
    }
}
ログイン後にコピー

以上がSpring AOP を使用して SpringBoot にインターフェイス認証を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート