Spring Security LDAP - login problem (ProviderNotFoundException) - spring

I have problem with LDAP Spring Security, I'm trying to authorise against the LDAP server. I have the spring configuration xml file (security-config.xml) like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://111.111.111.111"/>
<property name="userDn" value="cn=auth-user,ou=System,dc=foo,dc=com"/>
<property name="password" value="fooPwd"/>
</bean>
<bean id="ldapAuthProvider" class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
<constructor-arg ref="contextSource"/>
<property name="userSearch">
<bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" value="ou=people"/>
<constructor-arg index="1" value="(uid={0})"/>
<constructor-arg index="2" ref="contextSource" />
</bean>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="com.company.name.services.UserAuthoritiesPopulator" />
</constructor-arg>
</bean>
</beans>
In the login controller (LoginController.java) I'm authorising like this:
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String loginPPost(String username, String password, Model model, HttpServletRequest req, HttpServletResponse res) throws SQLException {
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
Authentication authentication = authenticationManager.authenticate(authRequest);
SecurityContextHolder.getContext().setAuthentication(authentication);
...
}
The method "authenticationManager.authenticate(authRequest)" throws this exception:
org.springframework.security.providers.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.providers.UsernamePasswordAuthenticationToken
at org.springframework.security.providers.ProviderManager.doAuthentication(ProviderManager.java:214)
at org.springframework.security.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:46)
Does anybody know how to solve this problem? Should I use different method for authorisation? Or is my configuration bad?
Thanks for any help,
Mateo

You must add the tag 'sec:custom-authentication-provider' in your authentication provider bean:
<bean id="ldapAuthProvider" class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
<sec:custom-authentication-provider/>
...
</bean>
You can find an example that use Crowd instead of LDAP on my blog:
http://aloiscochard.blogspot.com/2009/12/integrating-spring-security-with-ntlm_19.html

Related

Spring MVC can't access #Autowired fields from #MessageMapping annotated methods

I've been setting up my Spring 4 MVC application to work with STOMP over WebSocket and so far i've succeeded, my servlet can handle and dispatch STOMP messages without problems.
However, i've encountered an annoying problem when handling these messages from #MessageMapping annotated methods inside my controllers: I can't access any of the #Autowired controller's fields from inside these methods (they all are null pointers), but i can access these fields on the same controller from #RequestMapping annotated methods without any problem.
My Dispatcher Servlet Config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd">
<mvc:annotation-driven/>
<mvc:resources location="assets" mapping="/assets/**"/>
<mvc:resources location="assets/img/favicon.ico" mapping="/favicon.ico" />
<context:component-scan base-package="com.company.web.controller"/>
<security:global-method-security pre-post-annotations="enabled" />
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="contentNegotiationManager">
<bean class="org.springframework.web.accept.ContentNegotiationManager">
<constructor-arg>
<bean class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy">
<constructor-arg>
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</constructor-arg>
</bean>
</constructor-arg>
</bean>
</property>
</bean>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="language"/>
<bean class="com.hxplus.web.interceptor.aCustomAwesomeInterceptor"/>
</mvc:interceptors>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" p:defaultLocale="es"/>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="messages"></bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" p:order="2"/>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" p:order="0"/>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size -->
<property name="maxUploadSize" value="${upload.limit}" />
</bean>
<context:property-placeholder location="classpath*:upload_config.properties"/>
<websocket:message-broker application-destination-prefix="/app">
<websocket:stomp-endpoint path="/hello/{recipient}">
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic" />
</websocket:message-broker>
</beans>
My Controller:
#Controller
public class TheController {
private static final Logger _logger = LoggerFactory.getLogger(TheController.class);
#Autowired private TheService theService;
#Autowired private SimpMessagingTemplate simpMessagingTemplate;
#PreAuthorize("hasRole('GOD')")
#RequestMapping(value = "/something/{id}", method = RequestMethod.GET)
public String show(Model model, #PathVariable("id") Long id) {
//HERE I CAN ACCESS BOTH "theService" AND
//"simpMessagingTemplate" WITHOUT PROBLEMS
}
#MessageMapping("/hello/{recipient}")
private VOID testing(StompEvent event, #DestinationVariable String recipient){
//HERE BOTH "theService" AND "simpMessagingTemplate" ARE NULL
}
}
I found my error and it had nothing to do with Spring Messaging or configuration, it was a pretty dumb error actually so i apologize:
My #MessageMapping annotated method was private and it should have been public.

