keycloak授权流程详解


这里需要注意 client一般默认一种加密方式(RS256) 我是修改源码之后才能使用PS256

package org.keycloak.keys.loader;

import org.jboss.logging.Logger;
import org.keycloak.authentication.authenticators.client.JWTClientAuthenticator;
import org.keycloak.common.util.KeyUtils;
import org.keycloak.crypto.Algorithm;
import org.keycloak.crypto.KeyType;
import org.keycloak.crypto.KeyUse;
import org.keycloak.crypto.KeyWrapper;
import org.keycloak.jose.jwk.JSONWebKeySet;
import org.keycloak.jose.jwk.JWK;
import org.keycloak.keys.PublicKeyLoader;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelException;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
import org.keycloak.protocol.oidc.utils.JWKSHttpUtils;
import org.keycloak.representations.idm.CertificateRepresentation;
import org.keycloak.services.util.CertificateInfoHelper;
import org.keycloak.services.util.ResolveRelative;
import org.keycloak.util.JWKSUtils;
import org.keycloak.util.JsonSerialization;

import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Map;

/**
 * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
 */
public class ClientPublicKeyLoader implements PublicKeyLoader {

    private static final Logger logger = Logger.getLogger(ClientPublicKeyLoader.class);

    private final KeycloakSession session;
    private final ClientModel client;
    private final JWK.Use keyUse;

    public ClientPublicKeyLoader(KeycloakSession session, ClientModel client) {
        this.session = session;
        this.client = client;
        this.keyUse = JWK.Use.SIG;
    }

    public ClientPublicKeyLoader(KeycloakSession session, ClientModel client, JWK.Use keyUse) {
        this.session = session;
        this.client = client;
        this.keyUse = keyUse;
    }

    @Override
    public Map<String, KeyWrapper> loadKeys() throws Exception {
        OIDCAdvancedConfigWrapper config = OIDCAdvancedConfigWrapper.fromClientModel(client);
        try {
            logger.debugv( "oidc advancedConfig is {0}", JsonSerialization.writeValueAsPrettyString( config ) );
        } catch (Exception cause) {

        }

        if (config.isUseJwksUrl()) {
            String jwksUrl = config.getJwksUrl();
            jwksUrl = ResolveRelative.resolveRelativeUri(session.getContext().getUri().getRequestUri(), client.getRootUrl(), jwksUrl);
            JSONWebKeySet jwks = JWKSHttpUtils.sendJwksRequest(session, jwksUrl);
            return JWKSUtils.getKeyWrappersForUse(jwks, keyUse);
        } else if (keyUse == JWK.Use.SIG) {
            try {
                CertificateRepresentation certInfo = CertificateInfoHelper.getCertificateFromClient(client, JWTClientAuthenticator.ATTR_PREFIX);
                KeyWrapper publicKey = getSignatureValidationKey(certInfo);
                return Collections.singletonMap(publicKey.getKid(), publicKey);
            } catch (ModelException me) {
                logger.warnf(me, "Unable to retrieve publicKey for verify signature of client '%s' . Error details: %s", client.getClientId(), me.getMessage());
                return Collections.emptyMap();
            }
        } else {
            logger.warnf("Unable to retrieve publicKey of client '%s' for the specified purpose other than verifying signature", client.getClientId());
            return Collections.emptyMap();
        }
    }

