gpt4 book ai didi

java - 如何测试 spring-security-oauth2 资源服务器安全性?

转载 作者:IT老高 更新时间:2023-10-28 20:39:50 25 4
gpt4 key购买 nike

在 Spring Security 4 发布之后,它是 improved support for testing我想更新我当前的 Spring 安全性 oauth2 资源服务器测试。

目前我有一个帮助类,它使用 ResourceOwnerPasswordResourceDetails 设置一个 OAuth2RestTemplate 和一个连接到实际 AccessTokenUri 的测试 ClientId 为我的测试请求一个有效的 token 。然后使用这个 resttemplate 在我的 @WebIntegrationTests 中发出请求。

我想通过利用 Spring Security 4 中的新测试支持,放弃对实际 AuthorizationServer 的依赖,以及在我的测试中使用有效(如果有限)用户凭据。

到目前为止,我所有尝试使用 @WithMockUser@WithSecurityContextSecurityMockMvcConfigurers.springSecurity()SecurityMockMvcRequestPostProcessors.* 未能通过 MockMvc 进行经过身份验证的调用,我在 Spring 示例项目中找不到任何此类工作示例。

谁能帮助我使用某种模拟凭据测试我的 oauth2 资源服务器,同时仍然测试施加的安全限制?

** 编辑 **此处提供示例代码:https://github.com/timtebeek/resource-server-testing对于每个测试类,我都理解为什么它不能正常工作,但我正在寻找可以让我轻松测试安全设置的方​​法。

我现在正在考虑在 src/test/java 下创建一个非常宽松的 OAuthServer,这可能会有所帮助。有人有其他建议吗?

最佳答案

为了有效地测试资源服务器的安全性,使用 MockMvcRestTemplate它有助于配置 AuthorizationServersrc/test/java 下:

授权服务器

@Configuration
@EnableAuthorizationServer
@SuppressWarnings("static-method")
class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Bean
public JwtAccessTokenConverter accessTokenConverter() throws Exception {
JwtAccessTokenConverter jwt = new JwtAccessTokenConverter();
jwt.setSigningKey(SecurityConfig.key("rsa"));
jwt.setVerifierKey(SecurityConfig.key("rsa.pub"));
jwt.afterPropertiesSet();
return jwt;
}

@Autowired
private AuthenticationManager authenticationManager;

@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.accessTokenConverter(accessTokenConverter());
}

@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("myclientwith")
.authorizedGrantTypes("password")
.authorities("myauthorities")
.resourceIds("myresource")
.scopes("myscope")

.and()
.withClient("myclientwithout")
.authorizedGrantTypes("password")
.authorities("myauthorities")
.resourceIds("myresource")
.scopes(UUID.randomUUID().toString());
}
}

集成测试
对于集成测试,可以简单地使用内置的 OAuth2 测试支持规则和注释:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApp.class)
@WebIntegrationTest(randomPort = true)
@OAuth2ContextConfiguration(MyDetails.class)
public class MyControllerIT implements RestTemplateHolder {
@Value("http://localhost:${local.server.port}")
@Getter
String host;

@Getter
@Setter
RestOperations restTemplate = new TestRestTemplate();

@Rule
public OAuth2ContextSetup context = OAuth2ContextSetup.standard(this);

@Test
public void testHelloOAuth2WithRole() {
ResponseEntity<String> entity = getRestTemplate().getForEntity(host + "/hello", String.class);
assertTrue(entity.getStatusCode().is2xxSuccessful());
}
}

class MyDetails extends ResourceOwnerPasswordResourceDetails {
public MyDetails(final Object obj) {
MyControllerIT it = (MyControllerIT) obj;
setAccessTokenUri(it.getHost() + "/oauth/token");
setClientId("myclientwith");
setUsername("user");
setPassword("password");
}
}

MockMvc 测试
使用 MockMvc 进行测试也是可能的,但需要一个小助手类来获得 RequestPostProcessor设置 Authorization: Bearer <token>请求 header :

@Component
public class OAuthHelper {
// For use with MockMvc
public RequestPostProcessor bearerToken(final String clientid) {
return mockRequest -> {
OAuth2AccessToken token = createAccessToken(clientid);
mockRequest.addHeader("Authorization", "Bearer " + token.getValue());
return mockRequest;
};
}

@Autowired
ClientDetailsService clientDetailsService;
@Autowired
AuthorizationServerTokenServices tokenservice;

OAuth2AccessToken createAccessToken(final String clientId) {
// Look up authorities, resourceIds and scopes based on clientId
ClientDetails client = clientDetailsService.loadClientByClientId(clientId);
Collection<GrantedAuthority> authorities = client.getAuthorities();
Set<String> resourceIds = client.getResourceIds();
Set<String> scopes = client.getScope();

// Default values for other parameters
Map<String, String> requestParameters = Collections.emptyMap();
boolean approved = true;
String redirectUrl = null;
Set<String> responseTypes = Collections.emptySet();
Map<String, Serializable> extensionProperties = Collections.emptyMap();

// Create request
OAuth2Request oAuth2Request = new OAuth2Request(requestParameters, clientId, authorities, approved, scopes,
resourceIds, redirectUrl, responseTypes, extensionProperties);

// Create OAuth2AccessToken
User userPrincipal = new User("user", "", true, true, true, true, authorities);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userPrincipal, null, authorities);
OAuth2Authentication auth = new OAuth2Authentication(oAuth2Request, authenticationToken);
return tokenservice.createAccessToken(auth);
}
}

您的MockMvc然后测试必须得到 RequestPostProcessor来自 OauthHelper类并在发出请求时传递它:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApp.class)
@WebAppConfiguration
public class MyControllerTest {
@Autowired
private WebApplicationContext webapp;

private MockMvc mvc;

@Before
public void before() {
mvc = MockMvcBuilders.webAppContextSetup(webapp)
.apply(springSecurity())
.alwaysDo(print())
.build();
}

@Autowired
private OAuthHelper helper;

@Test
public void testHelloWithRole() throws Exception {
RequestPostProcessor bearerToken = helper.bearerToken("myclientwith");
mvc.perform(get("/hello").with(bearerToken)).andExpect(status().isOk());
}

@Test
public void testHelloWithoutRole() throws Exception {
RequestPostProcessor bearerToken = helper.bearerToken("myclientwithout");
mvc.perform(get("/hello").with(bearerToken)).andExpect(status().isForbidden());
}
}

GitHub 上提供了完整的示例项目:
https://github.com/timtebeek/resource-server-testing

关于java - 如何测试 spring-security-oauth2 资源服务器安全性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29510759/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com