How to consume third party WSDL services in Spring MVC

I wrote some services (used by an Android app) which takes a request and sends th response in json. Now I have a scenario where I have to consume a third party web service, through a provided WSDL file. I don't know how to do this, can anyone help?
This is my dispatcher-servlet.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans ">
<context:property-placeholder location="classpath:jdbc.properties" />
<context:component-scan base-package="com.srihari" />
<tx:annotation-driven transaction-manager="hibernateTransactionManager" />
<mvc:annotation-driven />
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.srihari.model.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
//This is used to convert my requests and responses into json automatically
<bean id="jacksonMessageChanger" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list id="beanList">
<ref bean="jacksonMessageChanger"/>
</util:list>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="json" value="application/json"/>
<entry key="html" value="text/html"></entry>
<entry key="xml" value="application/xml"></entry>
</map>
</property>
</bean>
</beans>
This is my simple controller: These services are working fine
#Controller
#RequestMapping("/home")
public class UserController {
#RequestMapping(value="/getallusers",method = RequestMethod.GET)
public #ResponseBody List<User> getallusers()
{
List<User> allUsersDetails =userServices.getAllUsers();
return allUsersDetails;
}
}
This is the WSDL file provided by the third party
POST /someservices/otherService.asmx HTTP/1.1
Host: sriharicorp.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/CreateCard"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<UserCredentials xmlns="http://tempuri.org/">
<Password>string</Password>
<Username>string</Username>
</UserCredentials>
</soap:Header>
<soap:Body>
Example String Request
<CreateCard xmlns="http://tempuri.org/">
<request>
<DePpAcctCreationDate>string</DePpAcctCreationDate>
<DePpAcctCreationTime>string</DePpAcctCreationTime>
//Some other fields also
</request>
</CreateCard>
</soap:Body>
</soap:Envelope>
Example String Response
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<CreateCardResponse xmlns="http://tempuri.org/">
<CreateCardResult>
<RequestType>string</RequestType>
<ProductType>string</ProductType>
<ResponseCode>string</ResponseCode>
<ReasonDescription>string</ReasonDescription>
</CreateCardResult>
</CreateCardResponse>
</soap:Body>
</soap:Envelope>
Finally I'm able to access Third services.
This is my method to access service
public void createSoapActionCallBack(ValidateCardRequest validateCardRequest) {
//This is used to send header message
SoapActionCallback actionCallBack=new SoapActionCallback(soapAction);
try{
actionCallBack = new SoapActionCallback(ResponseConstants.SOAPACTION_DEFAULT_URL) {
public void doWithMessage(WebServiceMessage msg) {
SoapMessage smsg = (SoapMessage)msg;
SoapHeader soapHeader = smsg.getSoapHeader();
try{
//To send header message
StringSource headerSource = new StringSource("<UserCredentials xmlns='URL'>\n" +
"<userid>"+"ABCD"+"</userid>\n" +
"<password>"+"ABCD"+"</password>\n" +
"</UserCredentials>");
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(headerSource, soapHeader.getResult());
smsg.setSoapAction(soapAction);
}catch(Exception e)
{
e.printStackTrace();
}
}
};
validateCardResponse = (FVValidateCardResponse) webServiceTemplate.marshalSendAndReceive(URL, validateCardRequest, actionCallBack);
} catch (Exception e) {
e.printStackTrace();
}
}
This is my configuration xml file:
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="soapVersion">
<util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_12"/>
</property>
</bean>
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<!-- If we want to use contextPath then we mush create ObjectFactory class in the described Package-->
<!-- <property name="contextPath" value="com.waleteros.firstviewmodel" /> -->
<property name="classesToBeBound">
<list>
<value>com.waleteros.firstviewmodel.FVValidateCardRequest</value>
<value>com.waleteros.firstviewmodel.FVValidateCardResponse</value>
</list>
</property>
</bean>
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="messageFactory" />
<property name="marshaller" ref="marshaller"></property>
<property name="unmarshaller" ref="marshaller"></property>
<property name="messageSender">
<bean class="org.springframework.ws.transport.http.HttpComponentsMessageSender"/>
</property>
<!-- <property name="defaultUri" value="https://www.firstviewcorp.com/dbbapplications/ServicesSS/Selfservice.asmx?wsdl"/> -->
</bean>
Create pojo's according to your xmls
Here is example
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "CardUpdateResponse",namespace="http://www.corecard.com/Prepaid")
public class FVCardUpdateResponse {
#XmlElement(name="CARDUPDATE_RET", namespace="http://www.corecard.com/Prepaid")
private CARDUPDATE_RET response;
//Getters and Setters
public static class CARDUPDATE_RET{
#XmlElement(name = "ACCOUNTNUMBER", namespace="http://www.corecard.com/Prepaid")
private String AccountNumber;
#XmlElement(name = "ResCode", namespace="http://www.corecard.com/Prepaid")
private String ResCode;
#XmlElement(name = "ResErrorCode", namespace="http://www.corecard.com/Prepaid")
private String ResErrorCode;
#XmlElement(name = "ResErrorMsg", namespace="http://www.corecard.com/Prepaid")
private String ResErrorMsg;
//Getters and Setters
}
}

