I tried to configure the authorization code flow as a client. As far the flow is working. I get a redirect to the login page. The oauth2 server gives me an auth code and I can exchange the code for an access token.
But I can't get the last step right: get back to the original resource. This is my SecurityConfig:
@Configuration
@EnableWebSecurity
@EnableOAuth2Client
public class SecureConfig extends WebSecurityConfigurerAdapter {
@Autowired
OAuth2ClientContext oauth2ClientContext;
@Value("${openId.userinfo}")
private String userInfoUri;
@Value("${openId.clientId}")
private String clientId;
@Value("${openId.clientSecret}")
private String clientSecret;
@Value("${openId.accessTokenUri}")
private String accessTokenUri;
@Value("${openId.userAuthorizationUri}")
private String userAuthorizationUri;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.addFilterAfter(ssoFilter(), BasicAuthenticationFilter.class);
}
private OAuth2ClientAuthenticationProcessingFilter ssoFilter() {
OAuth2ClientAuthenticationProcessingFilter openIDFilter = new OAuth2ClientAuthenticationProcessingFilter("/resource/**");
openIDFilter.setRestTemplate(restTemplate());
UserInfoTokenServices tokenServices = new UserInfoTokenServices(userInfoUri, clientId);
tokenServices.setRestTemplate(restTemplate());
openIDFilter.setTokenServices(tokenServices);
return openIDFilter;
}
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public OAuth2RestTemplate restTemplate() {
return new OAuth2RestTemplate(protectedResourceDetails(), oauth2ClientContext);
}
@Bean
public FilterRegistrationBean oauth2ClientFilterRegistration(
OAuth2ClientContextFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(filter);
registration.setOrder(-100);
return registration;
}
@Bean
public OAuth2ProtectedResourceDetails protectedResourceDetails() {
AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
details.setClientId(clientId);
details.setClientSecret(clientSecret);
details.setAccessTokenUri(accessTokenUri);
details.setUserAuthorizationUri(userAuthorizationUri);
details.setScope(Arrays.asList("read"));
details.setUseCurrentUri(true);
return details;
}
}
And this is my controller:
@Controller
@RequestMapping("/resource")
public class TestController {
@RequestMapping(value = "/test", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseStatus(code = HttpStatus.OK)
public void test(){
System.out.println("hello world");
}
}
In the last step spring redirect me to my base url:
I found this forum post
It suggests saving the request in the RequestCache
. But this post is about 6 years old, maybe spring offers a more elegant solution in the meantime?
EDIT: This are my dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
</dependencies>