傲渊山岳 发表于 2024-5-18 02:29:04

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

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是什么,可以看这里
   <dependencyManagement>
      <dependencies>
          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>${spring-boot-dependencies.version}</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
          <dependency>
            <groupId>org.keycloak.bom</groupId>
            <artifactId>keycloak-adapter-bom</artifactId>
            <version>14.0.0</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
      </dependencies>
</dependencyManagement>

<dependencies>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      
      <dependency>
          <groupId>org.keycloak</groupId>
          <artifactId>keycloak-spring-boot-starter</artifactId>
      </dependency>
      
      <dependency>
          <groupId>com.auth0</groupId>
          <artifactId>java-jwt</artifactId>
          <version>3.11.0</version>
      </dependency>
      <dependency>
          <groupId>com.auth0</groupId>
          <artifactId>jwks-rsa</artifactId>
          <version>0.12.0</version>
      </dependency>
</dependencies>相关设置

keycloak:
    realm: fabao
    resource: pkulaw
    client-key-password: c0b7ab8e-485b-4a10-bff8-7c7d3f472096
    auth-server-url: http://192.168.xx.xx:8080/auth/realms/fabao/protocol/openid-connect/auth
kc:
jwk-set-uri: http://192.168.xx.xx:8080/auth/realms/fabao/protocol/openid-connect/certs
certs-id: E_6ih35yTLJMieI0vqg9MmTQrJ6RcUSxiXeNdcMaoYkjwks服务

@Service
public class JwtService {

    @Value("${kc.jwk-set-uri}")
    private String jwksUrl;

    @Value("${kc.certs-id}")
    private String certsId;

    @Cacheable(value = "jwkCache")
    public Jwk getJwk() throws Exception {
      return new UrlJwkProvider(new URL(jwksUrl)).get(certsId);
    }
}校验token

这只是个简单的demo,真实项目中,这种校验的代码应该写在拦截器中,统一进行处理惩罚
@GetMapping("/teacher")
public HashMap teacher(@RequestHeader("Authorization") String authHeader) {
    try {
      DecodedJWT jwt = JWT.decode(authHeader.replace("Bearer", "").trim());

      // check JWT is valid
      Jwk jwk = jwtService.getJwk();
      Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);

      algorithm.verify(jwt);

      // check JWT role is correct
      List<String> roles = ((List)jwt.getClaim("realm_access").asMap().get("roles"));
      if(!roles.contains("teacher"))
            throw new Exception("not a teacher role");

      // check JWT is still active
      Date expiryDate = jwt.getExpiresAt();
      if(expiryDate.before(new Date()))
            throw new Exception("token is expired");

      // all validation passed
      return new HashMap() {{
            put("role", "teacher");
      }};
    } catch (Exception e) {
      logger.error("exception : {} ", e.getMessage());
      return new HashMap() {{
            put("status", "forbidden");
      }};
    }
}JWKS(JSON Web Key Set)是一个包含一组公钥的 JSON 格式文件,用于在使用 JSON Web Token(JWT)进行身份验证和授权时,验证 JWT 的签名。JWKS 通常用于在 OAuth 2.0 和 OpenID Connect 等认证协议中进行密钥管理。在 JWKS 中,每个公钥都包含了算法、公钥类型和现实的公钥值。通过 JWKS,验证方可以获取到签发方使用的公钥,从而验证 JWT 的签名是否有效。
JWKS 包含以下重要字段:

[*]keys:一个数组,包含多个公钥信息的对象,每个对象包括了公钥的相关信息,如算法、公钥类型和公钥值等。
示例 JWKS 文件如下所示:
{
"keys": [
    {
      "kty": "RSA",
      "kid": "123",
      "use": "sig",
      "alg": "RS256",
      "n": "public_key_value",
      "e": "AQAB"
    }
]
}在使用 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企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: keycloak~使用jwks验证token的合法性