    private static KeyWrapper getSignatureValidationKey(CertificateRepresentation certInfo) throws ModelException {
        KeyWrapper keyWrapper = new KeyWrapper();
        String encodedCertificate = certInfo.getCertificate();
        String encodedPublicKey = certInfo.getPublicKey();

        if (encodedCertificate == null && encodedPublicKey == null) {
            throw new ModelException("Client doesn't have certificate or publicKey configured");
        }

        if (encodedCertificate != null && encodedPublicKey != null) {
            throw new ModelException("Client has both publicKey and certificate configured");
        }

        //here ...................
//        keyWrapper.setAlgorithm(Algorithm.RS256);
//注意这里
        keyWrapper.setAlgorithm(Algorithm.PS256);
        keyWrapper.setType(KeyType.RSA);
        keyWrapper.setUse(KeyUse.SIG);
        String kid = null;
        if (encodedCertificate != null) {
            X509Certificate clientCert = KeycloakModelUtils.getCertificate(encodedCertificate);
            // Check if we have kid in DB, generate otherwise
            kid = certInfo.getKid() != null ? certInfo.getKid() : KeyUtils.createKeyId(clientCert.getPublicKey());
            keyWrapper.setKid(kid);
            keyWrapper.setPublicKey(clientCert.getPublicKey());
            keyWrapper.setCertificate(clientCert);
            logger.debug("getSignatureValidationKey * * * get the kid"+kid+"keyWrapper"+keyWrapper.toString());
        } else {
            logger.debugf( "encodedPublicKey is %s", encodedPublicKey );
            PublicKey publicKey = KeycloakModelUtils.getPublicKey(encodedPublicKey);
            logger.debugv( "public key algo", publicKey.getAlgorithm() );
            // Check if we have kid in DB, generate otherwise
            kid = certInfo.getKid() != null ? certInfo.getKid() : KeyUtils.createKeyId(publicKey);
            keyWrapper.setKid(kid);
            //注意这里
            keyWrapper.setAlgorithm( Algorithm.PS256 );
            keyWrapper.setPublicKey(publicKey);
        }
        return keyWrapper;
    }


}

client配置

在这里插入图片描述
在这里插入图片描述

公钥私钥生成

        RSAKey privateKey = new RSAKeyGenerator(2048)
                .algorithm(JWSAlgorithm.PS256)
                .keyUse(KeyUse.SIGNATURE)
                .keyID("client-PS256")
                .generate();
        RSAKey publicKey = privateKey.toPublicJWK();

私钥

