Spring Boot OAuth2 - 无法从令牌获取用户详细信息

Posted

技术标签:

【中文标题】Spring Boot OAuth2 - 无法从令牌获取用户详细信息【英文标题】:Spring Boot OAuth2 - Could not obtain user details from token 【发布时间】:2016-06-02 01:14:56 【问题描述】:

我在网上搜索了此问题的解决方案,但没有找到任何可行的解决方案。我正在尝试设置基本的 Spring Boot OAuth2 授权提供程序和客户端。

我遵循官方 Spring Boot 说明并使用 Facebook 和 Github 创建了单点登录。然后我按照说明创建安全 Spring Boot Web 应用程序。

我想创建自己的授权服务器,因此我将 @EnableAuthorizationServer 注释添加到安全 Web 应用程序,如 here 所述。如链接中所述,我还添加了 OAuth2 客户端的详细信息。我按照进一步的说明创建了一个 OAuth2 客户端。

我启动两个应用程序,访问 127.0.0.1:9999 以打开客户端,客户端将我重定向到 localhost:8080/login,我输入用户详细信息,身份验证提供程序将我重定向到 127.0.0.1:9999/login,我得到一个错误信息:

身份验证失败:无法从令牌获取用户详细信息

这是记录的内容:

INFO 2800 --- [nio-9999-exec-3] o.s.b.a.s.o.r.UserInfoTokenServices : 从 http://localhost:8080/me 获取用户信息

DEBUG 2800 --- [nio-9999-exec-3] o.s.s.oauth2.client.OAuth2RestTemplate : 为 http://localhost:8080/me 创建了 GET 请求

DEBUG 2800 --- [nio-9999-exec-3] o.s.s.oauth2.client.OAuth2RestTemplate : 将请求接受标头设置为 [application/json, application/*+json]

DEBUG 2800 --- [nio-9999-exec-3] o.s.s.oauth2.client.OAuth2RestTemplate :对 http://localhost:8080/me 的 GET 请求导致 200(OK)

INFO 2800 --- [nio-9999-exec-3] osbasorUserInfoTokenServices:无法获取用户详细信息:类 org.springframework.web.client.RestClientException,无法提取响应:找不到适合响应类型的 HttpMessageConverter [接口 java.util.Map] 和内容类型 [text/html;charset=UTF-8]]

这是我的客户端应用程序:

@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);
    


这是客户端应用程序 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

这是我的授权提供者应用程序:

@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;
    

这是应用程序提供者 YML:

security:
  oauth2:
    client:
      client-id: acme
      client-secret: acmesecret
      scope: read,write
      auto-approve-scopes: '.*'

【问题讨论】:

【参考方案1】:

我解决了这个问题!我错过了处理用户端点(user-info-uri)请求的资源服务器。我在 Authorization Provider 应用程序中添加了这个类:

@Configuration
@EnableResourceServer
public class ResourceServer
        extends ResourceServerConfigurerAdapter 
    @Override
    public void configure(HttpSecurity http) throws Exception 
        http
            .antMatcher("/me")
            .authorizeRequests().anyRequest().authenticated();
    

【讨论】:

您将 /me uri 的映射放在身份验证服务器中的什么位置? 看起来像spring.io/guides/tutorials/spring-boot-oauth2 的指南只是告诉你在完成这个必要的步骤(这是下一个)和另一个之前尝试它。我有同样的问题。 @mad_fox,它已在资源服务器主应用程序中配置,而不是在授权服务器中。如果两台服务器都有不同的应用程序。【参考方案2】:

user-info-uri 应该在授权服务器中,因为所有帐户/用户都在其中。

【讨论】:

这应该是一条评论。

以上是关于Spring Boot OAuth2 - 无法从令牌获取用户详细信息的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 access_token 访问资源:spring boot Oauth2

Spring Boot OAuth2 - 无法从令牌获取用户详细信息

Spring Boot OAuth2 - GoogleApi - 无法从令牌获取用户详细信息

Spring Boot 2 和 OAuth2/JWT 配置

如何将 oAuth2.0 与 Spring boot 1.5.8.RELEASE 集成

如何使用spring-boot 1.3.0.RC1为oauth2提供自定义安全性配置