keycloak的access_token解析 用于后端接口鉴权

keycloak的access_token解析 用于后端接口鉴权

keycloak 获取token

https://{}:{}/auth/realms/{realm}/protocol/openid-connect/token

{
    "access_token": "...",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "...",
    "token_type": "bearer",
    "id_token": "...",
    "not-before-policy": 0,
    "session_state": "53959d20-c80b-4923-82b8-bd32cd31563c",
    "scope": "openid profile email"
}
access_token: 认证token
expires_in:到期时间
refresh_expires_in:刷新token到期时间

获取access_token后 和bearer拼接到header头中

-authorization:Bearer {access_token}

access_token 解析

1.keycloak的token是3分钟刷新一次,不是长效的token

这里我们只需要拿到 access_token 即可

eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwsia2lkIiA6ICI2ZDViYzFETUljRi1xRWcwTkhnQ0U3a1NEaEV3UlNGb3FVakF2RXo0NVE0In0.eyJleHAiOjE2ODIzMDQ5MzUsImlhdCI6MTY4MjMwNDYzNSwiYXV0aF90aW1lIjoxNjgyMzA0NjMxLCJqdGkiOiI4ZGFiODI4OS01MDM0LjAtOWQ5Mi1mNjBkYzdmODUwZDkiLCJpc3MiOiJodHRwOi8vbHl0YXBpLmxvbmd5b3UuZ292LmNuOjg0NDMvYXV0aC9yZWFsbXMvbHl0IiwiYXVkIjpbImF1dGgtYXBpIiwiYWNjb3VudCJdLCJzdWIiOiIwNjZlN2NjZS05ZjI0LTQ1NzUtOTk3MC1hMmQzYjRkMTllZWEiJ0eXAiOiJCZWFyZXIiLCJhenAiOiJtYW4iLCJub25jZSI6ImYNjU5LTk5NzAtNDBkYi05NTI3LWYyYTlkMTZjMTExOCIsInNlc3Npb25fc3RhdGUiOiI1Mzk1OWQyMC1jODBiLTQ5MjMtODJiOC1iZDMyY2QzMTU2M2MiLCJhY3IiOiIwIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHBzOi8venh3eS5sb25neW91Lmdvdi5jbjo4MDk1IiwiaHR0cHM6Ly95dGgubHllZHV5dW4uY29tIiwiaHR0cHM6Ly9seWZ5ZHAubG9uZ3lvdS5nb3YuY246OTQ0MyIsImh0dHBzOi8vcXdnYy5sb25neW91Lmdvdi5jbiIsImh0dHA6Ly9seS1nYXRld2F5Lm1veW9uLmNuIiwiaHR0cDovLzELjIzNS4xNTQ6MTAwMjEiLCJodHRwczovL3pobG4ubG9uZ3lvdS5nb3YuY24iLCJodHRwczovL2x5Y3MuY2hpbmE5NTA1OS5jb20uY246MTY2NjYiLCJodHRwczovL2x5dGFwaS5sb25neW91Lmdvdi5jbiIsImh0dHBzOi8veWxqei5sb25neW91Lmdvdi5jbiIsImh0dHA6Ly9seWZ5ZHAubG9uZ3lvdS5nb3YuY246ODA4NSJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImF1dGgtYXZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJsuYW1lIjoi5aiBIOaxqiIsInByZWZlcnJlZF91c2VybmFtZSI6Ijc4OTg1OTI3QGRnd29yay5jb20iLCJnaXZlbl9uYW1lIjoi5aiBIiwiZmFtaWx5X25hbWUiOiLmsaoiLCJlbWFpbCI6Ijc4OTg1OTI3QGRnd29yay5jbs20ifQ.dP1XA2IOYZUD7E-HmQ-F3FaJr4XAgcFEaARSWpGu2pgRuq7lRqlWStoCEUFNaimb5-513SNpZEPQ-1cYn2iJgQHjGfbHD_gIVI1hKmoGIRqNONHpqiF_ttixF93bCYWQbp-cF09Yu-pQeKtl6z28yPcjF7OsagvRpBStclgOSEgwWrL2OAcQkiBfy8IVBpF20mu7B4Swar0VppQ0Brv0cMJCpLqKRrvoOXgGLGZxMiBRHKEfpOiClq5WN3Gbx_QuSy_JvXVHR-RfSRrHIUJ0eJFyulFKEjMooEWJ6x0eXiPwvFOhtu9rOa6huXr44MRjQN_aKjcZOPwod0xdtHoY4w