{
    "keys": [
        {
            "p": "77_7i2uGN6RxaCU6m217guw2gdLeknEbi34IeJpvK5xqufrs00aMCqnCXwWAEsqCm3CmITdhTPNZSemETcsouW82NiHQ_cbI7agNpAaTU6kRdzaOVyJSJgs-pmxgFMbgkBmIHZbbtdrpIykTHlhmilPnRhQvwN3N_7eymmbXPe0", 
            "kty": "RSA", 
            "q": "nbVbCk7BMP1syPPR0IUbDwYmLkFnUL6TXgXA4o-3IIdP-bFJKc2ONTxtsLl-Q-H2dDKugjHe-AyVvVRmiMUna2VVEUbG3I6z0mvok19fC9Gd7kCalJuXfNBnJVyoJfCfOmDn3RepYUP7mWUAmlbtMxbud0-F90T60vIgewPN7e0", 
            "d": "COuCJEsUHUcg39kF9S9cTt8GsaxIEP-vqI9GonGz_nC3uBFDRhyqGKj-JWWoG3Vso3i658bnJdMf1aW4KjxJon-D0nfAAZXPUj7OfJZ__D874BKRSg9NqE7uubsU3ByPvLVexqsGAy4tRCM14zwXpNM_YAe0z7c4tmSrDmUdFZUpt8YhL33jPi5KDaxtEdMrbL2OKIdrolJjJnX7loVJcSneM7bXvx-6ieDfO8HgMlmnpik3t_9HVeJ1-o30ndv5KsVG1i7NtTDgAGTqbInHD7WdRLIzgTbXTmoAWY4ccHeDNzh6S_9jKk_sQE9A1oLFUmL-7qtk8qnl9ZBDoxGIYQ", 
            "e": "AQAB", 
            "use": "sig", 
            "kid": "client-PS256", 
            "qi": "AiADA77A6JGn1iOEd2CM0c17LK6AzpGkVUzMfI_yoIzwpaJh41zd77nO_xe49e0FQNEEIjh__C4svctz7RA_90pteFDQ8TBoSmm8j6Jb-BdaDVIt_Ax77RRAiPD5ZSSqj-XzkjIUCNjghWjDz6H_k1FbcBA-lTBaia1tvioWh7A", 
            "dp": "vue3TBAlgr8Nkqk6XrMyC1E-IeggVKl-DnggFLCcXzShA1CcLavaLU95t6IwlkXs9AsiLgbkEpsfeSxZrnxcBDRbDYWl3b3hFuSfYAHgZFiW0L9_XkC0-xgvHePkKgcmn3fFHBKZBti2lcnKMHqhw_oFiZbfY4r60mma7TmAoQ0", 
            "alg": "PS256", 
            "dq": "O75nNblt8Fwg6OOM2VyDSqa-sgku1WTMuPKfBnUBH76C6olhuQdY1wwEVc1_asHgNla4yzOPTxKdazLdAPUHIOUrW7cfQJCCyLT-T03y2KxZEtfAd4mV0r-0Q3Addvn3qArr61K6ZNF3L74Wg2FozFDkl6g1jN3B00XMTi27xmU", 
            "n": "k7KVREAwJPKOfJC9Q71ZA3MZyZpv2S0wRDtz4wurqu2kNNd33-pIAkUABnSFDWxHdrXF0lL6fBJ558f5ybLk4rXE4dT0UJQLYxjBONoilkOIbZhXvtd-GWRy6bzmuRMBgUzvULTjCXSUpyllche6uStZFMRrlrRaZYGU1K0MNGmC6VzbKyYU8SJg9T9OupdtVSA0zmRtMeI7tk8-vQceonStkNrBklJ_pbqtFh-UpqRlZABJ-UqTNRY3Cm2x8X_QaEzGA-3eeRk4uNLTPVdgOOKven0lZdePRtdCowfXRxVwGrFGINonZn--gqlVc6rqo2KRIJgSTWXndIsb12G9aQ"
        }
    ]
}

公钥

{
    "keys": [
        {
            "kty": "RSA", 
            "e": "AQAB", 
            "use": "sig", 
            "kid": "client-PS256", 
            "alg": "PS256", 
            "n": "k7KVREAwJPKOfJC9Q71ZA3MZyZpv2S0wRDtz4wurqu2kNNd33-pIAkUABnSFDWxHdrXF0lL6fBJ558f5ybLk4rXE4dT0UJQLYxjBONoilkOIbZhXvtd-GWRy6bzmuRMBgUzvULTjCXSUpyllche6uStZFMRrlrRaZYGU1K0MNGmC6VzbKyYU8SJg9T9OupdtVSA0zmRtMeI7tk8-vQceonStkNrBklJ_pbqtFh-UpqRlZABJ-UqTNRY3Cm2x8X_QaEzGA-3eeRk4uNLTPVdgOOKven0lZdePRtdCowfXRxVwGrFGINonZn--gqlVc6rqo2KRIJgSTWXndIsb12G9aQ"
        }
    ]
}

request加密

claims

{
    "aud": "http://localhost:8080/auth/realms/openbanking", 
    "claims": {
        "id_token": {
            "openbanking_intent_id": {
                "essential": true, 
                "value": "64a7d936-c063-45a9-bc81-40e851bc5d30"
            }
        }
    }, 
    "client_id": "client-PS256", 
    "exp": 1581680397, 
    "iss": "client-PS256", 
    "nonce": "SqoQKopVco", 
    "redirect_uri": "http://localhost:8080/v3/hello", 
    "response_type": "code id_token", 
    "scope": "openid accounts", 
    "state": "0nidnhEdvX"
}

header

{
    "kid": "client-PS256", 
    "typ": "JWT", 
    "alg": "PS256"
}

加密代码

