客户端授权不适用于单元测试
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
好的,首先要知道的是我可以按预期使用实际的 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