使用资源服务器客户端密钥和机密生成的令牌向资源服务器授予访问权限-Spring Boot

时间:2020-01-25 11:57:31

标签: spring spring-boot spring-security spring-security-oauth2

我有一个使用spring-boot配置的AuthorizationServer和ResourceServer,我已经在oauth_client_details表中使用唯一的client-id和client-secret注册了两个虚拟客户端。我在ResourceServer中配置了其中一个客户端,提供了client-id和client-secret。然后我使用另一个密钥和密钥生成了一个令牌,并发送了一个带有承载令牌的api请求,它返回成功,这不是预期的行为。我需要允许发送带有由应用程序客户端密钥和机密生成的令牌的请求。在互联网上找不到与此相关的任何内容,我们将为您提供帮助。

下面是授权服务器的代码

@Configuration
public class AuthorizationServerConfiguration implements AuthorizationServerConfigurer {

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private DataSource dataSource;
    @Autowired
    private AuthenticationManager authenticationManager;


    @Bean
    TokenStore jdbcTokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.checkTokenAccess("isAuthenticated()").tokenKeyAccess("permitAll()");

    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource).passwordEncoder(passwordEncoder);

    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(jdbcTokenStore());
        endpoints.authenticationManager(authenticationManager);
    }
}
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {


    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    protected AuthenticationManager getAuthenticationManager() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
}

在资源服务器中,我启用了@EnableResourceServer并在application.yml文件中添加了相关的安全配置

security:
  oauth2:
    resource:
      token-info-uri: http://localhost:9191/oauth/check_token
    client:
      client-id: mobile
      client-secret: pin

请注意,我已经使用另一个注册的客户端密钥和密钥生成了令牌,但是仍然可以使用该令牌成功调用上述资源服务器。

谢谢, 拉吉斯

1 个答案:

答案 0 :(得分:0)

在Google上浏览一天后,我发现我们可以使用resourceId来满足上述情况。

  • 注册客户端(将客户端密钥,秘密保存在带有资源ID或多个资源ID的oauth_client_details中)
  • 使用注册的客户端密钥和机密生成令牌,该令牌包含一个“ aud”字段,该字段表示我们保存在数据库中的资源ID。
  • 下面是从生成的令牌返回的check_token响应

例如:

{
  "aud": [
    "mobile",
    "web",
  ],
  "user_name": "user1",
  "scope": [
    "READ"
  ],
  "active": true,
  "language": "ENGLISH",
  "exp": 1580028351,
  "client_id": "client_1"
}
  • 现在在ResourceServer中,您需要检查提供的令牌是否包含此资源ID。请参见下面的示例代码,它检查提供的承载令牌是否在移动设备上带有aud声音,否则将禁止该请求。
@Configuration
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    private static final String RESOURCE_ID = "mobile";

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId(RESOURCE_ID);
    }

}

就是这样,请告诉我是否可以添加更多内容。谢谢@Thomas Andolf的澄清。