具有 OAuth2-ResourceServer 的 Spring 微服务仅返回 String 作为主体而不是我的自定义用户
Posted
技术标签:
【中文标题】具有 OAuth2-ResourceServer 的 Spring 微服务仅返回 String 作为主体而不是我的自定义用户【英文标题】:Spring microservices with OAuth2- ResourceServer returns only String as principal not my custom user 【发布时间】:2018-12-04 09:24:50 【问题描述】:我有两个微服务,一个配置为 OAuth2 服务器 - A,另一个配置为 OAuth2 客户端 - B。我想在这两个微服务之间共享我的自定义用户。当用户通过AI对自己进行身份验证时,创建UserDetails的自定义实现,我想保护B中的一些资源。所以我配置了与A相同的资源服务器。我希望我可以在之间共享我的UserDetails自定义实现A 和 B 使用 Principal。我能够从 A 中的主体获取自定义用户,但在 B 中,主体仅由字符串(用户名)表示。如何让资源服务器返回 UserDetails 的自定义实现而不仅仅是用户名?
source of A - server
服务器配置:
@SpringBootApplication
@EnableResourceServer
@EnableAuthorizationServer
@EnableWebSecurity
public class Application
public static void main(String[] args)
SpringApplication.run(Application.class, args);
UserDetailsService 的实现,它返回我的实现 UserDetails 的 CustomUser(为简单起见只是一个虚拟的)
@Service
@Primary
public class UserDetailsServiceImpl implements UserDetailsService
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
GrantedAuthority authority = new Authority("USER");
return new CustomUser(5L, "username", "nooppassword", Arrays.asList(authority));
OAuth2服务器配置:
@Configuration
public class OAuth2Config extends AuthorizationServerConfigurerAdapter
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception
endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore());
@Bean
public TokenStore tokenStore()
return new InMemoryTokenStore();
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception
clients.inMemory()
.withClient("user")
.secret("nooppassword")
.authorizedGrantTypes("password", "refresh_token")
.scopes("webapp");
WebSecurityConfigurerAdapter:
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter
@Autowired
private UserDetailsService userDetailsService;
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(userDetailsService);
这是其他服务“应该”通过仅返回 Principal 的 rest 端点访问主体的方式,在服务 A 中,它包含 CustomUser 的实例:
@RestController
@RequestMapping("/user")
public class UserRestController
@GetMapping("/auth")
public Principal getPrincipal(Principal principal)
return principal;
客户 source of B - client
Application.properties - A 端点的 url
server.port=8081
security.oauth2.resource.user-info-uri=http://localhost:8080/user/auth
B的开始
@SpringBootApplication
@EnableResourceServer
@EnableWebSecurity
@EnableOAuth2Client
public class Application
public static void main(String[] args)
SpringApplication.run(Application.class, args);
最后是我用来测试主体是字符串(用户名)还是自定义用户的其余控制器。不幸的是,Principal 总是只包含一个用户名和字段映射,其中包含来自自定义用户的值。
@RestController
@RequestMapping("/client")
public class ClientRestController
@GetMapping("/print")
public void printId(Principal principal)
System.out.println(principal);
你能帮我解决一下吗?如何通过我的 CustomUser 传递 Principal?
感谢您的帮助:)
【问题讨论】:
如果您的授权和资源服务器彼此不同,那么这个答案可能会对您有所帮助***.com/questions/51240197/… 【参考方案1】:嗯,返回 Principal 对象不是一个好主意(很可能是它的实现类UsernamePasswordAuthenticationToken
)。如果您只希望端点共享自定义用户详细信息,那么最好的方法是创建一个仅包含您想要公开的信息的数据传输对象。
获取委托人(发出请求的经过身份验证的用户)的推荐方法是从安全上下文中获取。更多信息请访问here。
【讨论】:
以上是关于具有 OAuth2-ResourceServer 的 Spring 微服务仅返回 String 作为主体而不是我的自定义用户的主要内容,如果未能解决你的问题,请参考以下文章
编写一个Car类,具有String类型的属性品牌,具有功能drive;