I searched the web for solution of this problem but didn't find any working solution. I'm trying to setup basic Spring Boot OAuth2 Authorization Provider and Client.
I followed official Spring Boot instructions and created single sign on with Facebook and Github. Then i followed instructions to create Secure Spring Boot Web application.
I wanted to create my own Authorization Server so I added @EnableAuthorizationServer annotation to Secure Web Application as explained here. I also added details of an OAuth2 client as described in a link. I followed further instructions and created a OAuth2 Client.
I start both applications, visit 127.0.0.1:9999 to open a Client, client redirects me to localhost:8080/login, I enter user details and Authentication Provider redirects me to 127.0.0.1:9999/login and I get an error message:
Authentication Failed: Could not obtain user details from token
This is what gets logged:
INFO 2800 --- [nio-9999-exec-3] o.s.b.a.s.o.r.UserInfoTokenServices : Getting user info from: http:// localhost:8080/me
DEBUG 2800 --- [nio-9999-exec-3] o.s.s.oauth2.client.OAuth2RestTemplate : Created GET request for http:// localhost:8080/me
DEBUG 2800 --- [nio-9999-exec-3] o.s.s.oauth2.client.OAuth2RestTemplate : Setting request Accept header to [application/json, application/*+json]
DEBUG 2800 --- [nio-9999-exec-3] o.s.s.oauth2.client.OAuth2RestTemplate : GET request for http:// localhost:8080/me resulted in 200 (OK)
INFO 2800 --- [nio-9999-exec-3] o.s.b.a.s.o.r.UserInfoTokenServices : Could not fetch user details: class org.springframework.web.client.RestClientException, Could not extract response: no suitable HttpMessageConverter found for response type [interface java.util.Map] and content type [text/html;charset=UTF-8]]
This is my Client application:
@EnableAutoConfiguration
@Configuration
@EnableOAuth2Sso
@RestController
public class ClientApplication {
@RequestMapping("/")
public String home(Principal user) {
return "Hello " + user.getName();
}
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
This is client application YML:
server:
port: 9999
security:
oauth2:
client:
client-id: acme
client-secret: acmesecret
access-token-uri: http://localhost:8080/oauth/token
user-authorization-uri: http://localhost:8080/oauth/authorize
resource:
user-info-uri: http://localhost:8080/me
This is my Authorization Provider application:
@SpringBootApplication
public class SecurityApp {
public static void main(String[] args) {
SpringApplication.run(SecurityApp.class, args);
}
}
@Configuration
@EnableWebSecurity
@EnableAuthorizationServer
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("home");
registry.addViewController("/hello").setViewName("hello");
registry.addViewController("/login").setViewName("login");
}
}
@RestController
public class Controller {
@RequestMapping({ "/user", "/me" })
public Map<String, String> user(Principal principal) {
Map<String, String> map = new LinkedHashMap<>();
map.put("name", principal.getName());
return map;
}
}
This is Application Provider YML:
security:
oauth2:
client:
client-id: acme
client-secret: acmesecret
scope: read,write
auto-approve-scopes: '.*'
OAuth2 is an authorization framework that enables the application Web Security to access the resources from the client. To build an OAuth2 application, we need to focus on the Grant Type (Authorization code), Client ID and Client secret.
Conclusion. Spring Security and Spring Boot permit to quickly set up a complete OAuth2 authorization/authentication server in an almost declarative manner. The setup can be further shortened by configuring OAuth2 client's properties directly from application. properties/yml file, as explained in this tutorial.
I solved the issue! I was missing the Resource Server which handles the requests for user endpoint (user-info-uri). To the Authorization Provider application I added this class:
@Configuration
@EnableResourceServer
public class ResourceServer
extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/me")
.authorizeRequests().anyRequest().authenticated();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With