当前位置: 首页 > 知识库问答 >
问题:

Spring OAuth2-客户端凭据授予类型中的用户信息

段哲圣
2023-03-14

开发Spring Cloud(使用Netflix OSS堆栈)微服务架构已经有一段时间了。正如您所料,我已经将授权服务器分离为一个独立的微服务。我的前端应用程序使用“密码”授权类型用于用户登录目的。但是,对于从前端服务到其他后端服务的rest调用,我使用的是“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");
}

}

我试图实现一个令牌增强器类来在令牌中提供额外的数据。然而,我不认为这是正确和安全的方式,我正在努力实现。

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;
    }
}

你的协助将不胜感激。

共有1个答案

戚繁
2023-03-14

如果使用的是使用客户机凭据生成的oauth令牌,则无法获取用户信息。您只能获得请求(客户端)的源。

如果想要跨微服务的用户信息,那么您必须使用密码授予类型来生成oauth令牌。

 类似资料:
  • 我可以使用,其中一个keycloak客户机与另一个keycloak客户机通信。然而,只有当我登录到第一个keycloak客户机时,它才起作用,即它向keycloak服务器发送客户机ID、客户机机密、用户名和密码。如果我没有在第一个客户机上使用用户和密码进行身份验证,我会得到“无法设置授权头,因为没有身份验证原则”。但是我已经将keycloak配置为对第一个客户机使用服务帐户(客户机凭据授权),因此

  • 我想使用Spring Security的资源服务器和我的组件中包含的授权服务器来保护我的应用程序。所需的流包括仅使用客户端凭据授予类型并将client_id与client_secret一起传递为bas64标头,在命中终结点后,应该返回令牌以用于进一步的请求。我还包括grant_type:请求参数中的客户端凭据 目前我收到错误:。奇怪的是,尽管我进行了配置,Spring仍然会生成控制台日志中可以看到

  • 我正在玩这里描述的客户端凭据授予流https://msdn.microsoft.com/en-us/office/office365/howto/building-service-apps-in-office-365 这是我最初的授权申请:https://login.microsoftonline.com/common/oauth2/authorize?nonce = c43a 377 e-8b

  • null 用户在登录表单中输入凭据->应用程序1将使用用户凭据从应用程序2获取令牌,其具有密码授予类型->使用令牌访问应用程序1的资源。 问题是Spring Security 5是否支持客户端的密码授予类型?我在Spring Security 5实现中找到了所有rest授予类型,但没有找到密码。

  • 我喜欢从我自己的应用程序管理键斗篷:创建用户 请求一个访问令牌,其用户名:密码在标题 但答案是403: 如何/是否可能通过客户端凭据授权从新服务帐户访问Admin REST API?

  • 我们有一个第三方移动应用程序。它在登录过程中创建一个访问令牌,以使用授权码授权流访问我们的API(.netcore)之一。 https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code 该移动应用程序显示了许多互动程序。登录后,当用户单击其中一个互动程序时,我想调用另一个。netcor