public static void main(String[] args) throws Exception {
        Provider bc = BouncyCastleProviderSingleton.getInstance();
        Security.addProvider(bc);
        String pdpAddress = "http://localhost:8080";
        String realmName = "openbanking";
        String clientId = "client-PS256";
        String redirectClientId = "client-PS256";
        String clienSecret = "9563616a-31d2-45ce-94a2-c0109963a134";
        String client_alg = "PS256";
        String kid = "client-PS256";
        String openbankingIntentIdValue = "64a7d936-c063-45a9-bc81-40e851bc5d30";
        String state = "0nidnhEdvX";
        String nonce = "SqoQKopVco";
        String uri = "http://localhost:8080/v3/hello";
        OpenbankingIntentId openbankingIntentId = new OpenbankingIntentId();
        openbankingIntentId.setValue(openbankingIntentIdValue);
        openbankingIntentId.setEssential(true);
        IdToken idToken = new IdToken();
        idToken.setOpenbanking_intent_id(openbankingIntentId);
        ClaimsModel claimsModel = new ClaimsModel();
        claimsModel.setId_token(idToken);
        Claims claims = new Claims();
        StringBuffer bufferAud = new StringBuffer();
        bufferAud.append(pdpAddress);
        bufferAud.append("/auth/realms/");
        bufferAud.append(realmName);
        String aud = bufferAud.toString();
        claims.setAud(aud);
        claims.setScope("openid accounts");
        claims.setClaims(claimsModel);
        claims.setIss(clientId);
        claims.setResponse_type("code id_token");
        claims.setRedirect_uri(uri);
        claims.setState(state);
        claims.setNonce(nonce);
        claims.setExp(new Long(new Date(new Date().getTime() + 5 * 60 * 1000).getTime()).intValue());
        claims.setClient_id(clientId);

        JSONObject json = JSONObject.fromObject(claims);
        String requestObjectClaims = json.toString();
        BufferedReader reader = new BufferedReader(new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("ps256jwt.json"), "UTF-8"));
        StringBuilder sb = new StringBuilder();
        String s; // 依次循环,至到读的值为空
        while ((s = reader.readLine()) != null) {
            sb.append(s);
        }
        reader.close();
        String jwks = sb.toString();
        JWTClaimsSet claimSet = JWTClaimsSet.parse(requestObjectClaims);
        JWKSet jwkSet = JWKSet.parse(jwks);
        if (jwkSet.getKeys().size() == 1) {
            // figure out which algorithm to use
            JWK jwk = jwkSet.getKeys().iterator().next();
            JWSSigner signer = null;
            if (jwk.getKeyType().equals(KeyType.RSA)) {
                signer = new RSASSASigner((RSAKey) jwk);
            } else if (jwk.getKeyType().equals(KeyType.EC)) {
                signer = new ECDSASigner((ECKey) jwk);
            } else if (jwk.getKeyType().equals(KeyType.OCT)) {
                signer = new MACSigner((OctetSequenceKey) jwk);
            }
            JWSHeader header = new JWSHeader(JWSAlgorithm.parse(client_alg), JOSEObjectType.JWT, null, null, null, null, null, null, null, null, kid, null, null);
            SignedJWT requestObject = new SignedJWT(header, claimSet);
            requestObject.sign(signer);
//            logger.debug("**********claims" + claimSet.toString());
//            logger.debug("**********header" + header.toString());
//            logger.debug("**********requestObject" + requestObject.serialize());
//            logger.debug("**********key" + jwk.toJSONString());
            StringBuffer buffer = new StringBuffer();
            buffer.append(pdpAddress);
            buffer.append("/auth/realms/");
            buffer.append(realmName);
            buffer.append("/protocol/openid-connect/auth?request=");
            buffer.append(requestObject.serialize());
            buffer.append("&client_id=");
            buffer.append(redirectClientId);
            buffer.append("&redirect_uri=");
            buffer.append(uri);
            buffer.append("&scope=openid%20accounts&response_type=code%20id_token");
            String path = buffer.toString();
//            logger.debug("**********path" + path);
//            resultMap.put("path", path);
            System.out.println("path*****" + path);
        }

    }

