-
Notifications
You must be signed in to change notification settings - Fork 141
Spring Sample
###Introduction This is the step by step guide to show how to develop a Spring application using socialauth library. This requires the jars for socialauth-core and socialauth-spring.
###Prerequisites
Authenticating using the external oAuth providers requires that we regitser our application with the providers and obtain a key/secret from them that will be configured in our application. So following steps are needed to be set up before we can begin.
- Public domain - You will need a public domain for testing. You should have a public domain because most of the providers require a public domain to be specified when you register an application with them.
- Get the API Keys: You can get the API keys from the following URLs. * Google (show screenshot) - http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html * Yahoo (show screenshot) - https://developer.apps.yahoo.com/dashboard/createKey.html * Twitter - http://twitter.com/apps * Facebook - http://www.facebook.com/developers/apps.php * Hotmail (show screenshot) - http://msdn.microsoft.com/en-us/library/cc287659.aspx * FourSquare - (show screenshot) - https://foursquare.com/oauth/ * MySpace - (show screenshot) - http://developer.myspace.com/Apps.mvc * Linkedin - (show screenshot) - https://www.linkedin.com/secure/developer * Salesforce - (show screenshot) * Yammer - (show screenshot) - https://www.yammer.com/client_applications * Mendeley - (show screenshot) - http://dev.mendeley.com/applications/register/
- You can now develop the application using keys and secrets obtained above and deploy the application on your public domain. However, most people need to test the application on a local development machine using the API keys and secrets obtained above.
- We do not recommend it at all, but if you do not want to obtain your own keys and secrets while testing, you can use the keys and secrets that we obtained by registering "opensource.brickred.com" for our demo. Follow the same steps as above but with domain as "opensource.brickred.com" and keys from our sample.
###Development With the prerequisites out of the way, we are ready to begin development. Since Eclipse is our choice of the development environment, we have shown examples using Eclipse.
###Step 1. Create eclipse maven project
Create a maven web project in eclipse and provide groupId and artifactId. Lets say groupId is "com.threepillar.labs" and artifactId is "socialauth-spring-demo".
Directory structure will be as given below:-
###Step 2. Add following dependency in pom.xml file.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.threepillar.labs</groupId>
<artifactId>socialauth-spring-demo</artifactId>
<packaging>war</packaging>
<version>4.0</version>
<name>socialauthdemo</name>
<url>http://maven.apache.org</url>
<properties>
<org.springframework.version>3.1.2.RELEASE</org.springframework.version>
<org.slf4j.version>1.5.10</org.slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.brickred</groupId>
<artifactId>socialauth-spring</artifactId>
<version>[2.3,)</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>opensymphony</groupId>
<artifactId>sitemesh</artifactId>
<version>2.4.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1-beta-1</version>
<configuration>
<warName>socialauthdemo</warName>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>sonatype-oss-public</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
</project>
###Step 3. Web.xml file Create a web.xml file and configure the dispatcher servlet. In our case, the 'dispatcher' servlet is nothing but an instance of type 'org.springframework.web.servlet.DispatcherServlet?' and we passed the path of spring configuration file “root-context.xml” in inti-param. In this example, we map all URLs that ends with .do to dispatcher servlet.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>socialauthdemo</display-name>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<servlet>
<servlet-name>socialauthdemo-servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/root-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>socialauthdemo-servlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
###Step 4. properties.xml file This file contains key/value pair to store the application key and secret for different providers. You can copy keys from our sample
<?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: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/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- To enable @RequestMapping process on type level and method level -->
<util:properties id="socialAuthProperties">
<prop key="www.google.com.consumer_key">opensource.brickred.com</prop>
<prop key="www.google.com.consumer_secret">YC06FqhmCLWvtBg/O4W/aJfj</prop>
<prop key="api.login.yahoo.com.consumer_key">dj0yJmk9VTdaSUVTU3RrWlRzJmQ9WVdrOWNtSjZNMFpITm1VbWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD1iMA--</prop>
<prop key="api.login.yahoo.com.consumer_secret">1db3d0b897dac60e151aa9e2499fcb2a6b474546</prop>
<prop key="twitter.com.consumer_key">E3hm7J9IQbWLijpiQG7W8Q</prop>
<prop key="twitter.com.consumer_secret">SGKNuXyybt0iDdgsuzVbFHOaemV7V6pr0wKwbaT2MH0</prop>
<prop key="graph.facebook.com.consumer_key">152190004803645</prop>
<prop key="graph.facebook.com.consumer_secret">64c94bd02180b0ade85889b44b2ba7c4</prop>
<prop key="consent.live.com.consumer_key">000000004403D60E</prop>
<prop key="consent.live.com.consumer_secret">cYqlii67pTvgPD4pdB7NUVC7L4MIHCcs</prop>
<!-- <prop key="api.linkedin.com.consumer_key">9-mmqg28fpMocVuAg87exH-RXKs70yms52GSFIqkZN25S3m96kdPGBbuSxdSBIyL</prop>
<prop key="api.linkedin.com.consumer_secret">e6NBqhDYE1fX17RwYGW5vMp25Cvh7Sbw9t-zMYTIW_T5LytY5OwJ12snh_YftgE4</prop> -->
<prop key="api.linkedin.com.consumer_key">95ov9in19nvl</prop>
<prop key="api.linkedin.com.consumer_secret">CpVFHD8QATXtSpWh</prop>
<prop key="foursquare.com.consumer_key">JQKEM1PHWFW4YF2YPEQBRRESXE3SBGNCYJWWDTZKF3IZNJ3V</prop>
<prop key="foursquare.com.consumer_secret">4IILLDFDVPP2LC554S4KXKETQNTDKPDSEVCKVHA2QEHKYBEQ</prop>
<prop key="api.myspace.com.consumer_key">29db395f5ee8426bb90b1db65c91c956</prop>
<prop key="api.myspace.com.consumer_secret">0fdccc829c474e42867e16b68cda37a4c4b7b08eda574fe6a959943e3e9be709</prop>
<prop key="api.mendeley.com.consumer_key">f31077a7576d5e02537e232eb649403c04fce1dd0</prop>
<prop key="api.mendeley.com.consumer_secret">1810bc92d4625f673e4ff35cb248aab3</prop>
<prop key="www.yammer.com.consumer_key">5zyIkp12TrkulSRbSegQ</prop>
<prop key="www.yammer.com.consumer_secret">zUcCB9kqWhI1IiTAJbl9QdG2AWcUJMDWp3Qyv5VJJw</prop>
</util:properties>
</beans>
###Step 5. root-context.xml file
This is a spring configuration file for our application. This file contains the following bean definition:- 1. Import the properties.xml file. 1. Add a bean entry named "socialAuthConfig" and specify the class as "org.brickred.socialauth.SocialAuthConfig" and set property applicationProperties. This will be set in SocialAuthManager. 1. Add a bean entry named "socialAuthManager" and specify the class as "org.brickred.socialauth.SocialAuthManager" and set property socialAuthConfig. This bean is automatically injected into the "socialAuthWebController". We have the scope set to session for this manager. 1. Add a bean entry named "socialAuthTemplate" and specify the class as "org.brickred.socialauth.spring.bean.SocialAuthTemplate", which is part of socialauth-spring.jar. This bean is automatically injected into the "socialAuthWebController". On the "socialAuthTemplate" bean, we have the scope set to session. 1. Add a bean entry named "socialAuthWebController" and specify the class as "org.brickred.socialauth.spring.controller.SocialAuthWebController", which is also a part of socialauth-spring.jar. This required three arguments to pass in constructor definition. First is the application url with context, second is success page url and third one is access denied page url.
```
<context:component-scan base-package="com.threepillar.labs" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<import resource="properties.xml" />
<bean id="socialAuthConfig" class="org.brickred.socialauth.SocialAuthConfig">
<property name="applicationProperties"><ref bean="socialAuthProperties"/></property>
</bean>
<bean id="socialAuthManager" class="org.brickred.socialauth.SocialAuthManager" scope="session">
<property name="socialAuthConfig"><ref bean="socialAuthConfig"/></property>
<aop:scoped-proxy/>
</bean>
<bean id="socialAuthTemplate" class="org.brickred.socialauth.spring.bean.SocialAuthTemplate" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="socialAuthWebController" class="org.brickred.socialauth.spring.controller.SocialAuthWebController">
<constructor-arg value="http://opensource.brickred.com/socialauth-spring-demo" />
<constructor-arg value="authSuccess.do" />
<constructor-arg value="jsp/accessDenied.jsp" />
</bean>
###Step 6. Coding the index page
Now let us code the index page with the following code. In this page, we just create various icons that the user can click upon and attach them with the action that will process the authentication. Here attached action in “socialauth.do” which maps to the “org.brickred.socialauth.spring.controller.SocialAuthWebController”. ``` <title>SocialAuth Demo</title> <script> function validate(obj){ var val = obj.id.value; if(trimString(val).length <= 0){ alert("Please enter OpenID URL"); return false; }else{ return true; } } function trimString(tempStr) { return tempStr.replace(/^\s*|\s*$/g,""); } </script>
Please click on any icon. | |||||||
or enter OpenID url: |
![Index Page](images/spring_index.jpg)
##Step 7. Creating the success controller
Now we create a success action whose path is given in “SocialAuthWebController” constructor in socialauthdemo-servlet.xml. It gets the instance of the requested provider from “socialAuthTemplate” to get required information from providers like user profile, contacts etc. ``` package com.threepillar.labs.controller;
import java.util.ArrayList; import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.brickred.socialauth.AuthProvider; import org.brickred.socialauth.Contact; import org.brickred.socialauth.SocialAuthManager; import org.brickred.socialauth.spring.bean.SocialAuthTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView;
@Controller public class SuccessController {
@Autowired
private SocialAuthTemplate socialAuthTemplate;
@RequestMapping(value = "/authSuccess")
public ModelAndView getRedirectURL(final HttpServletRequest request)
throws Exception {
ModelAndView mv = new ModelAndView();
List<Contact> contactsList = new ArrayList<Contact>();
SocialAuthManager manager = socialAuthTemplate.getSocialAuthManager();
AuthProvider provider = manager.getCurrentAuthProvider();
contactsList = provider.getContactList();
if (contactsList != null && contactsList.size() > 0) {
for (Contact p : contactsList) {
if (!StringUtils.hasLength(p.getFirstName())
&& !StringUtils.hasLength(p.getLastName())) {
p.setFirstName(p.getDisplayName());
}
}
}
mv.addObject("profile", provider.getUserProfile());
mv.addObject("contacts", contactsList);
mv.setViewName("/jsp/authSuccess.jsp");
return mv;
}
}
##Step 8. Displaying the result with authSuccess.jsp
<br/>
It is the view returns by success controller. It shows the user profile and contacts. It also has update status button.
Profile Field | Value |
---|---|
Email: | |
First Name: | |
Last Name: | |
Country: | |
Language: | |
Full Name: | |
Display Name: | |
DOB: | |
Gender: | |
Location: | |
Profile Image: | |
Update status: |
Name | Profile URL | |
---|---|---|
![Success Page](images/spring_success.jpg)
###Step 9. Create the update status controller It gets the instance of the requested provider from “socialAuthTemplate” and calls the updateStatus() method and returns the view statusSuccess.jsp with the updated status success/failure message.
package com.threepillar.labs.controller;
import javax.servlet.http.HttpServletRequest;
import org.brickred.socialauth.AuthProvider;
import org.brickred.socialauth.SocialAuthManager;
import org.brickred.socialauth.exception.SocialAuthException;
import org.brickred.socialauth.spring.bean.SocialAuthTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class UpdateStatusController {
@Autowired
private SocialAuthTemplate socialAuthTemplate;
@RequestMapping(value = "/updateStatus", method = RequestMethod.POST)
public ModelAndView getRedirectURL(final HttpServletRequest request)
throws Exception {
ModelAndView mv = new ModelAndView();
SocialAuthManager manager = socialAuthTemplate.getSocialAuthManager();
AuthProvider provider = manager.getCurrentAuthProvider();
String statusMsg = request.getParameter("statusMessage");
try {
provider.updateStatus(statusMsg);
mv.addObject("Message", "Status Updated successfully");
} catch (SocialAuthException e) {
mv.addObject("Message", e.getMessage());
e.printStackTrace();
}
mv.setViewName("/jsp/statusSuccess.jsp");
return mv;
}
}
###Step 10. statusSuccess.jsp It shows the updated status success/failure message.
<%
if(request.getAttribute("Message")!=null){
out.print(request.getAttribute("Message"));
}%>
###Step 11. Create error.jsp Create error.jsp file in src\main\webapp\jsp directory.
<html>
<head>
<title>Error page</title>
</head>
<body>
<h2>Oops an error had occurred..</h2>
<br/><br/>
Go <a href="index.jsp">back</a>
</body>
</html>
###Conclusion
You can get the entire source code of the sample by browsing the source code or from socialauth-java-sdk-4.2.zip. Hope this guide would have been of help. If you have any questions, please file an issue.