oauth2 jwt token 返回accessToken对象中携带用户字段信息

本文介绍了如何在OAuth2中扩展JWT Token,使其在返回的accessToken对象中包含用户字段如userId。首先,需要重写DefaultAccessTokenConverter、UserAuthenticationConverter和JwtAccessTokenConverter在服务器端的方法。然后,在资源服务器client端进行相应配置,确保userId能在accessToken中持久化。对比两种方法,方法二更优,因为它使得access_token中不仅包含userId,还能在accessToken对象中直接显示,且client端配置更为简洁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

oauth2 源码中用户信息只返回用户名称,现有需求要求返回userId,只能重写某些方法,server端和client端都要修改:

方法一、结果:userId 封装在token中,需要解析access_token才能看到,但是经测试发现,使用此方法之后refresh_token获取access_token时,自定义的字段都不见了,连自带的username也不见了,应该是要再重写refresh_token获取时的一些方法,暂未实现。

server:

1、重写 DefaultAccessTokenConverter.java的部分方法:

import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;

import java.util.HashMap;
import java.util.Map;

public class MyDefaultAccessTokenConverter extends DefaultAccessTokenConverter {

    private boolean includeGrantType;

    private String scopeAttribute = SCOPE;

    private String clientIdAttribute = CLIENT_ID;

    private MyUserAuthenticationConverter userTokenConverter = new MyUserAuthenticationConverter();

    public Map<String, ?> convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
        Map<String, Object> response = new HashMap<String, Object>();
        OAuth2Request clientToken = authentication.getOAuth2Request();

        if (!authentication.isClientOnly()) {
            response.putAll(userTokenConverter.convertUserAuthentication(authentication.getUserAuthentication()));
        } else {
            if (clientToken.getAuthorities()!=null && !clientToken.getAuthorities().isEmpty()) {
                response.put(MyUserAuthenticationConverter.AUTHORITIES,
                        AuthorityUtils.authorityListToSet(clientToken.getAuthorities()));
            }
        }

        if (token.getScope()!=null) {
            response.put(scopeAttribute, token.getScope());
        }
        if (token.getAdditionalInformation().containsKey(JTI)) {
            response.put(JTI, token.getAdditionalInformation().get(JTI));
        }

        if (token.getExpiration() != null) {
            response.put(EXP, token.getExpiration().getTime() / 1000);
        }

        if (includeGrantType && authentication.getOAuth2Request().getGrantType()!=null) {
            response.put(GRANT_TYPE, authentication.getOAuth2Request().getGrantType());
        }

        response.putAll(token.getAdditionalInformation());

        response.put(clientIdAttribute, clientToken.getClientId());
        if (clientToken.getResourceIds() != null && !clientToken.getResourceIds().isEmpty()) {
            response.put(AUD, clientToken.getResourceIds());
        }
        return response;
    }
}

2、重写  UserAuthenticationConverter.java的部分方法:

import com.langyatech.fcp.oauth.entity.OauthUser;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;

import java.util.LinkedHashMap;
import java.util.Map;

public class MyUserAuthenticationConverter implements UserAuthenticationConverter {

    @Override
    public Map<String, ?> convertUserAuthentication(Authentication authentication) {
        LinkedHashMap response = new LinkedHashMap();
        response.put("userId", ((OauthUser) authentication.getPrincipal()).getUserId());
        if (authentication.getAuthorities() != null && !authentication.getAuthorities().isEmpty()) {
            response.put("authorities", AuthorityUtils.authorityListToSet(authentication.getAuthorities()));
        }
        return response;
    }

    @Override
    public org.springframework.security.core.Authentication extractAuthentication(Map<String, ?> map) {
        return null;
    }
}

3、重写 JwtAccessTokenConverter.java

import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.jwt.crypto.sign.*;
import org.springframework.security.oauth2.common.*;
import org.springframework.security.oauth2.common.util.JsonParser;
import org.springframework.security.oauth2.common.util.JsonParserFactory;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import java.util.Map;

public class MyJwtAccessTokenConverter extends JwtAccessTokenConverter
{

    private AccessTokenConverter tokenConverter = new MyDefaultAccessTokenConverter();

    private JsonParser objectMapper = JsonParserFactory.create();

    private String verifierKey = new RandomValueStringGenerator().
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值