keycloak~使用jwks验证token的合法性

打印 上一主题 下一主题

主题 917|帖子 917|积分 2751

keycloak提供了jwks服务,其地址可以在/auth/realms/fabao/.well-known/openid-configuration的返回结果中找到,jwks_uri它表示了公钥的颁发者,可以使用颁发出来的公钥来验证token的签名,基地址也是固定的/auth/realms/fabao/protocol/openid-connect/certs。
springboot构建keycloak的token校验服务

依赖包

jwt的解析以来于java-jwt包,由jwks服务解析依赖于jwks-rsa包,jwks是什么,可以看这里
  1.    <dependencyManagement>
  2.       <dependencies>
  3.           <dependency>
  4.               <groupId>org.springframework.boot</groupId>
  5.               <artifactId>spring-boot-starter-parent</artifactId>
  6.               <version>${spring-boot-dependencies.version}</version>
  7.               <type>pom</type>
  8.               <scope>import</scope>
  9.           </dependency>
  10.           <dependency>
  11.               <groupId>org.keycloak.bom</groupId>
  12.               <artifactId>keycloak-adapter-bom</artifactId>
  13.               <version>14.0.0</version>
  14.               <type>pom</type>
  15.               <scope>import</scope>
  16.           </dependency>
  17.       </dependencies>
  18.   </dependencyManagement>
  19.   <dependencies>
  20.       <dependency>
  21.           <groupId>org.springframework.boot</groupId>
  22.           <artifactId>spring-boot-starter-web</artifactId>
  23.       </dependency>
  24.       
  25.       <dependency>
  26.           <groupId>org.keycloak</groupId>
  27.           <artifactId>keycloak-spring-boot-starter</artifactId>
  28.       </dependency>
  29.       
  30.       <dependency>
  31.           <groupId>com.auth0</groupId>
  32.           <artifactId>java-jwt</artifactId>
  33.           <version>3.11.0</version>
  34.       </dependency>
  35.       <dependency>
  36.           <groupId>com.auth0</groupId>
  37.           <artifactId>jwks-rsa</artifactId>
  38.           <version>0.12.0</version>
  39.       </dependency>
  40.   </dependencies>
复制代码
相关设置
  1. keycloak:
  2.     realm: fabao
  3.     resource: pkulaw
  4.     client-key-password: c0b7ab8e-485b-4a10-bff8-7c7d3f472096
  5.     auth-server-url: http://192.168.xx.xx:8080/auth/realms/fabao/protocol/openid-connect/auth
  6. kc:
  7.   jwk-set-uri: http://192.168.xx.xx:8080/auth/realms/fabao/protocol/openid-connect/certs
  8.   certs-id: E_6ih35yTLJMieI0vqg9MmTQrJ6RcUSxiXeNdcMaoYk
复制代码
jwks服务
  1. @Service
  2. public class JwtService {
  3.     @Value("${kc.jwk-set-uri}")
  4.     private String jwksUrl;
  5.     @Value("${kc.certs-id}")
  6.     private String certsId;
  7.     @Cacheable(value = "jwkCache")
  8.     public Jwk getJwk() throws Exception {
  9.         return new UrlJwkProvider(new URL(jwksUrl)).get(certsId);
  10.     }
  11. }
复制代码
校验token

这只是个简单的demo,真实项目中,这种校验的代码应该写在拦截器中,统一进行处理惩罚
  1. @GetMapping("/teacher")
  2.   public HashMap teacher(@RequestHeader("Authorization") String authHeader) {
  3.     try {
  4.         DecodedJWT jwt = JWT.decode(authHeader.replace("Bearer", "").trim());
  5.         // check JWT is valid
  6.         Jwk jwk = jwtService.getJwk();
  7.         Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);
  8.         algorithm.verify(jwt);
  9.         // check JWT role is correct
  10.         List<String> roles = ((List)jwt.getClaim("realm_access").asMap().get("roles"));
  11.         if(!roles.contains("teacher"))
  12.             throw new Exception("not a teacher role");
  13.         // check JWT is still active
  14.         Date expiryDate = jwt.getExpiresAt();
  15.         if(expiryDate.before(new Date()))
  16.             throw new Exception("token is expired");
  17.         // all validation passed
  18.         return new HashMap() {{
  19.             put("role", "teacher");
  20.         }};
  21.     } catch (Exception e) {
  22.         logger.error("exception : {} ", e.getMessage());
  23.         return new HashMap() {{
  24.             put("status", "forbidden");
  25.         }};
  26.     }
  27. }
复制代码
JWKS(JSON Web Key Set)是一个包含一组公钥的 JSON 格式文件,用于在使用 JSON Web Token(JWT)进行身份验证和授权时,验证 JWT 的签名。JWKS 通常用于在 OAuth 2.0 和 OpenID Connect 等认证协议中进行密钥管理。在 JWKS 中,每个公钥都包含了算法、公钥类型和现实的公钥值。通过 JWKS,验证方可以获取到签发方使用的公钥,从而验证 JWT 的签名是否有效。
JWKS 包含以下重要字段:

  • keys:一个数组,包含多个公钥信息的对象,每个对象包括了公钥的相关信息,如算法、公钥类型和公钥值等。
示例 JWKS 文件如下所示:
  1. {
  2.   "keys": [
  3.     {
  4.       "kty": "RSA",
  5.       "kid": "123",
  6.       "use": "sig",
  7.       "alg": "RS256",
  8.       "n": "public_key_value",
  9.       "e": "AQAB"
  10.     }
  11.   ]
  12. }
复制代码
在使用 JWT 进行身份验证时,验证方可以通过获取并解析 JWKS 文件中的公钥信息,然后使用这些公钥来验证 JWT 的签名是否有效。这样可以进步安全性,并确保只有合法的签发方才能生成有效的 JWT。

参考:https://developers.redhat.com/blog/authentication-and-authorization-using-the-keycloak-rest-api#keycloak_connection_using_a_java_application

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

傲渊山岳

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表