一段时间以来,我一直在开发Spring Cloud(具有Netflix OSS堆栈)微服务架构。如您所料,我将授权服务器分离为独立的微服务。我的前端应用程序使用“密码”授予类型进行用户登录。但是,对于从前端服务到其他后端服务的其余调用,我正在使用“ client-credentials”授予类型。客户端凭据授予类型也正在其他后端服务中使用。这样,我无法获得谁是请求的实际调用者(当前登录的用户)。有没有办法将主体的身份验证和授权信息注入到客户端凭证授予中发布的令牌中?
我的授权服务器配置类
@Configuration
@EnableAuthorizationServer
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("testclient")
.secret("{noop}testsecret")
.authorizedGrantTypes("authorization_code","password","client_credentials")
.scopes("ui")
.autoApprove(true)
// .accessTokenValiditySeconds(3600)
.and()
.withClient("backend-service")
.secret("{noop}backendsecret")
.authorizedGrantTypes("client_credentials","refresh_token")
.scopes("server")
.autoApprove(true)
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
endpoints.tokenEnhancer(tokenEnhancer());
endpoints.tokenStore(tokenStore());
}
@Bean
public TokenStore tokenStore() {
//return new JdbcTokenStore(dataSource);
return new InMemoryTokenStore();
}
@Bean
@Primary
public AuthorizationServerTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenEnhancer(tokenEnhancer());
tokenServices.setTokenStore(tokenStore());
return tokenServices;
}
@Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
安全配置类
@Configuration
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.requestMatchers()
.antMatchers("/login", "/oauth/authorize")
.and()
.authorizeRequests()
.antMatchers("/resources/**", "/src/main/webapp/**","/css/**","/images/**").permitAll()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll().and().httpBasic().disable();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/static/**","/resources/**", "/src/main/webapp/**","/css/**","/images/**");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("admin").password("{noop}a1b2c3#").roles("User");
}
}
我尝试实现Token Enhancer类来传播令牌中的其他数据。但是,我认为这不是我想要实现的正确和安全的方法。
public class CustomTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {
final Map<String, Object> additionalInfo = new HashMap<>();
additionalInfo.put("customInfo", "testdata");
((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(additionalInfo);
return oAuth2AccessToken;
}
}
您的帮助将不胜感激。
答案 0 :(得分:0)
如果使用的是使用客户端凭据生成的oauth令牌,则无法获取用户信息。您只能获取请求的源(客户端)。
如果要跨微服务获取用户信息,则必须使用密码授予类型来生成oauth令牌。