Spring xml in response via JAXB

I am using spring 3.1, and my application is already set up to send and receive data in json format. Now I need to provide one request API that should return the same data but in xml format.
Please help me with this stuff or tell what I am doing wrong. I tried JAXB, but instead of xml I receive "406 Not Acceptable".
My requests API:
/**
* Gets objects in json format
*/
#RequestMapping(value = "/objects/json", method = RequestMethod.GET)
#ResponseBody
public List<MyObjectTO> getAll() {
List<MyObjectTO> objectsList = new ArrayList<MyObjectTO>();
//forming objects
return objectsList;
}
/**
* Gets objects in xml format
*/
#RequestMapping(value = "/objects/xml", method = RequestMethod.GET,headers={"Accept=application/xml"})
#ResponseBody
public ResponseList getAll() {
ResponseList objectsList = new ResponseList ();
//the same formation
return objectsList;
}
Context
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.kenshoo.urlbuilder"/>
<mvc:annotation-driven/>
<mvc:view-controller path="/mainpage" view-name="mainpage"/>
<util:properties id="addProps" location="classpath:config/addProps.properties"/>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="alwaysUseFullPath" value="true"/>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="alwaysUseFullPath" value="true"/>
</bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="html" value="text/html"/>
<entry key="json" value="application/json"/>
<entry key="pdf" value="application/pdf"/>
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="cache" value="true"/>
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
</list>
</property>
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
</beans>
My changes: Added message converters to AnnotationMethodHandlerAdapter and inserted JAXB marshaller. But after this got response "406 Not Acceptable":
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="alwaysUseFullPath" value="true"/>
<property name="messageConverters">
<list>
<ref bean="marshallingConverter" />
</list>
</property>
</bean>
<bean id="marshallingConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<property name="marshaller" ref="jaxbMarshaller" />
<property name="unmarshaller" ref="jaxbMarshaller" />
<property name="supportedMediaTypes" value="application/xml"/>
</bean>
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.ResponseList</value>
</list>
</property>
</bean>
I would appreciate any help, thanks.
UPDATE
ResponseList structure:
public class ResponseList {
private List<FirstLevel> firstLevelObjects;
public List<FirstLevel> getFirstLevelObjects() {
return firstLevelObjects;
}
public void setFirstLevelObjects(List<FirstLevel> firstLevelObjects) {
this.firstLevelObjects= firstLevelObjects;
}
}
FirstLevel structure:
public class FirstLevel {
List<SecondLevel> secondLevelObjects;
boolean isConditional;
String beforeStart;
ConditionType type;//enum object
//...getters and setters
}
I lost hope with Castor, so tried once more with JAXB. Changed post
with details for JAXB. The same issues - I got Not Acceptable when
trying to request xml. Can you help me?
All you should need to do for JAXB is to add an #XmlRootElement annotation to your ResponseList class.
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class ResponseList {
private List<FirstLevel> firstLevelObjects;
public List<FirstLevel> getFirstLevelObjects() {
return firstLevelObjects;
}
public void setFirstLevelObjects(List<FirstLevel> firstLevelObjects) {
this.firstLevelObjects= firstLevelObjects;
}
}

