Spring OAuth2登录-不允许匿名? [英] Spring Oauth2 login - anonymous not allowed?

查看:40
本文介绍了Spring OAuth2登录-不允许匿名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按照manual我实现了连接到Facebook图形API并从用户检索信息。当我想要访问(登录)Facebook时,出现了这个问题,我收到了这个错误:

org.springframework.security.authentication.InsufficientAuthenticationException: Authentication is required to obtain an access token (anonymous not allowed)
    at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:88) ~[spring-security-oauth2-2.0.7.RELEASE.jar:na]
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221) ~[spring-security-oauth2-2.0.7.RELEASE.jar:na]
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173) ~[spring-security-oauth2-2.0.7.RELEASE.jar:na]
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:105) ~[spring-security-oauth2-2.0.7.RELEASE.jar:na]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:565) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128) ~[spring-security-oauth2-2.0.7.RELEASE.jar:na]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:530) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at com.sun.proxy.$Proxy79.getForObject(Unknown Source) ~[na:na]
    at com.xxxx.xxxx.controllers.FacebookController.login(FacebookController.java:39) ~[classes/:na] 

错误清楚地显示为"不允许匿名用户获取访问令牌"。当然,该用户是匿名的,并且正在尝试进行身份验证。那我该怎么做呢?也许我在控制器上所做的不是正确的登录方式?

控制器:

@RequestMapping("/facebookLogin")
@ResponseBody
public User login() {
    ObjectNode result = facebookRestTemplate
            .getForObject(
                    "https://graph.facebook.com/me/?fields=name,email,third_party_id",
                    ObjectNode.class);
    ...
}

我正在使用spring-security:4.0.1.RELEASEspring-security-oauth2:2.0.7.RELEASE

注意:在此方案中,我使用的是Facebook,但该问题也应该出现在Google、Twitter等网站上。

推荐答案

Hi在tonr2项目中检查此代码

https://github.com/spring-projects/spring-security-oauth/blob/master/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/WebMvcConfig.java

@Bean
    public OAuth2ProtectedResourceDetails facebook() {
        AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
        details.setId("facebook");
        details.setClientId("233668646673605");
        details.setClientSecret("33b17e044ee6a4fa383f46ec6e28ea1d");
        details.setAccessTokenUri("https://graph.facebook.com/oauth/access_token");
        details.setUserAuthorizationUri("https://www.facebook.com/dialog/oauth");
        details.setTokenName("oauth_token");
        details.setAuthenticationScheme(AuthenticationScheme.query);
        details.setClientAuthenticationScheme(AuthenticationScheme.form);
        return details;
    }
相应地在OAuth2ProtectedResourceDetail上添加您的Facebook凭据。 然后,当您尝试从Facebook获取数据时,此Bean将由Spring Security OAuth AuthationProvider引用,一旦FacebookController尝试访问FB数据,该数据就会被自动检测到。 但您必须了解以下配置:

https://github.com/spring-projects/spring-security-oauth/blob/master/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("marissa").password("wombat").roles("USER").and().withUser("sam")
                .password("kangaroo").roles("USER");
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
            http.authorizeRequests()
                .antMatchers("/sparklr/**","/facebook/**").hasRole("USER")
                .anyRequest().permitAll()
                .and()
            .logout()
                .logoutSuccessUrl("/login.jsp")
                .permitAll()
                .and()
            .formLogin()
                .loginProcessingUrl("/login")
                .loginPage("/login.jsp")
                .failureUrl("/login.jsp?authentication_error=true")
                .permitAll();
        // @formatter:on
    }

}

假设您将使用tonr2应用程序,inMemory身份验证使用用户"marissa"和密码"袋熊"在Spring安全上提供身份验证。因此,在您的UI中,尝试首先针对Spring Security进行身份验证。 一旦通过身份验证,您将拥有"User"角色。只有这一次,您才能访问名为FaceBookController的资源,该资源试图从Facebook本身检索数据,请参阅此代码段

        http.authorizeRequests()
            .antMatchers("/sparklr/**","/facebook/**").hasRole("USER")
            .anyRequest().permitAll()
            .and()

因此只需相应地调整代码即可。

更新

注意:给定的Spring Security示例应用程序尚未配置为具有动态客户端密钥,为了简单演示,它仍然在OAuth2ProtectedResourceDetail中使用单个密钥进行硬编码。从经过身份验证的Facebook用户检索动态Facebook客户端密钥需要额外的更多步骤。或者,如果您只想测试Facebook检索,请将上面的代码调整为如下所示:

http.authorizeRequests()
            .anyRequest().permitAll()
            .and()

删除要求用户具有角色USER的限制,只允许所有请求,而无需首先在Spring Security上进行身份验证。

这篇关于Spring OAuth2登录-不允许匿名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