您好,登錄后才能下訂單哦!
這篇“怎么在SpringBoot中使用Spring AOP實現接口鑒權”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“怎么在SpringBoot中使用Spring AOP實現接口鑒權”文章吧。
面向切面編程,可以將與業務無關但是需要被各個業務模塊共同調用的邏輯抽取出來,以切面的方式切入到代碼中,從而降低系統中代碼的耦合度,減少重復的代碼。
Spring AOP是通過預編譯方式和運行期間動態代理實現程序面向切面編程
AOP底層使用動態代理完成需求,為需要增加增強功能的類來生成代理類,有兩種生成代理類的方式,對于被代理類(即需要增強的類),如果:
實現了接口,使用JDK動態代理,生成的代理類會使用其接口沒有實現接口,
使用CGlib動態代理,生成的代理類會集成被代理類
連接點:被代理(被增強)的類中的方法
切入點:實際上需要被增強的方法
通知:要增強的邏輯代碼
前置通知:在主體功能執行之前執行
后置通知:在主題功能執行之后執行
環繞通知:在主體功能執行前后執行
異常通知:在主題功能執行出現異常時執行
最終通知:主體功能無論執行是否成功都會執行
切面:切入點和切面的結合,即被增強的方法和增強的功能組成切面
注解:
@Aspect: 聲明某個類是切面,編寫通知、切入點
@Before: 對應前置通知
@AfterReturning: 對應后置通知
@Around: 對應環繞通知
@AfterThrowing: 對應異常通知
@After: 對應最終通知
@Pointcut: 聲明切入點,標注在一個方法上可以讓表達式更簡潔
使用切入點表達式聲明切入點
execution([權限修飾符][返回類型][類完全路徑].[方法名稱][參數列表類型])
execution(* com.xxx.ABC.add()),對ABC類的方法進行增強
配置接口鑒權賬密
account: infos: - account: xinchao secret: admin
@Data public class SecretInfo { private String account; private String secret; }
@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); } }
首先,編寫一個注解來標識不需要鑒權
@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(); } }
@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); }
通過這個接口,我們可以在內存中生成一個token,同時也會返回給前端。之后我們在調其他接口時傳入這個token進行鑒權即可。傳入的位置是captcha字段
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; } }
以上就是關于“怎么在SpringBoot中使用Spring AOP實現接口鑒權”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。