How-to configure Spring Social via XML

I spend a few hours trying to get Twitter integration to work with Spring Social using the XML configuration approach. All the examples I could find on the web (and on stackoverflow) always use the #Config approach as shown in the samples
For whatever reason the bean definition to get an instance to the twitter API throws an AOP exception:
Caused by: java.lang.IllegalStateException: Cannot create scoped proxy for bean 'scopedTarget.twitter': Target type could not be determined at the time of proxy creation.
Here's the complete config file I have:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/DefaultDB" />
<!-- initialize DB required to store user auth tokens -->
<jdbc:initialize-database data-source="dataSource" ignore-failures="ALL">
<jdbc:script location="classpath:/org/springframework/social/connect/jdbc/JdbcUsersConnectionRepository.sql"/>
</jdbc:initialize-database>
<bean id="connectionFactoryLocator"
class="org.springframework.social.connect.support.ConnectionFactoryRegistry">
<property name="connectionFactories">
<list>
<ref bean="twitterConnectFactory" />
</list>
</property>
</bean>
<bean id="twitterConnectFactory" class="org.springframework.social.twitter.connect.TwitterConnectionFactory">
<constructor-arg value="xyz" />
<constructor-arg value="xzy" />
</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="connectionRepository" factory-method="createConnectionRepository"
factory-bean="usersConnectionRepository" scope="request">
<constructor-arg value="#{request.userPrincipal.name}" />
<aop:scoped-proxy proxy-target-class="false" />
</bean>
<bean id="twitter" factory-method="findPrimaryConnection"
factory-bean="connectionRepository" scope="request" depends-on="connectionRepository">
<constructor-arg value="org.springframework.social.twitter.api.Twitter" />
<aop:scoped-proxy proxy-target-class="false" />
</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="https://socialscn.int.netweaver.ondemand.com/socialspringdemo" />
</bean>
<bean id="signInAdapter" class="com.sap.netweaver.cloud.demo.social.SimpleSignInAdapter" />
</beans>
What puzzles me is that the connectionRepositoryinstantiation works perfectly fine (I commented-out the twitter bean and tested the code!) ?!? It uses the same features: request scope and interface AOP proxy and works, but the twitter bean instantiation fails ?!?
The spring social config code looks as follows (I can not see any differences, can you?):
#Configuration
public class SocialConfig {
#Inject
private Environment environment;
#Inject
private DataSource dataSource;
#Bean
#Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)
public ConnectionFactoryLocator connectionFactoryLocator() {
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
registry.addConnectionFactory(new TwitterConnectionFactory(environment.getProperty("twitter.consumerKey"),
environment.getProperty("twitter.consumerSecret")));
return registry;
}
#Bean
#Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)
public UsersConnectionRepository usersConnectionRepository() {
return new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator(), Encryptors.noOpText());
}
#Bean
#Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public ConnectionRepository connectionRepository() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in");
}
return usersConnectionRepository().createConnectionRepository(authentication.getName());
}
#Bean
#Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public Twitter twitter() {
Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class);
return twitter != null ? twitter.getApi() : new TwitterTemplate();
}
#Bean
public ConnectController connectController() {
ConnectController connectController = new ConnectController(connectionFactoryLocator(), connectionRepository());
connectController.addInterceptor(new PostToWallAfterConnectInterceptor());
connectController.addInterceptor(new TweetAfterConnectInterceptor());
return connectController;
}
#Bean
public ProviderSignInController providerSignInController(RequestCache requestCache) {
return new ProviderSignInController(connectionFactoryLocator(), usersConnectionRepository(), new SimpleSignInAdapter(requestCache));
}
}
Any help/pointers would be appreciated!!!
I have a configuration that worked for Spring Social Facebook integration. (I have twitter configuration in it, But I haven't tested the twitter part in it)
<bean class="org.springframework.social.connect.web.ProviderSignInController">
<!-- relies on by-type autowiring for the constructor-args -->
<constructor-arg ref="signInAdapter" />
</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.consumerKey}" />
<constructor-arg value="${twitter.consumerSecret}" />
</bean>
<bean class="org.springframework.social.facebook.connect.FacebookConnectionFactory">
<constructor-arg value="${facebook.clientId}" />
<constructor-arg value="${facebook.clientSecret}" />
</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="false" />
</bean>
<bean id="signInAdapter" class="com.test.social.SimpleSignInAdapter"/>
<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" />
I have primarily referred the documentation which is small enough to read and a tutorial which had more to do with integration with spring security. I hope this helps in some way.
I have a working xml spring-mvc/spring-social configuration for tomcat7 in
this question I posted.
This question was posted a long time ago but maybe the configuration in my post will save some people some time. It took me quite some time to set up with XML configuration and latest spring 4.2.4 MVC including
spring-social(1.1.4) and spring-social-twitter(1.1.2) twitter connection.
I write versions here, because there are quite a few things different between spring versions.

