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
相关产品推荐
相关产品推荐

