客户端授权不适用于单元测试

Client authorization not working for unit tests

好的,首先要知道的是我可以按预期使用实际的 Web 客户端。我能够注册用户并使用它登录。

但是,当我尝试实施一些单元测试时,事情对我不起作用。这就是我在单元测试中创建用户的方式:

@Autowired
private TestRestTemplate template;

@Value("${security.jwt.client-id}")
private String clientId;

@Value("${security.jwt.client-secret}")
private String clientSecret;

private static String USERS_ENDPOINT = "http://localhost:8081/users/";

public AppUser registerUser(String username, String password) {

    AppUser appUser = new AppUser();
    appUser.setUsername(username);
    appUser.setPassword(password);

    ResponseEntity<AppUser> appUserResponseEntity = template.withBasicAuth(clientId, clientSecret)
            .postForEntity(USERS_ENDPOINT, appUser, AppUser.class);

    AppUser registeredAppUser = appUserResponseEntity.getBody();

    assertNotNull("Trying to register new user but the user ID is null which indicates it didn't work.",
            registeredAppUser.getId());

    return registeredAppUser;
}

问题是我在appUserResponseEntity中读取的状态是HTTP 401,返回的AppUser无效(数据库中没有创建用户)。

我也得到一个InsufficientScopeException:

Caused by: org.springframework.security.oauth2.common.exceptions.InsufficientScopeException: Insufficient scope for this resource
    at org.springframework.security.oauth2.provider.expression.OAuth2SecurityExpressionMethods.throwOnError(OAuth2SecurityExpressionMethods.java:71) ~[spring-security-oauth2-2.2.0.RELEASE.jar:na]
    ... 82 common frames omitted

您可以在下面找到我的 AuthorizationServerConfigurerAdapter OAuth2 配置。

@Configuration
@EnableAuthorizationServer
@EnableResourceServer
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {

    @Configuration
    @EnableResourceServer
    public class ResourceServer extends ResourceServerConfigurerAdapter {

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                .requestMatchers().antMatchers("/**")
                .and()
                .authorizeRequests().anyRequest().access("#oauth2.hasScope('write')");
        }

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

    }

    @Value("${security.jwt.client-id}")
    private String clientId;

    @Value("${security.jwt.client-secret}")
    private String clientSecret;

    @Value("${security.jwt.grant-type}")
    private String grantType;

    @Value("${security.jwt.scope-read}")
    private String scopeRead;

    @Value("${security.jwt.scope-write}")
    private String scopeWrite;

    @Value("${security.jwt.resource-ids}")
    private String resourceIds;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private JwtAccessTokenConverter accessTokenConverter;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
        configurer
                .inMemory()
                .withClient(clientId)
                .secret(clientSecret)
                .authorizedGrantTypes(grantType)
                .scopes(scopeRead, scopeWrite)
                .resourceIds(resourceIds);
    }


    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
        enhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));
        endpoints.tokenStore(tokenStore)
                .accessTokenConverter(accessTokenConverter)
                .tokenEnhancer(enhancerChain)
                .authenticationManager(authenticationManager);
    }



}

我不知道为什么这不起作用。有人知道问题出在哪里吗?


我觉得很奇怪的是,它在为匿名用户请求写入权限时失败了。 WebSecurity 实际上应该忽略 /users 端点:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/pub/**", "/users");
}

所以我不太确定为什么安全过滤器链实际上在这里处于活动状态。


更新:

我现在尝试的是在 8080 上启动服务器并在同一调试会话期间使用 TestRestTemplate template 并尝试 POST AppUser 到 8080 和 8081 - 看看:

如您所见,相同的调用在 8080(实际服务器实例 运行)上有效,但在 8081 上无效 - 服务器实例已启动以进行单元测试。

显然我的配置有问题或其他问题,但我无法确定它..

这个我无话可说了:

http://localhost:8081/users