You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Authorization Server中如何为OAuth2Authorizations添加自定义属性?

解决方案

一、确认OAuth2Authorization的attributes字段适用性

完全适合你的场景。OAuth2Authorization的attributes就是为存储自定义扩展信息设计的,JdbcOAuth2AuthorizationService会自动将该Map序列化为JSON格式,存入数据库oauth2_authorization表的attributes字段中,无需额外修改表结构。

二、获取HttpServletRequest中的User-Agent与IP

在Spring Security上下文里,可通过RequestContextHolder直接获取当前请求实例,再提取所需信息:

  • User-Agent:直接通过request.getHeader("User-Agent")获取
  • 请求IP:需考虑反向代理场景(如Nginx),优先读取X-Forwarded-For等头,兜底用request.getRemoteAddr()

工具方法示例:

private String getClientIp(HttpServletRequest request) {
    String ip = request.getHeader("X-Forwarded-For");
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("Proxy-Client-IP");
    }
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getRemoteAddr();
    }
    // 多IP场景取第一个有效IP
    if (ip != null && ip.contains(",")) {
        ip = ip.split(",")[0].trim();
    }
    return ip;
}

三、将自定义信息注入OAuth2Authorization

推荐两种实现方式,按需选择:

方式1:自定义OAuth2AuthorizationGenerator

直接拦截OAuth2Authorization的生成过程,添加自定义属性:

@Component
public class CustomOAuth2AuthorizationGenerator implements OAuth2AuthorizationGenerator {

    private final OAuth2AuthorizationGenerator delegate;

    public CustomOAuth2AuthorizationGenerator(OAuth2AuthorizationGenerator delegate) {
        this.delegate = delegate;
    }

    @Override
    public OAuth2Authorization generate(OAuth2AuthorizationContext context) {
        OAuth2Authorization authorization = this.delegate.generate(context);
        // 获取当前请求实例
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        
        String userAgent = request.getHeader("User-Agent");
        String clientIp = getClientIp(request);
        
        // 基于原实例构建新的OAuth2Authorization,添加自定义属性
        return OAuth2Authorization.from(authorization)
                .attribute("user_agent", userAgent)
                .attribute("client_ip", clientIp)
                .build();
    }

    private String getClientIp(HttpServletRequest request) {
        // 实现上述IP获取逻辑
    }
}

然后在授权服务器配置中替换默认生成器:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig implements AuthorizationServerConfigurer {

    private final CustomOAuth2AuthorizationGenerator customAuthorizationGenerator;

    public AuthorizationServerConfig(CustomOAuth2AuthorizationGenerator customAuthorizationGenerator) {
        this.customAuthorizationGenerator = customAuthorizationGenerator;
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authorizationGenerator(customAuthorizationGenerator);
        // 其他配置:数据源、客户端详情、令牌存储等
    }
}

方式2:通过AuthenticationListener注入授权请求

在授权请求认证成功时,将信息存入AuthorizationRequest的属性中,后续生成OAuth2Authorization会自动继承这些属性:

@Component
public class CustomAuthorizationRequestListener implements AuthenticationListener<OAuth2AuthorizationRequestAuthenticationToken> {

    @Override
    public void onAuthenticationSuccess(OAuth2AuthorizationRequestAuthenticationToken authentication) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        
        String userAgent = request.getHeader("User-Agent");
        String clientIp = getClientIp(request);
        
        // 将属性添加到授权请求中
        authentication.getAuthorizationRequest().getAttributes().put("user_agent", userAgent);
        authentication.getAuthorizationRequest().getAttributes().put("client_ip", clientIp);
    }

    private String getClientIp(HttpServletRequest request) {
        // 实现上述IP获取逻辑
    }
}

四、验证效果

授权流程完成后,查看数据库oauth2_authorization表的attributes字段,会看到包含user_agent和client_ip的JSON数据,说明自定义信息已成功持久化。

内容的提问来源于stack exchange,提问作者wmkoch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 14:28:13