中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring Cloud OAuth2中/oauth/token返回的內容格式是什么

發布時間:2021-07-30 18:18:43 來源:億速云 閱讀:185 作者:chen 欄目:開發技術

本篇內容介紹了“Spring Cloud OAuth2中/oauth/token返回的內容格式是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

目錄
  • 背景

  • 實現原理

  • 代碼實現

    • 相關類

    • 關鍵切面攔截器

背景

在前后端分離的項目中,一般后端返回給前端的格式是一個固定的json格式。在這個前提下,Spring Cloud OAuth3 生成access token的請求/oauth/token的返回內容就需要自定義。

訪問/oauth/token示例如下:

Spring Cloud OAuth2中/oauth/token返回的內容格式是什么

原始返回值的格式如下:

Spring Cloud OAuth2中/oauth/token返回的內容格式是什么

我們希望使用我們自己固定的json格式,如下:

Spring Cloud OAuth2中/oauth/token返回的內容格式是什么

實現原理

原理就是通過切面編程實現對/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返回的內容格式是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

手游| 曲靖市| 托里县| 施甸县| 巩留县| 阜平县| 佛山市| 拜泉县| 曲靖市| 收藏| 潞西市| 新干县| 资源县| 个旧市| 舞阳县| 武宁县| 海阳市| 安化县| 育儿| 青铜峡市| 环江| 黑河市| 石楼县| 长岭县| 双牌县| 启东市| 吉林省| 镶黄旗| 铜川市| 西峡县| 北票市| 延长县| 池州市| 前郭尔| 衡阳县| 密山市| 平武县| 尚志市| 凌云县| 平顺县| 石首市|