Spring security 作为登录提供商使用的Spring Social Google在成功登录Oauth2后失败,返回403

Spring security 作为登录提供商使用的Spring Social Google在成功登录Oauth2后失败,返回403,spring-security,spring-social,spring-social-facebook,spring-social-google,Spring Security,Spring Social,Spring Social Facebook,Spring Social Google,我需要同时使用Facebook和Google作为OpenId登录提供商。我已经使用SocialAuthenticationFilter将它们与Spring Security集成,如中所述,并查看了示例应用程序 我已经成功地配置了Facebook 问题是,当我尝试通过Google验证时: 在OAuth2AuthenticationService.getAuthToken()中: 此时,我可以看到accessGrant包含一个accessToken,因此到目前为止它似乎是正确的。它在以下调用中失败:

我需要同时使用Facebook和Google作为OpenId登录提供商。我已经使用SocialAuthenticationFilter将它们与Spring Security集成,如中所述,并查看了示例应用程序

我已经成功地配置了Facebook

问题是,当我尝试通过Google验证时:

OAuth2AuthenticationService.getAuthToken()中:

此时,我可以看到accessGrant包含一个accessToken,因此到目前为止它似乎是正确的。它在以下调用中失败:

// TODO avoid API call if possible (auth using token would be fine)
Connection<S> connection = getConnectionFactory().createConnection(accessGrant);
getApiAdapter().fetchUserProfile(Google)
->
Google.plusOperations().getGoogleProfile()引发403异常:

org.springframework.web.client.HttpClientErrorException: 403 Forbidden
为什么它不能得到谷歌的个人资料?显然,我设置的范围和提示用户的内容是正确的

完整的项目可在以下位置获得:

配置文件摘录:

证券配置

@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/secure*").authenticated()
                .and()
            .formLogin()
                .loginPage("/login").permitAll()
                //.loginProcessingUrl("/secure-home")
                .failureUrl("/login?param.error=bad_credentials")
                .and()
            .logout()
                .logoutUrl("/logout")
                .deleteCookies("JSESSIONID")
                .and()
            /*.rememberMe()
                .and()*/
            .apply(new SpringSocialConfigurer());
    }

    @Bean
    public SocialUserDetailsService socialUserDetailsService(){
        return new SocialUserDetailsService(){
            @Override
            public SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException{
                return new SimpleSocialUserDetails(userId);
            }
        }
    }

}
@Configuration
@EnableSocial
class SocialConfig extends SocialConfigurerAdapter{

    @Override
    void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) {
        FacebookConnectionFactory fcf = new FacebookConnectionFactory(env.getProperty("facebook.clientId"), env.getProperty("facebook.clientSecret"))
        fcf.setScope("public_profile,email")
        cfConfig.addConnectionFactory(fcf)

        GoogleConnectionFactory gcf = new GoogleConnectionFactory(env.getProperty("google.clientId"), env.getProperty("google.clientSecret"))
        gcf.setScope("openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo#email https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/tasks https://www-opensocial.googleusercontent.com/api/people https://www.googleapis.com/auth/plus.login");
        cfConfig.addConnectionFactory(gcf);
    }

    @Bean
    @Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
    Facebook facebook(ConnectionRepository repository) {
        Connection<Facebook> connection = repository.findPrimaryConnection(Facebook.class);
        return connection != null ? connection.getApi() : null;
    }

    @Bean
    @Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
    Google google(ConnectionRepository repository) {
        Connection<Google> connection = repository.findPrimaryConnection(Google.class);
        return connection != null ? connection.getApi() : null;
    }

    @Override
    UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
        //return new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
        InMemoryUsersConnectionRepository rep = new InMemoryUsersConnectionRepository(connectionFactoryLocator)
        rep.setConnectionSignUp(new ConnectionSignUp(){
            public String execute(Connection<?> connection){
                Facebook facebook = (Facebook)connection.getApi();
                String [] fields = [ "id", "email",  "first_name", "last_name", "about" , "gender" ];
                User userProfile = facebook.fetchObject(connection.getKey().getProviderUserId(), User.class, fields);
                return userProfile.getEmail();
            }
        })
        return rep;
    }

    @Override
    UserIdSource getUserIdSource() {
        return new AuthenticationNameUserIdSource()
    }

}
社会配置

