Spring Social Facebook + Spring Security

6
我希望将Spring Social Facebook整合到我的应用程序中,并使用Spring Security(我使用XML配置)。我所需要的只是连接Facebook账户与我的应用程序账户。在一个简单的示例中,我找到了以下内容:
<bean id="connectionRepository" factory-method="createConnectionRepository" 
      factory-bean="usersConnectionRepository" scope="request">
    <constructor-arg value="#{request.userPrincipal.name}" />
    <aop:scoped-proxy proxy-target-class="false" />
</bean>

因此,据我理解,这种方法发挥作用:
public ConnectionRepository createConnectionRepository(String userId) {
        if (userId == null) {
            throw new IllegalArgumentException("userId cannot be null");
        }
        return new JdbcConnectionRepository(userId, jdbcTemplate, connectionFactoryLocator, textEncryptor, tablePrefix);
    }

它从#{request.userPrincipal.name}接收“userId”。因此,我的问题是:如果我想使用SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取这个“userId”,那么我该如何将“userId”传递给这个方法呢?
我唯一能想到的方法是创建我的JdbcUsersConnectionRepository实现,并重新定义createConnectionRepository(String userId)方法。但可能还有更优雅的解决方案。
1个回答

7
还有另外一种方法:
<bean id="connectionRepository" factory-method="createConnectionRepository" factory-bean="usersConnectionRepository"
    scope="request">
    <constructor-arg value="#{authenticationService.getAuthenticatedUsername()}" />
    <aop:scoped-proxy proxy-target-class="false" />
</bean>

@Service("authenticationService")
public class AuthenticationService {

    public String getAuthenticatedUsername() {
        return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    }

}

你可以完全使用SPeL来完成它(我不喜欢这种依赖关系):
<bean id="connectionRepository" factory-method="createConnectionRepository" factory-bean="usersConnectionRepository"
    scope="request">
    <constructor-arg value="#{T(org.springframework.security.core.context.SecurityContextHolder).getContext().getAuthentication().getPrincipal()}" />
    <aop:scoped-proxy proxy-target-class="false" />
</bean>

值得一提的是,SpEL 表达式只是字符串,因此不容易进行测试或必要的类型安全性,这是它们在这里感到笨拙的主要原因。但是,通过选择 XML 进行配置,您已经决定不使用类型安全的配置选项。这让我想知道为什么您不想使用 Java 配置,这是配置 Spring 的更强大和类型安全的选项? - Craig Walls
感谢您的澄清,Craig。UserIdSource接口是一个好消息(我们需要等待1.1.0.RELEASE才能在生产代码中使用它)。对于您的第二个问题:原因很简单。我们有一个项目已经使用基于xml的配置来配置Spring和Spring Security(框架bean)。注释仅用于应用程序的bean。我认为将所有配置内容放在一个格式(xml)中对支持团队更方便。据我所知,没有办法使用Spring Security进行Java配置。 - Maksym Demidas
您说得没错,目前在JavaConfig中还没有简单的方法来配置Spring Security。因此,我仍然会尽可能地使用自动配置(组件扫描/自动装配),尽可能多地使用JavaConfig来配置必须明确配置的内容,并且仅在JavaConfig不可行时(例如Spring Security)使用XML配置。话虽如此,Spring Security 3.2.0.M1已经开始支持JavaConfig - 所以这将在Spring Security 3.2.0中推出。 - Craig Walls
默认情况下,Spring Security 会为每个匿名用户创建匿名会话。也许在您的安全性 XML 中关闭了此功能?例如通过 <anonymous enabled="true" />。 - Maksym Demidas
只需在 SecurityContextImpl.setAuthentication(...) 方法中设置一个断点,并在调试模式下查找原因。 - Maksym Demidas
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接