Spring Boot OAuth2 - GoogleApi - 无法从令牌获取用户详细信息
Posted
技术标签:
【中文标题】Spring Boot OAuth2 - GoogleApi - 无法从令牌获取用户详细信息【英文标题】:Spring Boot OAuth2 - GoogleApi- Could not obtain user details from token 【发布时间】:2016-12-31 11:28:57 【问题描述】:我正在开发一个对 Gmail 身份验证有要求并且可以扩展的项目。 我正在关注本教程here,其中包含 Facebook 和 GitHub 身份验证的示例。因此,我尝试使用 Gmail,但遇到了无法解决的错误,并在尝试解决时遇到了新的异常。请帮助我,因为我相信这是代码受我添加影响最小的地方。有了这么多的配置和代码,它适用于 github 和 fb,但不适用于 google。
SocialApplication.java
@SpringBootApplication
@RestController
@EnableOAuth2Client
@EnableAuthorizationServer
@Order(6)
public class SocialApplication extends WebSecurityConfigurerAdapter
@Autowired
OAuth2ClientContext oauth2ClientContext;
@RequestMapping( "/user", "/me" )
public Map<String, String> user(Principal principal)
Map<String, String> map = new LinkedHashMap<>();
map.put("name", principal.getName());
return map;
@Override
protected void configure(HttpSecurity http) throws Exception
// @formatter:off
http.antMatcher("/**").authorizeRequests().antMatchers("/", "/login**", "/webjars/**").permitAll().anyRequest()
.authenticated().and().exceptionHandling()
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/")).and().logout()
.logoutSuccessUrl("/").permitAll().and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
// @formatter:on
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter
@Override
public void configure(HttpSecurity http) throws Exception
// @formatter:off
http.antMatcher("/me").authorizeRequests().anyRequest().authenticated();
// @formatter:on
public static void main(String[] args)
SpringApplication.run(SocialApplication.class, args);
@Bean
public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter)
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(filter);
registration.setOrder(-100);
return registration;
@Bean
@ConfigurationProperties("github")
ClientResources github()
return new ClientResources();
@Bean
@ConfigurationProperties("facebook")
ClientResources facebook()
return new ClientResources();
**@Bean
@ConfigurationProperties("gmail")
ClientResources gmail()return new ClientResources();**
private Filter ssoFilter()
CompositeFilter filter = new CompositeFilter();
List<Filter> filters = new ArrayList<>();
filters.add(ssoFilter(facebook(), "/login/facebook"));
filters.add(ssoFilter(github(), "/login/github"));
**filters.add(ssoFilter(gmail(), "/login/gmail"));**
filter.setFilters(filters);
return filter;
private Filter ssoFilter(ClientResources client, String path)
OAuth2ClientAuthenticationProcessingFilter oAuth2ClientAuthenticationFilter = new OAuth2ClientAuthenticationProcessingFilter(
path);
OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext);
oAuth2ClientAuthenticationFilter.setRestTemplate(oAuth2RestTemplate);
UserInfoTokenServices tokenServices = new UserInfoTokenServices(client.getResource().getUserInfoUri(),
client.getClient().getClientId());
tokenServices.setRestTemplate(oAuth2RestTemplate);
oAuth2ClientAuthenticationFilter.setTokenServices(tokenServices);
return oAuth2ClientAuthenticationFilter;
class ClientResources
private OAuth2ProtectedResourceDetails client = new AuthorizationCodeResourceDetails();
private ResourceServerProperties resource = new ResourceServerProperties();
public OAuth2ProtectedResourceDetails getClient()
return client;
public ResourceServerProperties getResource()
return resource;
index.html
<div>
With Facebook: <a href="/login/facebook">click here</a>
</div>
<div>
With Github: <a href="/login/github">click here</a>
</div>
**<div>
With Gmail: <a href="/login/gmail">click here</a>
</div>**
application.yml // 跳过 github 和 fb 的内容以节省空间
gmail:
client:
client_id: 7xxxxxxxx-1spjexxxxxxxc.apps.googleusercontent.com
scope: https://www.googleapis.com/auth/userinfo.profile
client_secret: Xxxxxxx-I*****zx
userAuthorizationUri: https://accounts.google.com/o/oauth2/auth
accessTokenUri: https://accounts.google.com/o/oauth2/token
auth_provider_x509_cert_url:https://www.googleapis.com/oauth2/v1/certs
日志
org.springframework.security.authentication.BadCredentialsException: 无法从令牌获取用户详细信息 org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter.attemptAuthentication(OAuth2ClientAuthenticationProcessingFilter.java:122) ~[spring-security-oauth2-2.0.10.RELEASE.jar:na] 在 org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) [spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 在 org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:112) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) [spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 在 org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:112) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) [spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 在 org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:112) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE] 在 org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:73) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
**引起: org.springframework.security.oauth2.common.exceptions.InvalidTokenException: 是的 ***********dCCnRbsve3 在 org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices.loadAuthentication(UserInfoTokenServices.java:91) ~[spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE] 在 org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter.attemptAuthentication(OAuth2ClientAuthenticationProcessingFilter.java:112) ~[spring-security-oauth2-2.0.10.RELEASE.jar:na] ... 66 个常用框架 省略
在 Google API 控制台上。
我给出的重定向 URL 为:localhost:8080/login/gmail
【问题讨论】:
【参考方案1】:在您的 application.yml 配置中,我找不到定义的用户信息 url? 我有以下谷歌配置为我工作:
google:
client:
clientId: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
clientSecret: YYYYYYYYYYYYYYYYYY
accessTokenUri: https://accounts.google.com/o/oauth2/token
userAuthorizationUri: https://accounts.google.com/o/oauth2/auth
clientAuthenticationScheme: form
scope: profile email
resource:
userInfoUri: https://www.googleapis.com/userinfo/v2/me
【讨论】:
仅供参考:您不应该使用 userInfoUri 进行身份验证,正如 google 文档中某处指定的那样,您这样做,任何恶意资源提供者都可能冒充您的用户之一。 oAuth2 用于授权,OpenidConnect 用于身份验证。以上是关于Spring Boot OAuth2 - GoogleApi - 无法从令牌获取用户详细信息的主要内容,如果未能解决你的问题,请参考以下文章
使用 spring-boot OAuth2 服务器保护的 Spring-boot 应用程序
让 oauth2 与 spring-boot 和 rest 一起工作
Spring Boot Restful WebAPI集成 OAuth2
Spring Boot + Spring Security + Spring OAuth2 + Google 登录