生成授权跳转页面地址

http://localhost:8080/auth/realms/openbanking/protocol/openid-connect/auth?request=eyJraWQiOiJjbGllbnQtUFMyNTYiLCJ0eXAiOiJKV1QiLCJhbGciOiJQUzI1NiJ9.eyJhdWQiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODA4MFwvYXV0aFwvcmVhbG1zXC9vcGVuYmFua2luZyIsInNjb3BlIjoib3BlbmlkIGFjY291bnRzIiwiY2xhaW1zIjp7ImlkX3Rva2VuIjp7Im9wZW5iYW5raW5nX2ludGVudF9pZCI6eyJ2YWx1ZSI6IjY0YTdkOTM2LWMwNjMtNDVhOS1iYzgxLTQwZTg1MWJjNWQzMCIsImVzc2VudGlhbCI6dHJ1ZX19fSwiaXNzIjoiY2xpZW50LVBTMjU2IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUgaWRfdG9rZW4iLCJyZWRpcmVjdF91cmkiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODA4MFwvdjNcL2hlbGxvIiwic3RhdGUiOiIwbmlkbmhFZHZYIiwiZXhwIjoxNTgxOTIxMTk4LCJub25jZSI6IlNxb1FLb3BWY28iLCJjbGllbnRfaWQiOiJjbGllbnQtUFMyNTYifQ.TqSYiATjGMk_aHxMliYP5jzANnnCOlAjF8H5fG99g9AEPa3asWhAJJVleXoekf5T56PRYWBEqjcTqJDrTYmthTEoSIAgGd7zalztt1TuWa-0FND43VzdsC2CEsh9B7BbNraROVMY1AKBzrPeTeEdgasH-RBVj-f9dQkIhFrJWplmXEZSZ0ZyvvcelWZqklfeSWH_3OCVlmUkf5TxJLtoXpHYlWZOTe_exm-jeKK_jWzuNsBvcAAVnfDG15EgZH6M8buecXtlatnOzM-SKWxPzfxlfg4HX8e8IPkANDoemCpQCZfPvblzHfBOdl0fk5mY9LQpaz-iHgDDCEtlkAIpFA&client_id=client-PS256&redirect_uri=http://localhost:8080/v3/hello&scope=openid%20accounts&response_type=code%20id_token

授权跳转返回 code

在这里插入图片描述