直接去用 base64 解密是失败的,

可以用 . 号区分开三段 ,这三段分别代表着不同的信息

第一段解析之后是keycloak 里realm里key的设置

第二段解析之后是登录返回的用户信息及配置信息

{
    "exp":1682304935,
    "iat":1682304635,
    "auth_time":1682304631,
    "jti":"8d234sdf9-5434-4fb0-9d92-f60234v850d9",
    "iss":"http://{}:8443/auth/realms/{realm}",
    "aud":[
        "auth-api",
        "account"
    ],
    "sub":"066e7cce-9f24-4575-9970-a2d3b4d19eea",
    "typ":"Bearer",
    "azp":"client_id",
    "nonce":"f8a8ew659-9970-40db-9527-f2ade34c1118",
    "session_state":"5395crd20-c80b-4923-82b8-bd32ad2d563c",
    "acr":"0",
    "allowed-origins":[
        "https://{{}}:8095"
    ],
    "realm_access":{
        "roles":[
            "offline_access",
            "uma_authorization"
        ]
    },
    "resource_access":{
        "client_id":{
            "roles":[
                "roles"
            ]
        },
        "client_id":{
            "roles":[
                "roles"
            ]
        },
        "client_id":{
            "roles":[
                "roles"
            ]
        }
    },
    "scope":"openid profile email",
    "email_verified":false,
    "name":"test",
    "preferred_username":"test",
    "given_name":"test",
    "family_name":"test",
    "email":"test"
}
exp:到期时间 注意这个时间戳是秒为单位的
preferred_username:用户信息

代码实例

这里使用springboot自带的拦截器实现

package com.hzlh.handler;


/**
 * 基于keycloke的access token 做接口的鉴权   token每分钟刷新一次
 */
@Component
public class KeycloakAuthInterceptor implements HandlerInterceptor {

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String authorization = request.getHeader("authorization");
    if (StrUtil.isEmpty(authorization)){
      response.sendError(HttpServletResponse.SC_UNAUTHORIZED,"Invalid authentication token. Please check your token and try again");
      return false;
    }
    authorization=authorization.replace("Bearer ","");
    String[] splitToken = authorization.split("\\.");
    String decodedToken = new String(Base64.getUrlDecoder().decode(splitToken[1]), StandardCharsets.UTF_8);
    JSONObject jsonObject = JSONObject.parseObject(decodedToken);
    //获得用户信息  可做用户校验这边只简单判空
    String preferred_username = jsonObject.getString("preferred_username");
    if (StrUtil.isEmpty(preferred_username)){
      response.sendError(HttpServletResponse.SC_UNAUTHORIZED,"Invalid authentication token. Please check your token and try again");
      return false;
    }
    //令牌过期时间
    String expTime = jsonObject.getString("exp");
    if (StrUtil.isEmpty(expTime)){
      response.sendError(HttpServletResponse.SC_UNAUTHORIZED,"Invalid authentication token. Please check your token and try again");
      return false;
    }
    long l = System.currentTimeMillis()/1000;
    if (l > Convert.toLong(expTime)){
      response.sendError(HttpServletResponse.SC_UNAUTHORIZED,"Invalid authentication token. Please check your token and try again");
      return false;
    }
    return true;
  }
}
  • 拦截器注册
package com.hzlh.config;


@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new KeycloakAuthInterceptor())
                .addPathPatterns(
                        //拦截请求
                );
    }
}

注:本文涉及的密钥都是参了假数据的所以不要尝试解析,以你的数据为准

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值