您好,登錄后才能下訂單哦!
本篇內容介紹了“Spring Cloud OAuth2中/oauth/token返回的內容格式是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
背景
實現原理
代碼實現
相關類
關鍵切面攔截器
在前后端分離的項目中,一般后端返回給前端的格式是一個固定的json格式。在這個前提下,Spring Cloud OAuth3 生成access token的請求/oauth/token的返回內容就需要自定義。
訪問/oauth/token示例如下:
原始返回值的格式如下:
我們希望使用我們自己固定的json格式,如下:
原理就是通過切面編程實現對/oauth/token端點請求的結果進行攔截封裝處理,由于/oauth/token是Spring Cloud OAuth3的內部端點,因此需要對相關的Spring源碼進行分析。最終定位到
org.springframework.security.oauth3.provider.endpoint.TokenEndpoint.postAccessToken()
方法上。
CodeEnum.java
package com.wongoing.common.model; /** * @description: 代碼枚舉 * @author: zheng * @date: Created in 2021/1/26 11:18 * @version: 0.0.1 * @modified By: */ public enum CodeEnum { SUCCESS(0), ERROR(1); private Integer code; CodeEnum(Integer code) { this.code = code; } public Integer getCode() { return this.code; } }
Result.java
package com.wongoing.common.model; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; /** * @description: Rest API 接口方法返回類型定義 * @author: zheng * @date: Created in 2021/1/26 13:25 * @version: 0.0.1 * @modified By: */ @Data @NoArgsConstructor @AllArgsConstructor public class Result<T> implements Serializable { private T data; private Integer code; private String msg; public static <T> Result<T> of(T data, Integer code, String msg) { return new Result<>(data, code, msg); } public static <T> Result<T> succeed(String msg) { return of(null, CodeEnum.SUCCESS.getCode(), msg); } public static <T> Result<T> succeed(T model, String msg) { return of(model, CodeEnum.SUCCESS.getCode(), msg); } public static <T> Result<T> succeed(T model) { return of(model, CodeEnum.SUCCESS.getCode(), ""); } public static <T> Result<T> failed(String msg) { return of(null, CodeEnum.ERROR.getCode(), msg); } public static <T> Result<T> failed(T model, String msg) { return of(model, CodeEnum.ERROR.getCode(), msg); } }
在uaa項目中定義OauthTokenAspect.java
package com.wongoing.oauth3.filter; import com.wongoing.common.constant.SecurityConstants; import com.wongoing.common.context.TenantContextHolder; import com.wongoing.common.model.Result; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.oauth3.common.OAuth3AccessToken; import org.springframework.security.oauth3.common.util.OAuth3Utils; import org.springframework.security.oauth3.provider.OAuth3Authentication; import org.springframework.stereotype.Component; import java.security.Principal; import java.util.Map; /** * @description: oauth-token攔截器 * 1. 賦值租戶 * 2. 統一返回token格式 * * @author: zheng * @date: Created in 2021/7/12 16:25 * @version: 0.0.1 * @modified By: */ @Slf4j @Component @Aspect public class OauthTokenAspect { @Around("execution(* org.springframework.security.oauth3.provider.endpoint.TokenEndpoint.postAccessToken(..))") public Object handleControllerMethod(ProceedingJoinPoint joinPoint) throws Throwable { try { Object[] args = joinPoint.getArgs(); Principal principal = (Principal) args[0]; if (!(principal instanceof Authentication)) { throw new InsufficientAuthenticationException("There is no client authentication. Try adding an appropriate authentication filter."); } String clientId = this.getClientId(principal); Map<String, String> parameters = (Map<String, String>) args[1]; String grantType = parameters.get(OAuth3Utils.GRANT_TYPE); //保存租戶id TenantContextHolder.setTenant(clientId); Object proceed = joinPoint.proceed(); if (SecurityConstants.AUTHORIZATION_CODE.equals(grantType)) { /** * 如果使用 @EnableOAuth3Sso 注解不能修改返回格式,否則授權碼模式可以統一改 * 因為本項目的 sso-demo/ss-sso 里面使用了 @EnableOAuth3Sso 注解,所以這里就不修改授權碼模式的token返回值了 */ return proceed; } else { ResponseEntity<OAuth3AccessToken> responseEntity = (ResponseEntity<OAuth3AccessToken>) proceed; OAuth3AccessToken body = responseEntity.getBody(); return ResponseEntity .status(HttpStatus.OK) .body(Result.succeed(body)); } } finally { TenantContextHolder.clear(); } } private String getClientId(Principal principal) { Authentication client = (Authentication) principal; if (!client.isAuthenticated()) { throw new InsufficientAuthenticationException("The client is not authenticated."); } String clientId = client.getName(); if (client instanceof OAuth3Authentication) { clientId = ((OAuth3Authentication) client).getOAuth3Request().getClientId(); } return clientId; } }
其中的常量值:
public abstract class OAuth3Utils { public static final String GRANT_TYPE = "grant_type"; }
public interface SecurityConstants { /** * 授權碼模式 */ String AUTHORIZATION_CODE = "authorization_code"; }
“Spring Cloud OAuth2中/oauth/token返回的內容格式是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。