{
 http://localhost:8080/auth/realms/openbanking/login-actions/authenticate?session_code=2iFMm2p6Hk3ynNwaQqDF6MRnoAuMiUn8ltUltgXfCCA&execution=b5a519cd-ce00-48fe-a890-72e4bf7fd5a1&client_id=client-RS256&tab_id=r2S0SP5L16Q
}
http://localhost:8888/v3/hello#state=0nidnhEdvX&session_state=89e57637-5e0d-4f26-b9b2-05b64bdd183a&code=f0b38a8a-1273-4b34-8f21-bbe2e1edbcfd.89e57637-5e0d-4f26-b9b2-05b64bdd183a.840ce672-051a-4630-a4bd-9eff8573ce4d
&id_token=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJpdmhsSndKdm8xWlNzX1BuTTE0Q1ZFSG5fTUJ3cE5UMkQwSTlFQkFkZEw4In0.eyJqdGkiOiI4NDJjYmNlZS03MGM5LTQ0MzgtOGJhNi1kODhkMzliYmM3YTAiLCJleHAiOjE1OTA3MjIyNTIsIm5iZiI6MCwiaWF0IjoxNTkwNzIxOTUyLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvb3BlbmJhbmtpbmciLCJhdWQiOiJjbGllbnQtUlMyNTYiLCJzdWIiOiJmMTUzYmIwZS0wMDczLTQ1ZWMtODU5NC1mMzJjODQ4ZjhmYWIiLCJ0eXAiOiJJRCIsImF6cCI6ImNsaWVudC1SUzI1NiIsIm5vbmNlIjoiU3FvUUtvcFZjbyIsImF1dGhfdGltZSI6MTU5MDcyMTk1Miwic2Vzc2lvbl9zdGF0ZSI6Ijg5ZTU3NjM3LTVlMGQtNGYyNi1iOWIyLTA1YjY0YmRkMTgzYSIsImNfaGFzaCI6IlVmMHNkakVLRHhxSV9EeW4ydmV4RUEiLCJhY3IiOiIxIiwic19oYXNoIjoiZm9GbUZmUWZyTXhLWVpOTnc5SGRRQSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoib3BlbmJhbmtpbmcifQ.RyG8eCt4gCdbC1yTyi69Xl4y3397IWlCkjG0J2LdoSMaLjpi9RBMc9louH1moqfOZewJMhuF27E4DXFFbcT9fiXHLFIfRhWHDRJP5CPKVIyjBMrmF2GiPCsNyCX1cAuINc5WujTKL49xGe1FmhYdkxDxJgnVAqQXab89VXQbRk1sctc2nYGaw6q2I9pOQtivbpYrZfl2Ttegvvq4P3I2L_e3v5XskS4VMxtjAwFWngnHjOXYDLPPLmNY-mwmn-Bvl35BiP2yaq9WQKb0TiUOTnDlX_84HmxFtv6yeE65qUIIr7xcBVvF1P6JmAj2eeC4wNnkc0lN0N8Qm1MTlAOyuQ

authorization_code 获取token (只能使用一次)

client必须切换为
在这里插入图片描述

curl --location --request POST 'http://localhost:8080/auth/realms/openbanking/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=f0b38a8a-1273-4b34-8f21-bbe2e1edbcfd.89e57637-5e0d-4f26-b9b2-05b64bdd183a.840ce672-051a-4630-a4bd-9eff8573ce4d' \
--data-urlencode 'redirect_uri=http://localhost:8888/v3/hello' \
--data-urlencode 'client_id=client-RS256' \
--data-urlencode 'client_secret=cd949e24-1c96-4ea4-9cb8-03f61aa6c601'