@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/secure*").authenticated()
                .and()
            .formLogin()
                .loginPage("/login").permitAll()
                //.loginProcessingUrl("/secure-home")
                .failureUrl("/login?param.error=bad_credentials")
                .and()
            .logout()
                .logoutUrl("/logout")
                .deleteCookies("JSESSIONID")
                .and()
            /*.rememberMe()
                .and()*/
            .apply(new SpringSocialConfigurer());
    }

    @Bean
    public SocialUserDetailsService socialUserDetailsService(){
        return new SocialUserDetailsService(){
            @Override
            public SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException{
                return new SimpleSocialUserDetails(userId);
            }
        }
    }

}
@Configuration
@EnableSocial
class SocialConfig extends SocialConfigurerAdapter{

    @Override
    void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) {
        FacebookConnectionFactory fcf = new FacebookConnectionFactory(env.getProperty("facebook.clientId"), env.getProperty("facebook.clientSecret"))
        fcf.setScope("public_profile,email")
        cfConfig.addConnectionFactory(fcf)

        GoogleConnectionFactory gcf = new GoogleConnectionFactory(env.getProperty("google.clientId"), env.getProperty("google.clientSecret"))
        gcf.setScope("openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo#email https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/tasks https://www-opensocial.googleusercontent.com/api/people https://www.googleapis.com/auth/plus.login");
        cfConfig.addConnectionFactory(gcf);
    }

    @Bean
    @Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
    Facebook facebook(ConnectionRepository repository) {
        Connection<Facebook> connection = repository.findPrimaryConnection(Facebook.class);
        return connection != null ? connection.getApi() : null;
    }

    @Bean
    @Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
    Google google(ConnectionRepository repository) {
        Connection<Google> connection = repository.findPrimaryConnection(Google.class);
        return connection != null ? connection.getApi() : null;
    }

    @Override
    UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
        //return new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
        InMemoryUsersConnectionRepository rep = new InMemoryUsersConnectionRepository(connectionFactoryLocator)
        rep.setConnectionSignUp(new ConnectionSignUp(){
            public String execute(Connection<?> connection){
                Facebook facebook = (Facebook)connection.getApi();
                String [] fields = [ "id", "email",  "first_name", "last_name", "about" , "gender" ];
                User userProfile = facebook.fetchObject(connection.getKey().getProviderUserId(), User.class, fields);
                return userProfile.getEmail();
            }
        })
        return rep;
    }

    @Override
    UserIdSource getUserIdSource() {
        return new AuthenticationNameUserIdSource()
    }

}
@配置
@使能社会
类SocialConfig扩展了SocialConfigureAdapter{
@凌驾
void addConnectionFactorys(ConnectionFactoryConfigurer cfConfig,环境环境){
FacebookConnectionFactory fcf=新的FacebookConnectionFactory(env.getProperty(“facebook.clientId”)、env.getProperty(“facebook.clientSecret”))
fcf.设置范围(“公共档案,电子邮件”)
cfConfig.addConnectionFactory(fcf)
GoogleConnectionFactory gcf=新的GoogleConnectionFactory(env.getProperty(“google.clientId”)、env.getProperty(“google.clientSecret”))
gcf.设置范围(“openidhttps://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo#email https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/tasks https://www-opensocial.googleusercontent.com/api/people https://www.googleapis.com/auth/plus.login");
cfConfig.addConnectionFactory(gcf);
}
@豆子
@范围(value=“request”,proxyMode=ScopedProxyMode.INTERFACES)
Facebook(ConnectionRepository存储库){
Connection=repository.findPrimaryConnection(Facebook.class);
返回连接!=null?连接。getApi():null;
}
@豆子
@范围(value=“request”,proxyMode=ScopedProxyMode.INTERFACES)
Google(连接存储库){
Connection=repository.findPrimaryConnection(Google.class);
返回连接!=null?连接。getApi():null;
}
@凌驾
UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator ConnectionFactoryLocator){
//返回新的JdbcUsersConnectionRepository(数据源、connectionFactoryLocator、Encryptors.noOpText());
InMemoryUsersConnectionRepository=新建InMemoryUsersConnectionRepository(connectionFactoryLocator)
rep.setConnectionSignUp(新的ConnectionSignUp(){
公共字符串执行(连接){
Facebook=(Facebook)connection.getApi();
字符串[]字段=[“id”、“电子邮件”、“名”、“姓”、“关于”、“性别”];
User userProfile=facebook.fetchObject(connection.getKey().getProviderUserId(),User.class,字段);
返回userProfile.getEmail();
}
})
返回代表;
}
@凌驾
UserIdSource getUserIdSource(){
返回新的AuthenticationNameUserIdSource()
}
}

修复,我必须在Google开发者控制台上启用Google+API