Why is HttpEntity causing an HTTP Status 415 error in Spring?

This has been bugging me for days and I'm turning to the community for help. I've been trying to access the request body and headers using the HttpEntity as suggested by the Spring 3 docs. Every time I introduce the HttpEntity as a parameter, I always get the following error:
The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().
So, this works:
#RequestMapping("/handle")
public HttpEntity<String> handle() { //
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("MyResponseHeader", "MyValue");
return new HttpEntity<String>("Hello World", responseHeaders);
}
But, this does not:
#RequestMapping("/handle")
public HttpEntity<String> handle(HttpEntity<String> requestEntity) { //
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("MyResponseHeader", "MyValue");
return new HttpEntity<String>("Hello World", responseHeaders);
}
I'm not using <mvc:annotation-driven>. I'm using good ol' <context:annotation-driven> but I've tried adding to my config as suggested here without any luck. I've also dabbled with creating a bean post processor without any luck. I think I'm running out of ideas/Google searches.
Here's my current Spring config:
<?xml version="1.0" encoding="windows-1252"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.gn" />
<tx:annotation-driven />
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:gn.properties" />
<!-- values come from resources/properties/jdbc.properties -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!--bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list>
<bean id="byteArrayMessageConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
</bean>
</util:list>
</property>
</bean-->
<!--bean id="encodingPostProcessor" class="com.glowpinion.core.postprocessor.EncodingPostProcessor" /-->
Thanks!
You need to send a POST request so that there is a body to parse into an HttpEntity.
I would also recommend using the method attribute of the RequestMapping annotation so that you can specify which HTTP methods your mapping controller method handles.
#RequestMapping(value = "/handle" method = RequestMethod.POST)
public HttpEntity<String> handle(HttpEntity<String> requestEntity) {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("MyResponseHeader", "MyValue");
return new HttpEntity<String>("Hello World", responseHeaders);
}
I believe you could also do something like this to deal with the request body as a String:
#RequestMapping(value = "/handle" method = RequestMethod.POST)
public String handle(#RequestBody String body) {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("MyResponseHeader", "MyValue");
return new HttpEntity<String>("Hello World", responseHeaders);
}
Have you tried adding the #ResponseBody annotation to your methods?

Resources