获取到的token id_token中携带的是授权信息

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJpdmhsSndKdm8xWlNzX1BuTTE0Q1ZFSG5fTUJ3cE5UMkQwSTlFQkFkZEw4In0.eyJqdGkiOiIxMmNhZDI0Yy1kMGUzLTQ3YzctOGQwNy0wMGU4ODAyOTg4NWUiLCJleHAiOjE1OTA3MjI3MTUsIm5iZiI6MCwiaWF0IjoxNTkwNzIyNDE1LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvb3BlbmJhbmtpbmciLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiZjE1M2JiMGUtMDA3My00NWVjLTg1OTQtZjMyYzg0OGY4ZmFiIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiY2xpZW50LVJTMjU2Iiwibm9uY2UiOiJTcW9RS29wVmNvMSIsImF1dGhfdGltZSI6MTU5MDcyMjM5Mywic2Vzc2lvbl9zdGF0ZSI6IjNjZTkzOTVhLWI3YjQtNGQ2Ni05NjRlLTQ4MzcxMzhmNTFiOCIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo4ODg4Il0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoib3BlbmJhbmtpbmcifQ.IafBnpwO0nj6JfLx6QnE-bmMYIlhiSrdY7cVPkh1vk6QQbs1XnBVW8ItBmsNdBjZblycPEUQF9C7Ud3GHwOQroKJn99t-Ytsskvy7crQUBeo0GTpVtpvsM2MLvGgKRWUVH31VVL24z-M5POaBAkNiAsGqcgViQCBApIPUP5qFGoNxbyNZAftEiIX_gvygjqN91Telh5aUflsN8FYssKnbKUnNr4TGFs1avTIDYvXToNJDra99GjydgsLkoRU7kp0pjYX8H-VAxXc9jnqkJphfSzdFsYIkVjmxHhKAAD_3IXKM-83yipR5eq_2uSJq_w4ibExp-N0CyqC71pvt0pSEA",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI2YmNkZmNkNy1kOTQ2LTRkNzUtYWQxMi1mZjE0ZGYxZTM4MGMifQ.eyJqdGkiOiI5NDUxOTFhOS0zYWEzLTRlYWQtYTcyYi03YWJhZWMxN2M3NWQiLCJleHAiOjE1OTA3MjQyMTUsIm5iZiI6MCwiaWF0IjoxNTkwNzIyNDE1LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvb3BlbmJhbmtpbmciLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvb3BlbmJhbmtpbmciLCJzdWIiOiJmMTUzYmIwZS0wMDczLTQ1ZWMtODU5NC1mMzJjODQ4ZjhmYWIiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoiY2xpZW50LVJTMjU2Iiwibm9uY2UiOiJTcW9RS29wVmNvMSIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6IjNjZTkzOTVhLWI3YjQtNGQ2Ni05NjRlLTQ4MzcxMzhmNTFiOCIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCJ9.sZFYkOf-KgHlaCbOAOofiIr_Dq5xcqLHgdPGmr9za-8",
    "token_type": "bearer",
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJpdmhsSndKdm8xWlNzX1BuTTE0Q1ZFSG5fTUJ3cE5UMkQwSTlFQkFkZEw4In0.eyJqdGkiOiJjNjZmMDE3Zi05OGU5LTQ5ZjMtOWJkNi1lNGY5OGRhOTE0MjEiLCJleHAiOjE1OTA3MjI3MTUsIm5iZiI6MCwiaWF0IjoxNTkwNzIyNDE1LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvb3BlbmJhbmtpbmciLCJhdWQiOiJjbGllbnQtUlMyNTYiLCJzdWIiOiJmMTUzYmIwZS0wMDczLTQ1ZWMtODU5NC1mMzJjODQ4ZjhmYWIiLCJ0eXAiOiJJRCIsImF6cCI6ImNsaWVudC1SUzI1NiIsIm5vbmNlIjoiU3FvUUtvcFZjbzEiLCJhdXRoX3RpbWUiOjE1OTA3MjIzOTMsInNlc3Npb25fc3RhdGUiOiIzY2U5Mzk1YS1iN2I0LTRkNjYtOTY0ZS00ODM3MTM4ZjUxYjgiLCJhY3IiOiIxIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJvcGVuYmFua2luZyJ9.c6n_QfMIlTCoZLoWwxaIrlt4L7qBmS5x91bcU31okW2xMgQsDNP_GBLUEjtIthP8hwtXnOh1UZKxrKxrVae0nxdLFxrZ9-t6FHXBseNRK8-JwWxijdvzSBj6UrAnHeUxDPdWsYF6gLn3_KOCJq0bGkXTPzJ6p0n6gZP-3070vvkrkWmjcTCh3wCrcpEIpI8o5z8QlqHLTbFEg78lkLZKhY8oEQZbIkMKJM3Xkz4lrvRGu3tZIAU3RfyyAwsRXwojwiugeS7GLHrNdoalUiR9oyor3NQ3fUfAASp-opracFKijzjbWxng3xNgkwa9biCBmAMgtiTNFLEOKPKbp9oSVA",
    "not-before-policy": 1590722346,
    "session_state": "3ce9395a-b7b4-4d66-964e-4837138f51b8",
    "scope": "openid profile email"
}

token解析

