0

使用 - spring-social 1.1.4 - spring-social-twitter 1.1.2 - spring-mvc-4.2 - 在tomcat 7上

下面是我的 MVC 应用程序的 tomcat 配置,包括 twitter 设置和 usersConnectionRepository。

这对于登录的 MVC 用户来说一切正常。

当我想允许客户端从非 MVC 身份验证用户可用的公共链接发送推文时,我的问题就出现了。(#{request.userPrincipal.name} 将为空)

我看过很多例子。大多数示例使用旧的 1.0.0 spring-social。我注意到 spring-social- twitter的新 1.1.2 版本没有零参数 Twitter() 构造函数,在某些示例中,它被证明是一种无需 connectionRepository 的工作方式。

我正在寻找一种方法来配置或编码一个选项,以允许登录到我的应用程序的用户和匿名用户在我的网站上使用某些选项。

在下面的配置中,匿名用户被重定向到 connect/twitter 将导致获取 connetionRepository 的问题。usersConnectionRepository 必须有一个“#{request.userPrincipal.name}”,因为我的 connectController 依赖于此。

我在想也许我需要一个自定义连接控制器......必须有一个正确的方法。

欢迎任何建议。

我的 web.xml

    <listener>
  <listener-class>
          org.springframework.web.util.Log4jConfigListener
      </listener-class>
</listener>


<display-name>Central Portal</display-name>

<context-param>  
    <param-name>spring.profiles.active</param-name>  
    <param-value>dev</param-value>  
</context-param>  
<context-param>  
    <param-name>spring.profiles.default</param-name>  
    <param-value>dev</param-value>  
</context-param>
<context-param>  
    <param-name>spring.liveBeansView.mbeanDomain</param-name>  
    <param-value>dev</param-value>  
</context-param> 

<!-- Spring MVC -->
<servlet> 
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<error-page>
    <error-code>500</error-code>
    <location>/WEB-INF//pages/error.jsp</location>
</error-page>

<error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/pages/error.jsp</location>
</error-page>

<error-page>
    <location>/WEB-INF/pages/error.jsp</location>
</error-page>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring-security.xml,
        /WEB-INF/spring-database.xml   
    </param-value>
</context-param> 



<!-- Enable POST  --> 
<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>


<!-- Spring Security -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- Concurrency listener -->
<listener>
    <listener-class>
        org.springframework.security.web.session.HttpSessionEventPublisher
    </listener-class>
</listener>

一点java配置 在此处输入图像描述

mvc-调度程序-servlet.xml

<context:component-scan base-package="org.schoolit.usermanager.config" /> 

<!-- component-scan / controllers -->
<context:component-scan base-package="org.schoolit.webapplication.*" />
<context:component-scan base-package="org.schoolit.spring.social.*"/>

<!-- property-placeholder's  -->
<context:property-placeholder location="classpath:oauth.properties"/>

<!-- resource mapping  -->
<mvc:resources mapping="/gen/**" location="/WEB-INF/gen/" cache-period="31556926"/>
<mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" cache-period="31556926"/>

<!-- JSP ViewResolver -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/pages/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

<!-- twitter stuff start --> 
<bean id="handlerExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="Exception">error</prop>
        </props>
    </property>
</bean> 

 <bean id="twitterTemplate" 
    class="org.springframework.social.twitter.api.impl.TwitterTemplate">
    <constructor-arg value="${twitter.oauth.consumerKey}"/>
    <constructor-arg value="${twitter.oauth.consumerSecret}"/>
<!--<constructor-arg value="${twitter.oauth.accessToken}"/>
    <constructor-arg value="${twitter.oauth.accessTokenSecret}"/>   --> 
</bean> 



<bean id="connectionFactoryLocator" class="org.springframework.social.connect.support.ConnectionFactoryRegistry">
    <property name="connectionFactories">
        <list>
            <bean class="org.springframework.social.twitter.connect.TwitterConnectionFactory">
                <constructor-arg value="${twitter.oauth.consumerKey}" />
                <constructor-arg value="${twitter.oauth.consumerSecret}" />          
            </bean>
        </list>
    </property>
</bean>  


<bean id="connectionRepository" factory-method="createConnectionRepository" factory-bean="usersConnectionRepository" scope="request">
    <constructor-arg value="#{request.userPrincipal.name}" />
    <aop:scoped-proxy proxy-target-class="true" />
</bean>

<bean id="usersConnectionRepository" 
      class="org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository">
    <constructor-arg ref="dataSource" />
    <constructor-arg ref="connectionFactoryLocator" />
    <constructor-arg ref="textEncryptor" />
</bean>

<bean id="textEncryptor" class="org.springframework.security.crypto.encrypt.Encryptors" 
            factory-method="noOpText" />

 <bean id="connectController" class="org.springframework.social.connect.web.ConnectController">
    <constructor-arg ref="connectionFactoryLocator"/>
    <constructor-arg ref="connectionRepository"/>
    <property name="applicationUrl" value="http://localhost:8080/CentralPortal/" />
    <property name="connectInterceptors">
            <list> 
                <bean class="org.schoolit.spring.social.TweetAfterConnectInterceptor"/>
            </list>
    </property> 
</bean>       

弹簧数据库.xml

    <!-- App's dataSource used by jdbcTemplate,jdbc-user-service and connectController -->
<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/spring_me" />
    <property name="username" value="root" />
    <property name="password" value="<mypassword>" />
</bean>

<!-- jdbcTemplate used in usermanager bit only for now. --> 
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
    <constructor-arg ref="dataSource" /> 
</bean>

弹簧安全.xml

  <!-- enable use-expressions -->
<http auto-config="true" use-expressions="true"> 

    <!-- Set up rolefilter's for requestmapping's -->
    <intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" />
    <intercept-url pattern="/usermanager**" access="hasRole('ROLE_ADMIN')" />  
    <intercept-url pattern="/users**" access="hasRole('ROLE_ADMIN')" />


    <!-- access denied page --> 
    <access-denied-handler error-page="/403" /> 
    <!-- loginform-setup Spring Security -->
    <form-login 
        login-page="/login" 
        default-target-url="/home" 
        login-processing-url="/j_spring_security_check"
        authentication-failure-url="/login?error" 
        username-parameter="username"
        password-parameter="password" /> 
    <logout logout-success-url="/login?logout"  />

    <!-- enable csrf protection default is enabled from 4.0 spring 
    <csrf /> <csrf disabled="true"/>  -->
     <csrf request-matcher-ref="connect/*" disabled="true"/>

    <!-- Prevent Clickjacking iframe's  --> 
    <headers>
        <frame-options policy="SAMEORIGIN"/> 
    </headers>  
    <!-- One login per username should be one set to 5 for testing-->
    <session-management>
        <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/login?error"   /> 
    </session-management>
</http>

<!-- Select users and user_roles from database -->
<authentication-manager>
    <authentication-provider>
    <password-encoder ref="encoder" />
        <jdbc-user-service data-source-ref="dataSource"
            users-by-username-query="select username,password, enabled from users where username=?"
            authorities-by-username-query="select username, role from user_roles where username =?  " />
    </authentication-provider>
</authentication-manager>

<!-- encoder bean. Used for password encryption -->
<beans:bean id="encoder" 
    class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
    <beans:constructor-arg name="strength" value="11" />
</beans:bean>
4

1 回答 1

2

我看到您已经twitterTemplate配置了 bean,如果您能够在应用程序中使用它,您将不需要做任何其他事情。

使用TwitterTemplate而不是Twitter. TwitterTemplate实现Twitter接口,所以所有方法都可用。

例子:

//1. Search Twitter
SearchResults results = twitterTemplate.searchOperations().search("#WinterIsComing");
List<Tweet> tweets = results.getTweets();
int i =0;
for (Tweet tweet : tweets) {
    System.out.println(tweet.getUser().getName() + " Tweeted : "+tweet.getText() + " from " + tweet.getUser().getLocation() 
            + " @ " + tweet.getCreatedAt() + tweet.getUser().getLocation()  );
}

//2. Search Place by GeoLocation        
RestTemplate restTemplate = twitterTemplate.getRestTemplate();
GeoTemplate geoTemplate = new GeoTemplate(restTemplate, true, true);
List<Place> place = geoTemplate.search(37.423021, -122.083739);
for (Place p : place) {
    System.out.println(p.getName() + " " + p.getCountry() + " "+p.getId());
}           

//3. Get Twitter UserProfile
TwitterProfile userProfile = twitterTemplate.userOperations().getUserProfile();
System.out.println(userProfile.getName()+" has " +userProfile.getFriendsCount() + " friends");

使用TwitterTemplate,用户无需登录。希望这可以帮助!

于 2016-01-23T19:44:52.763 回答