如何使用 spring-social-security SocialAuthenticationFilter 指定 OAuth2 范围?

Posted

技术标签:

【中文标题】如何使用 spring-social-security SocialAuthenticationFilter 指定 OAuth2 范围?【英文标题】:How to specify OAuth2 scope with spring-social-security SocialAuthenticationFilter? 【发布时间】:2013-07-17 22:59:44 【问题描述】:

我正在使用 Spring Social 和 Spring Security 来验证用户身份并在我的 Web 应用程序上自动创建本地帐户。如何提供 OAuth2 scope 进行身份验证?

在spring-social-samples 中,我看不到scope 应该去哪里。

<bean id="socialAuthenticationFilter" class="org.springframework.social.security.SocialAuthenticationFilter"
    c:_0-ref="authenticationManager"
    c:_1-ref="userIdSource"
    c:_2-ref="usersConnectionRepository"
    c:_3-ref="connectionFactoryLocator"
    p:signupUrl="/spring-social-showcase/signup"
    p:rememberMeServices-ref="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices#0" />

<bean id="socialAuthenticationProvider" class="org.springframework.social.security.SocialAuthenticationProvider"
    c:_0-ref="usersConnectionRepository"
    c:_1-ref="socialUsersDetailService" />

scope 的一个特定用例是让用户通过 Facebook 进行身份验证,然后获取用户的 Facebook 电子邮件 (scope="email") 以创建本地帐户。

【问题讨论】:

【参考方案1】:

在您的配置中,您需要将scope 指定为FacebookAuthenticationService 的属性。这是处理对auth/facebook的调用的服务

在 XML 配置中,而不是:

<facebook:config app-id="$facebook.clientId" app-secret="$facebook.clientSecret"/>

使用:

<bean id="connectionFactoryLocator" class="org.springframework.social.security.SocialAuthenticationServiceRegistry">
    <property name="authenticationServices">
        <list>
            <bean class="org.springframework.social.facebook.security.FacebookAuthenticationService">
                <constructor-arg value="$facebook.clientId" />
                <constructor-arg value="$facebook.clientSecret" />
                <!-- Important: The next property name changed from "scope" to "defaultScope" in 1.1.0.M4 -->
                <property name="scope" value="email" />              
            </bean>
        </list>
    </property>
</bean>

这适用于 Spring Social 1.1.0.M3

【讨论】:

恐怕这在 1.1.0.M4 上失败了。原因:org.springframework.beans.NotWritablePropertyException:bean 类 [org.springframework.social.facebook.security.FacebookAuthenticationService] 的无效属性“范围”:Bean 属性“范围”不可写或设置方法无效。 setter的参数类型和getter的返回类型是否匹配 属性名称在 1.1.0.M4 中从 scope 更改为 defaultScope。见github.com/spring-projects/spring-social/blob/1.1.0.M4/…【参考方案2】:

您可以在连接/注册表单中传递额外的scope 参数。参见官方文档中的example for twitter:

<form action="<c:url value="/connect/twitter" />" method="POST">
    <input type="hidden" name="scope" value="publish_stream,offline_access" />
    ...
    <button type="submit"><img src="<c:url value="/resources/social/twitter/signin.png" />"/></button>
</form>

facebook 的原理也是一样的,只是使用适当的范围值。

请务必不要错过这部分:

Facebook 访问令牌在大约 2 小时后过期。所以,为了避免 要求您的用户每 2 小时重新授权一次,这是保持 长寿命访问令牌是请求“offline_access”。

【讨论】:

上面的例子是ProviderSignInController,它使用了url /connect/provider。我想对 SocialAuthenticationFilter 做同样的事情,它使用 url /auth/provider 或者从用户的角度找出如何通过单击鼠标将两者结合起来。 嗨@VictorLyuboslavsky,你能找到解决方案吗?我也在使用 SocialAuthenticationFilter 并且令人惊讶的是,作为隐藏表单字段传递范围在我的本地主机上有效,但在生产环境中无效! @VictorLyuboslavsky @shailesh 我不知道您是否找到了解决方案,但这很简单。使用 GET 参数范围,而不是 /auth/facebook 使用 auth/facebook?scope=email

以上是关于如何使用 spring-social-security SocialAuthenticationFilter 指定 OAuth2 范围?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?

WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?