我在本地有以下情况:
现在,我想编写一些集成测试,但是我有点受阻。
默认情况下,我的安全性被配置为有状态的(因此,如果我导航到我的应用程序而不是访问令牌,则将获得会话ID cookie,这不是问题,因为我拥有某种API网关。我有以下内容:
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
http.authorizeRequests(authorizeRequests -> authorizeRequests
.anyRequest()
.authenticated())
.oauth2Login(AbstractAuthenticationFilterConfigurer::permitAll)
.addFilterAfter(new CustomAuthenticationFilter(benutzerRepository), UsernamePasswordAuthenticationFilter.class)
.logout(logout -> logout.logoutSuccessHandler(oidcLogoutSuccessHandler()));
} // @formatter:on
而且我的application.properties类似于:
spring.security.oauth2.client.registration.keycloak.client-id=application_name
spring.security.oauth2.client.registration.keycloak.client-secret=36a2740b-e7b9-4e66-9e2f-242a19d7815f
spring.security.oauth2.client.registration.keycloak.client-name=Keycloak
spring.security.oauth2.client.registration.keycloak.scope=openid, roles
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.keycloak.client-authentication-method=basic
spring.security.oauth2.client.registration.keycloak.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
spring.security.oauth2.client.provider.keycloak.authorization-uri=http://localhost:8180/auth/realms/application_name/protocol/openid-connect/auth
spring.security.oauth2.client.provider.keycloak.token-uri=http://localhost:8180/auth/realms/application_name/protocol/openid-connect/token
spring.security.oauth2.client.provider.keycloak.user-info-uri=http://localhost:8180/auth/realms/application_name/protocol/openid-connect/userinfo
spring.security.oauth2.client.provider.keycloak.jwk-set-uri=http://localhost:8180/auth/realms/application_name/protocol/openid-connect/certs
spring.security.oauth2.client.provider.keycloak.user-name-attribute=preferred_username
这可行,但是现在,我想编写一些集成测试。因此,基本上是在测试中从我的Spring Boot应用程序调用API来触发一些操作,并且我的API当然受到保护。
因此,我做的是让WebClient尝试仅出于集成测试的目的获取访问令牌,并重复通常在后台“神奇地完成”的请求。
我的想法是:-使用webclient调用授权网址以获取代码-发送此代码以及客户ID和客户机密以获取令牌
听起来很简单,但我只是被阻止。我一直从KEycloak收到error = invalid_request,我不知道为什么。
我只是想开始以下操作以获得代码(可能是错误的……):
URIBuilder authorizationURI = new URIBuilder("http://localhost:8180/auth/realms/application_name/protocol/openid-connect/auth");
authorizationURI.addParameter("client_id", "application_name");
authorizationURI.addParameter("scope", "openid");
authorizationURI.addParameter("state", "123456");
authorizationURI.addParameter("redirect_uri", "http://localhost:8080/login/oauth2/code/keycloak");
authorizationURI.addParameter("response_type", "code");
WebClient webclient = WebClient.builder()
.baseUrl(authorizationURI.toString())
.build();
var test = webclient.post()
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body(
BodyInserters.fromFormData("username", "user")
.with("password", "password"))
.exchange()
.block()
.bodyToMono(String.class)
.block();
如果有人遇到相同的问题,我找到了解决方法。
因此,必须在Keycloak中为其客户端设置机密,然后启用服务客户端。然后可以执行以下操作:
URIBuilder authorizationURI = new URIBuilder("http://localhost:8180/auth/realms/application_name/protocol/openid-connect/token");
WebClient webclient = WebClient.builder().build();
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
formData.put("grant_type", Collections.singletonList("client_credentials"));
formData.put("client_id", Collections.singletonList("application_name"));
formData.put("client_secret", Collections.singletonList("tralala-5d0e-4bea-938b-884c1ce4c981"));
还有tadaaaa,您将获得测试的访问令牌。