首页 > Java > java教程 > 正文

Spring OAuth2 资源服务器中为特定端点添加自定义 Token 授权

碧海醫心
发布: 2025-08-23 13:00:01
原创
803人浏览过

spring oauth2 资源服务器中为特定端点添加自定义 token 授权

本文介绍了如何在 Spring OAuth2 资源服务器中为特定端点实现自定义 Token 授权。通过利用 JWT 的私有声明和 Keycloak 的 mapper 功能,以及自定义的 AbstractAuthenticationToken 实现,可以实现灵活且安全的访问控制策略。文章提供了一种基于订阅数据的访问控制方案,并讨论了如何使用客户端凭据流来认证受信任的客户端。

在标准的 Spring OAuth2 资源服务器配置中,通常使用 JWT 验证来自授权服务器的 Token。然而,在某些情况下,可能需要为特定的端点添加自定义的 Token 验证逻辑。本文将探讨如何实现这种自定义授权,并提供一种基于订阅数据的访问控制方案。

利用 JWT 私有声明实现细粒度访问控制

一种有效的方法是将访问控制所需的所有数据存储在 JWT 中。这需要在授权服务器(例如 Keycloak)上配置,以便将相关数据添加到私有声明中。在 Keycloak 中,可以使用 "mappers" 来实现这一点。

以下是一个 Keycloak mapper 的示例,它查询一个 REST API 来获取订阅数据,并在用户登录时将返回的值作为私有声明添加到 access-token 中:

  1. 创建 REST API: 创建一个 REST API,用于公开订阅数据。该 API 应该能够根据给定的用户 ID 返回该用户的订阅信息和有效期。
  2. 声明 Keycloak 客户端: 在 Keycloak 中声明一个 "confidential" 客户端,并为其分配一个专门的角色,用于访问上述 REST API。
  3. 创建 Keycloak Mapper: 创建一个 Keycloak mapper,该 mapper 使用客户端凭据流,通过上述声明的客户端来调用 REST API。然后,将返回的订阅信息作为私有声明添加到 access-token 中。

通过将订阅信息添加到 access-token 中,可以在资源服务器上使用这些信息来实现细粒度的访问控制。

自定义 AbstractAuthenticationToken

为了更方便地访问和使用 JWT 中的私有声明,可以创建一个自定义的 AbstractAuthenticationToken 实现。这个自定义实现可以将私有声明的解析逻辑封装起来,并提供更易于使用的 API。

以下是一个自定义 AbstractAuthenticationToken 实现的示例:

public class CustomAuthenticationToken extends AbstractAuthenticationToken {

    private final Object principal;
    private final Map<String, Object> attributes;

    public CustomAuthenticationToken(Object principal, Map<String, Object> attributes, Collection<? extends GrantedAuthority> authorities) {
        super(authorities);
        this.principal = principal;
        this.attributes = attributes;
        setAuthenticated(true);
    }

    @Override
    public Object getCredentials() {
        return null;
    }

    @Override
    public Object getPrincipal() {
        return this.principal;
    }

    public Map<String, Object> getAttributes() {
        return this.attributes;
    }

    public <T> T getAttribute(String name, Class<T> type) {
        Object value = this.attributes.get(name);
        if (value == null) {
            return null;
        }
        return type.cast(value);
    }
}
登录后复制

然后,在 jwtAuthenticationConverter bean 中,返回这个自定义的 AbstractAuthenticationToken 实现,而不是默认的 JwtAuthenticationToken。

稿定PPT
稿定PPT

海量PPT模版资源库

稿定PPT 111
查看详情 稿定PPT
@Bean
public Converter<Jwt, ? extends AbstractAuthenticationToken> jwtAuthenticationConverter() {
    JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter();
    jwtConverter.setJwtGrantedAuthoritiesConverter(new KeycloakRealmRoleConverter());
    return jwt -> {
        // Extract attributes from JWT claims
        Map<String, Object> attributes = jwt.getClaims();
        // Extract authorities from JWT
        Collection<GrantedAuthority> authorities = jwtConverter.getJwtGrantedAuthoritiesConverter().convert(jwt);
        // Create custom authentication token
        return new CustomAuthenticationToken(jwt.getSubject(), attributes, authorities);
    };
}
登录后复制

使用 @PreAuthorize 进行访问控制

有了自定义的 AbstractAuthenticationToken 实现,就可以在 @PreAuthorize 注解中使用更具可读性的安全表达式。

以下是一个使用 @PreAuthorize 注解的示例:

@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasSubscription('premium')")
public String getPremiumContent() {
    // ...
}
登录后复制

在这个示例中,只有具有 ROLE_ADMIN 权限或具有 premium 订阅的用户才能访问 getPremiumContent() 方法。

认证受信任的客户端

如果需要认证不受资源所有者("真实用户")上下文约束的受信任客户端,可以使用客户端凭据流从 Keycloak 获取 access-token。

  1. 声明 Keycloak 客户端: 在 Keycloak 中声明 "confidential" 客户端,并为每个客户端创建一个不同的客户端。
  2. 启用客户端凭据: 为这些客户端启用客户端凭据。
  3. 分配角色: 为这些客户端分配所需的角色。
  4. 配置客户端: 配置客户端以使用客户端凭据流从授权服务器获取 access-token,并将 access-token 作为 Bearer authorization header 发送到资源服务器。

从资源服务器的角度来看,这将与使用用户 access-token 的请求没有区别:所有请求都将使用由同一授权服务器颁发的 access-token 进行授权。

总结

通过结合 JWT 私有声明、Keycloak mapper 和自定义 AbstractAuthenticationToken 实现,可以实现灵活且安全的自定义 Token 授权方案。这种方法可以根据用户的订阅信息、角色或其他自定义属性来控制对特定端点的访问。此外,使用客户端凭据流可以认证不受资源所有者上下文约束的受信任客户端。

注意事项:

  • 确保在授权服务器上正确配置 Keycloak mapper,以便将所需的数据添加到 JWT 中。
  • 仔细设计自定义 AbstractAuthenticationToken 实现,以便提供易于使用的 API 来访问 JWT 中的私有声明。
  • 使用 @PreAuthorize 注解时,确保安全表达式的逻辑正确,以避免意外的访问控制漏洞。
  • 在生产环境中,务必保护好客户端凭据,以防止未经授权的访问。

以上就是Spring OAuth2 资源服务器中为特定端点添加自定义 Token 授权的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号