curl --location --request POST 'http://localhost:8080/auth/realms/openbanking/protocol/openid-connect/token/introspect' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=client-RS256' \
--data-urlencode 'client_secret=cd949e24-1c96-4ea4-9cb8-03f61aa6c601' \
--data-urlencode 'token=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJpdmhsSndKdm8xWlNzX1BuTTE0Q1ZFSG5fTUJ3cE5UMkQwSTlFQkFkZEw4In0.eyJqdGkiOiI1MTdjNjQ4MS00ODNkLTRiM2EtODcxYy1jMWNkODQ0M2JkZDkiLCJleHAiOjE1OTA3MjM1NTUsIm5iZiI6MCwiaWF0IjoxNTkwNzIzMjU1LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvb3BlbmJhbmtpbmciLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiZjE1M2JiMGUtMDA3My00NWVjLTg1OTQtZjMyYzg0OGY4ZmFiIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiY2xpZW50LVJTMjU2Iiwibm9uY2UiOiJTcW9RS29wVmNvMyIsImF1dGhfdGltZSI6MTU5MDcyMzIyNSwic2Vzc2lvbl9zdGF0ZSI6IjliODg4MDJiLWUxN2YtNDRiNC04NDdkLTU3ZDExOTQ0ZGU2OSIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo4ODg4Il0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoib3BlbmJhbmtpbmcifQ.b8P3gH46pH4fQJgoo4oPyDikGrxljZy_txEiQhPjh7iOivv22HGuqALK4SEmu0SoxaZ7qv4yj-hks0Dbn-RjWUncoLacDHEAXutsLQcE2LDAgEBVKzscpz7Om1cPMUvufH9ruMquohv0n9E-jJ-CBDljynhY12bN_kBKdB_t04rN6ZhqdpxB--vgzPrveXVuW_xzoOwFBswaC7ZsRZSEe77pOIBoZrhEzE-0nQ8VUaUxalNlnXiWJY4xolciqddPZ7iz1Mc6XLi_Q0SoW4Ut5vFpcv8QQDJnfrJSz3GifvFZZeqmuwsmIeUWJ202qqMksW3c-Ka0Uf9jcK1iDtvRLg'

解析完成

{
    "jti": "517c6481-483d-4b3a-871c-c1cd8443bdd9",
    "exp": 1590723555,
    "nbf": 0,
    "iat": 1590723255,
    "iss": "http://localhost:8080/auth/realms/openbanking",
    "aud": "account",
    "sub": "f153bb0e-0073-45ec-8594-f32c848f8fab",
    "typ": "Bearer",
    "azp": "client-RS256",
    "nonce": "SqoQKopVco3",
    "auth_time": 1590723225,
    "session_state": "9b88802b-e17f-44b4-847d-57d11944de69",
    "preferred_username": "openbanking",
    "email_verified": false,
    "acr": "1",
    "allowed-origins": [
        "http://localhost:8888"
    ],
    "realm_access": {
        "roles": [
            "offline_access",
            "uma_authorization"
        ]
    },
    "resource_access": {
        "account": {
            "roles": [
                "manage-account",
                "manage-account-links",
                "view-profile"
            ]
        }
    },
    "scope": "openid profile email",
    "client_id": "client-RS256",
    "username": "openbanking",
    "active": true
}

id token解析

{
    "jti": "bc4a2dc8-9e8b-4314-8d42-31d7fa9ff3bf",
    "exp": 1590724567,
    "nbf": 0,
    "iat": 1590724267,
    "iss": "http://localhost:8080/auth/realms/openbanking",
    "aud": "client-RS256",
    "sub": "f153bb0e-0073-45ec-8594-f32c848f8fab",
    "typ": "ID",
    "azp": "client-RS256",
    "nonce": "SqoQKopVco3",
    "auth_time": 1590724220,
    "session_state": "23a61c31-50b4-4ace-92f6-b81028f083c8",
    "preferred_username": "openbanking",
    "email_verified": false,
    "acr": "1",
    "client_id": "client-RS256",
    "username": "openbanking",
    "active": true
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值