0

0

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

碧海醫心

碧海醫心

发布时间:2025-08-23 13:00:01

|

806人浏览过

|

来源于php中文网

原创

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 attributes;

    public CustomAuthenticationToken(Object principal, Map attributes, Collection 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 getAttributes() {
        return this.attributes;
    }

    public  T getAttribute(String name, Class type) {
        Object value = this.attributes.get(name);
        if (value == null) {
            return null;
        }
        return type.cast(value);
    }
}

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

Sapling AI Content Detector
Sapling AI Content Detector

Sapling.ai推出的免费在线AI内容检测工具

下载
@Bean
public Converter jwtAuthenticationConverter() {
    JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter();
    jwtConverter.setJwtGrantedAuthoritiesConverter(new KeycloakRealmRoleConverter());
    return jwt -> {
        // Extract attributes from JWT claims
        Map attributes = jwt.getClaims();
        // Extract authorities from JWT
        Collection 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框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

94

2025.08.06

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6023

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

777

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1041

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

1059

2024.03.01

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

315

2023.10.09

vb连接access数据库的方法
vb连接access数据库的方法

vb连接access数据库方法:1、使用ADO连接,首先导入System.Data.OleDb模块,然后定义一个连接字符串,接着创建一个OleDbConnection对象并使用Open() 方法打开连接;2、使用DAO连接,首先导入 Microsoft.Jet.OLEDB模块,然后定义一个连接字符串,接着创建一个JetConnection对象并使用Open()方法打开连接即可。

363

2023.10.16

asp连接access数据库的方法
asp连接access数据库的方法

连接的方法:1、使用ADO连接数据库;2、使用DSN连接数据库;3、使用连接字符串连接数据库。想了解更详细的asp连接access数据库的方法,可以阅读本专题下面的文章。

114

2023.10.18

苹果官网入口直接访问
苹果官网入口直接访问

苹果官网直接访问入口是https://www.apple.com/cn/,该页面具备0.8秒首屏渲染、HTTP/3与Brotli加速、WebP+AVIF双格式图片、免登录浏览全参数等特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

10

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQL 教程
SQL 教程

共61课时 | 3万人学习

10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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