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

Spring Authorization Server对接oauth2-proxy时如何添加用户邮箱?

解决Spring Authorization Server添加用户邮箱以适配oauth2-proxy的方法

要给OAuth2授权流程添加用户邮箱,需要从自定义用户对象、调整UserDetailsService、配置令牌包含邮箱声明三个步骤入手,具体操作如下:

1. 创建自定义UserDetails实现类

默认的User类没有邮箱字段,我们需要实现UserDetails接口,封装包含邮箱的用户信息:

public class CustomUser implements UserDetails {
    private final String username;
    private final String password;
    private final String email;
    private final Collection<? extends GrantedAuthority> authorities;
    private final boolean accountNonExpired;
    private final boolean accountNonLocked;
    private final boolean credentialsNonExpired;
    private final boolean enabled;

    public CustomUser(String username, String password, String email, Collection<? extends GrantedAuthority> authorities) {
        this.username = username;
        this.password = password;
        this.email = email;
        this.authorities = authorities;
        this.accountNonExpired = true;
        this.accountNonLocked = true;
        this.credentialsNonExpired = true;
        this.enabled = true;
    }

    // 实现UserDetails接口的所有getter方法,新增getEmail()
    @Override
    public String getUsername() { return username; }

    @Override
    public String getPassword() { return password; }

    public String getEmail() { return email; }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() { return authorities; }

    @Override
    public boolean isAccountNonExpired() { return accountNonExpired; }

    @Override
    public boolean isAccountNonLocked() { return accountNonLocked; }

    @Override
    public boolean isCredentialsNonExpired() { return credentialsNonExpired; }

    @Override
    public boolean isEnabled() { return enabled; }
}

2. 修改内存式UserDetailsService

替换原来的User对象,返回自定义的CustomUser实例,注意生产环境不要使用明文密码,这里用{noop}仅做示例:

@Bean
public UserDetailsService userDetailsService() {
    GrantedAuthority userAuthority = new SimpleGrantedAuthority("ROLE_USER");
    CustomUser userDetails = new CustomUser(
            "user1",
            "{noop}user1", // 生产环境建议用BCryptPasswordEncoder加密
            "user1@example.com",
            Collections.singletonList(userAuthority)
    );
    return new InMemoryUserDetailsManager(userDetails);
}

3. 配置令牌包含邮箱声明

让Spring Authorization Server在ID Token中添加邮箱字段,oauth2-proxy就能从令牌中获取到邮箱信息:

@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> jwtTokenCustomizer() {
    return context -> {
        // 仅在ID Token中添加邮箱声明
        if (OidcParameterNames.ID_TOKEN.equals(context.getTokenType().getValue())) {
            CustomUser currentUser = (CustomUser) context.getPrincipal().getPrincipal();
            context.getClaims().claim("email", currentUser.getEmail());
        }
    };
}

4. 确保客户端请求包含email权限

在oauth2-proxy对应的客户端配置中,添加email scope,否则授权服务器不会返回邮箱信息:

@Bean
public RegisteredClientRepository registeredClientRepository() {
    RegisteredClient oauth2ProxyClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("oauth2-proxy-client")
            .clientSecret("{noop}your-client-secret")
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .redirectUri("https://your-oauth2-proxy-callback-url")
            .scope(OidcScopes.OPENID)
            .scope(OidcScopes.EMAIL) // 必须添加这个scope
            .scope("read")
            .build();
    return new InMemoryRegisteredClientRepository(oauth2ProxyClient);
}

完成以上配置后,oauth2-proxy就能在授权流程中获取到用户的邮箱地址了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:10:33