Spring Social facebook + Spring Security
Asked Answered
C

1

6

I want to integrate Spring Social facebook into my application with Spring Security (I use xml configurations). All I need is just connect facebook account with my app's account. In simple example I found this:

<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>

So, as I understood, this method comes into play:

public ConnectionRepository createConnectionRepository(String userId) {
        if (userId == null) {
            throw new IllegalArgumentException("userId cannot be null");
        }
        return new JdbcConnectionRepository(userId, jdbcTemplate, connectionFactoryLocator, textEncryptor, tablePrefix);
    }

It resives "userId" from #{request.userPrincipal.name}. So, my question: How can I pass "userId" to this method if I want to obtain this "userId" using SecurityContextHolder.getContext().getAuthentication().getPrincipal().

The only way I see is to create my implementation of JdbcUsersConnectionRepository and redefine createConnectionRepository(String userId) method. But maybe there is more elegant solution.

Curlew answered 10/4, 2013 at 7:13 Comment(0)
L
7

There is another way:

<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();
    }

}

You can do it complitely in SPeL too (I do not like this kind of dependencies):

<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>
Lots answered 10/4, 2013 at 12:6 Comment(8)
In Spring Social 1.0.x, the SpEL is the best way (albeit a bit cumbersome). In Spring Social 1.1.0 there's a new XML-based configuration namespace and a UserIdSource interface. You implement UserIdSource to lookup the user ID (however you see fit) and configure it as a bean. The XML config elements will look for that UserIdSource and use it.Jegger
FWIW, the fact that SpEL expressions are just strings and thus aren't easily testable or necessarily typesafe is the main reason they feel kludgy here. But by virtue of the fact that you're choosing XML for configuration, you've already decided against a typesafe configuration option. Which has me wondering why you would not want to use Java configuration, which is the more powerful and typesafe option for configuring Spring?Jegger
Thank for your clarification Craig. UserIdSource interface is a good news (we need to wait for 1.1.0.RELEASE to be able use it in production code). For you second question: the reason is simple. We have a project that already use xml based config for Spring and Spring Security (framework beans). Annotations are used only for appllication's beans. I think it will be more conviniet for support team to have all config stuff in one format (xml). There is no way to do java conf with Spring Security AFAIK.Lots
You are correct that there's no easy way (yet) to do Spring Security configuration in JavaConfig. My choice then would still be to do as much auto-configuration (component-scanning/auto-wiring) as possible, use JavaConfig for as much as you can for things that you must explicitly configure, and only use XML configuration in cases where JavaConfig isn't practical (e.g., Spring Security). That said, Spring Security 3.2.0.M1 has some initial support for JavaConfig--so that's coming in Spring Security 3.2.0.Jegger
@Maksym, I used your solution but I faced with another problem. SecurityContextHolder.getContext().getAuthentication() returns me null. In others methods where I use SecurityContextHolder, all is ok. As I understood the problem lies somewhere in security filters. If you know how to solve this I would appreciate it.Curlew
By default Spring Security will create anonymous session for each anonymous user. May be this feature is turned off in your security xml? For example via <anonymous enabled="true" />Lots
The problem is that my "user" isn't anonymous. I login into my application before I use getAuthenticatedUsername(). SecurityContextHolder.getContext().getAuthentication() returns null only if I use it in context of getAuthenticatedUsername() method.Curlew
Just make a brakepoint in SecurityContextImpl.setAuthentication(...) method and find a cause in debug mode.Lots

© 2022 - 2024 — McMap. All rights reserved.