Breaking News

Thursday 17 April 2014

How to get the AmazonS3 client object in java

It is very important to know and understand the API's provided from AWS.

AWS has provided some API's to connect to it's S3 bucket. We will using this to get the connection to amazon s3.

Below is direct code snippet which will give the created amazon s3 client object.


public AmazonS3 getAWSClient() {
AmazonS3 s3Client = null; 
BasicAWSCredentials awsCredential = new BasicAWSCredentials(
"ACCESS KEY", "SECRET ACCESS KEY");

ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setProtocol(Protocol.HTTPS);
s3Client = new AmazonS3Client(awsCredential, clientConfig);
return s3Client;


Read more ...

Sunday 6 April 2014

How to change the project facet Dynamic web module in eclipse

Here is another post on changing the dynamic web module version inside eclipse.
This is very easy to change the version of the facet in eclipse.

The steps to change the version is as follows:

1) Right click on project and select properties



2) Click on Project Facets in properties tab. Inside project facet window there is an option  for check-box selection for Dynamic Web Module version.
  
   a) First Un-check the check-box


   b) Now change the version as per the requirement. Click on apply and Ok.



Now the project facet dynamic web module is changed to required version.
Read more ...

Saturday 5 April 2014

Spring Context Configuration for Database connection

Defining Spring context configuration for database connection

This post helps in understanding the database configuration in spring in the form of bean.
The code snippet for this configuration is as below.

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${driverClassName}" />
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
</bean>

Some of the property values are configured in properties file.

The code snippet for properties file is as below.

jdbc.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/database_name
username=admin
password=admin


Read more ...

Simple JDBC Connection in java

Simple JDBC Connection code in java

This post is to get the simple JDBC connection in java.

 // JDBC driver name and database URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/DataBase_Name";


//  Database credentials
static final String USER = "admin";
static final String PASS = "admin";
public Connection conn = null;

/**
 *   This Method will return the Database Connection
 */

public Connection getDbConnection()
{ 
    try{
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL,USER,PASS);
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch(SQLException se){
        }
return conn;
}
Read more ...

Split String depending on delimiter in java

To Split a String with delimiter condition and form an array of string

Considering a scenario where in we have read a line from csv or xls file in the form of string and need to separate the columns in array of string depending on delimiters.


 Below is the code snippet to achieve this problem..

{
...
...
String line = new BufferedReader(new FileReader("your file"));

String[] splittedString = StringSplitToArray(stringLine,"\"");

}

public static String[] StringSplitToArray(String stringToSplit, String delimiter) {
         StringBuffer token = new StringBuffer();
         Vector tokens = new Vector();
         char[] chars = stringToSplit.toCharArray();
         for (int i=0; i  0) {
                     tokens.addElement(token.toString());
                     token.setLength(0);
                     i++;
                 }
             } else {
                 token.append(chars[i]);
             }
         }<br />
         if (token.length() &gt; 0) {
             tokens.addElement(token.toString());
         }
         // convert the vector into an array
         String[] preparedArray = new String[tokens.size()];
         for (int i=0; i &lt; preparedArray.length; i++) {
             preparedArray[i] = (String)tokens.elementAt(i);
         }
         return preparedArray;
}

Above code snippet contains method call to StringSplitToArray where in the method converts the stringline into string array splitting the line depending on the delimiter specified or passed to the method. Delimiter can be comma separator(,) or double code(").
Read more ...

Read CSV File data and skip some rows from CSV file in java

To read the data from csv file need an opencsv.jar which helps in an easy way to read the csv file content which even contains data containing commas as well. Here is a simple example for reading the csv data which contains one of the columns containing comma (,)  in the data.

Our example contains csvdata.csv file data as :


Our aim is to read each row of the csv data and to skip some rows from the file.

Example to Read data from CSV File :

For reading the csv data, opencsv jar is used in the project. The project structure looks like



The project package contains two java files .

1. CsvDataForm.java -> This file contains the form field variables or the columns from the csv file.

2. CsvRead.java -> This file contains the main method which has reading columns from the csv file mapped to CsvDataForm.java

Two file looks like

CsvDataForm.java

package com.scrapillars.csv;

public class CsvDataForm {

private String Department;

private String Employee;

private String Designation;

private String Salary;

private String Address;

private String Degree;

public String getDepartment() {
return Department;
}

public void setDepartment(String department) {
Department = department;
}

public String getEmployee() {
return Employee;
}

public void setEmployee(String employee) {
Employee = employee;
}

public String getDesignation() {
return Designation;
}

public void setDesignation(String designation) {
Designation = designation;
}

public String getSalary() {
return Salary;
}

public void setSalary(String salary) {
Salary = salary;
}

public String getAddress() {
return Address;
}

public void setAddress(String address) {
Address = address;
}

public String getDegree() {
return Degree;
}

public void setDegree(String degree) {
Degree = degree;
}

}


CsvRead.java

package com.scrapillars.csv;

import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import au.com.bytecode.opencsv.CSVReader;
import au.com.bytecode.opencsv.bean.ColumnPositionMappingStrategy;
import au.com.bytecode.opencsv.bean.CsvToBean;
import com.scrapillars.csv.CsvDataForm;

public class CsvRead {

public static void main(String[] args) throws IOException {

CSVReader reader = new CSVReader(new FileReader("E:/csvdata.csv"), ',','\"', 1);

ColumnPositionMappingStrategy cpms = new ColumnPositionMappingStrategy();
cpms.setType(CsvDataForm.class);

String[] columns = new String[] { "Department", "Employee", "Designation", "Salary", "Address","Degree"};
cpms.setColumnMapping(columns);
CsvToBean csvToBean = new CsvToBean();
List csvDataList = csvToBean.parse(cpms, reader);

for (CsvDataForm csvData : csvDataList) {

System.out.println("Department : " + csvData.getDepartment()
+ "\t Employee : " + csvData.getEmployee()
+ "\t Designation : " + csvData.getDesignation()
+ "\t Salary : " + csvData.getSalary()
+ "\t Address : " + csvData.getAddress()
+ "\t Degree : " + csvData.getDegree()
);
}
}
}


Place the csvdata.csv file in any of the drive and provide the path to CSVReader. In our example csvdata.csv file is placed in 'E' drive. Change the drive name accordingly.

The Output of the CsvRead.java after run looks like :

Department : IT         Employee : JOHN        Designation : PROJECT LEAD       Salary : 10000$         Address : Texas, USA          Degree : MASTERS
Department : IT         Employee : PETER      Designation : TEAM LEAD              Salary : 8000$           Address : New York,USA   Degree : MASTERS

CSVReader from opencsv jar contains constructor which takes FileReader, comma separator argument, double code("") separator argument as to remove this separator from the data and an integer argument which tells number of rows to skip from csv file. If the requirement is to skip 2 rows while reading the data, then the value of the argument should be '2'.
Read more ...

Monday 24 March 2014

Social Media Login with Spring Application


In the good old days users logged in by using the combination of username and password. A growing number of users want to sign in by using their social media accounts.

[ Reference from : Petri Kainulainen ]

This is a what makes Spring Social (and its sub projects) an useful addition to the Spring project portfolio. However, integrating Spring Social with Spring Security has been a bit cumbersome.
Spring Social 1.1.0 changes all this. It provides seamless integration with Spring Security, and the Java configuration support of Spring Security makes the configuration feel like a walk in the park.
You don’t have to take my word for it. Keep on reading and you will learn how this is done.
The requirements of our solution are the following:
§  It must be possible to create an user account by using a normal registration form.
§  It must be possible to create an user account by using a social sign in.
§  It must be possible to login by using username and password.
§  It must be possible to login by using a SaaS API provider.
§  The application must support Facebook and Twitter.
§  The application must use “regular” Spring MVC controllers (no REST).
Let’s start by taking a look at the prerequisites of this tutorial.
Prerequisites
This tutorial assumes that you have already created the Facebook and Twitter application used by the example application. You can create these applications by following these links:
If you don’t know how to do this, you can check out the following links:
§  Facebook Developers – Creating an App Details Page (Select “website with Facebook login” when you are asked how your application integrates with FB).
§  How to Create a Twitter App in 8 Easy Steps (Enable the “allow this application to be used to Sign in with Twitter” checkbox).
Let’s move on and find out how we can get the required dependencies with Maven.
Getting the Required Dependencies with Maven
The first thing that we have to do is to get the required dependencies with Maven. We can do this by declaring the following dependencies in our POM file:
§  Spring Security (version 3.2.0.RELEASE).
§  The core module contains core authentication and and access control components.
§  The config module contains the code used to parse XML configuration files using the Spring Security XML namespace.
§  The taglibs module contains the Spring Security JPS tag libraries.
§  The web module contains filters and all other code related to web security.
§  Apache HttpClient (version 4.3.2). Apache HttpClient is an optional dependency (but recommended) dependency of Spring Social. If it is present, Spring Social will use it as a HTTP client. If not, Spring social will use the standard Java SE components.
§  Spring Social (version 1.1.0.RC1).
§  The config module contains the code used to parse XML configuration files using the Spring Social XML namespace. It also adds support for Java Configuration of Spring Social.
§  The core module contains the connect framework and provides support for OAuth clients.
§  The security module integrates Spring Security with Spring Social. It delegates the authentication concerns typically taken care by Spring Security to service providers by using Spring Social.
§  The web module contains components which handle the authentication handshake between our web application and the service provider.
§  Spring Social Facebook (version 1.1.0.RC1) is an extension to Spring Social and it provides Facebook integration.
§  Spring Social Twitter (version 1.1.0.RC1) is an extension to Social Social which provides Twitter integration.
The relevant part of the pom.xml file looks as follows:
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>

<!-- Use Apache HttpClient as HTTP Client -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.2</version>
</dependency>

<!-- Spring Social -->
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-config</artifactId>
<version>1.1.0.RC1</version>
</dependency>
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-core</artifactId>
<version>1.1.0.RC1</version>
</dependency>
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-security</artifactId>
<version>1.1.0.RC1</version>
</dependency>
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-web</artifactId>
<version>1.1.0.RC1</version>
</dependency>

<!-- Spring Social Facebook -->
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-facebook</artifactId>
<version>1.1.0.RC1</version>
</dependency>

<!-- Spring Social Twitter -->
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-twitter</artifactId>
<version>1.1.0.RC1</version>
</dependency>
Our application has other dependencies as well. For example, it uses Spring Framework 4.0.0.RELEASE, Spring Data JPA 1.4.3, and Hibernate 4.2.4.Final. These dependencies are left out from the dependency listing for the sake of clarity. You can get the full list of dependencies from Github.
You might also want to read the following documents which give you more information about the dependencies of the frameworks discussed in this blog post (Spring Security and Spring Social):
Next we have to create a properties file for the configuration properties of our application. Let’s find out how this is done.
Creating the Properties File
We can create the properties file by following these steps:
1.    Create a file called application.properties and ensure that it is found from the classpath.
2.    Configure the database connection.
3.    Configure Hibernate.
4.    Add the Facebook application id and application secret to the properties file.
5.    Add the Twitter consumer key and consumer secret to the properties file.
The contents of the application.properties file looks as follows:
#Database Configuration
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/socialtwitter
db.username=socialtwitter
db.password=password

#Hibernate Configuration
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.format_sql=true
hibernate.hbm2ddl.auto=validate
hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
hibernate.show_sql=false

#Facebook
facebook.app.id=foo
facebook.app.secret=bar

#Twitter
twitter.consumer.key=foo
twitter.consumer.secret=bar
Before we can configure our application, we have to create a few common components. Let’s find out what these components are, and how we can create them.
Creating the Common Components
We have to create three components which are used during the authentication process. These components are:
§  We have create a class which contains the user details of an authenticated user.
§  We have to create a class which implements the UserDetailsService interface. This class is used to load user information when the user uses form login.
§  We have to create a class which implements the SocialUserDetailsService interface. This class is used to load user information when the user uses social sign in.
Let’s move on and find out how we can implement these classes.
Creating the User Details Class
We have to take the following requirements into account when we are creating the class which contains the user details of the authenticated user:
§  The class which stores the user details of a user who uses form login must implement the UserDetailsinterface.
§  The class which stores the user details of a user who uses social sign in must implement theSocialUserDetails interface.
Spring Social has a SocialUser class which fulfils both of these requirements. However, often we want to add application specific information to our user details class.
We can do this by following these steps:
1.    Create the user details class.
2.    Extend the SocialUser class.
3.    Add application specific fields to the created class. The application specific fields of our example application are: idfirstNamelastNamerole, and socialSignInProvider.
4.    Create a constructor which takes the username, password and a collection of granted authorities as parameters. Pass these parameters forward to the constructor of the SocialUser class.
5.    Create getters for application specific fields.
6.    Add an inner builder class which is used to build new ExampleUserDetails objects.
The source code of our user details class looks as follows:
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.social.security.SocialUser;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class ExampleUserDetails extends SocialUser {

private Long id;

private String firstName;

private String lastName;

private Role role;

private SocialMediaService socialSignInProvider;

public ExampleUserDetails(String username, String password, Collection<? extends GrantedAuthority> authorities) {
super(username, password, authorities);
}

//Getters are omitted for the sake of clarity.

public static class Builder {

private Long id;

private String username;

private String firstName;

private String lastName;

private String password;

private Role role;

private SocialMediaService socialSignInProvider;

private Set<GrantedAuthority> authorities;

public Builder() {
this.authorities = new HashSet<>();
}

public Builder firstName(String firstName) {
this.firstName = firstName;
return this;
}

public Builder id(Long id) {
this.id = id;
return this;
}

public Builder lastName(String lastName) {
this.lastName = lastName;
return this;
}

public Builder password(String password) {
if (password == null) {
password = "SocialUser";
}

this.password = password;
return this;
}

public Builder role(Role role) {
this.role = role;

SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role.toString());
this.authorities.add(authority);

return this;
}

public Builder socialSignInProvider(SocialMediaService socialSignInProvider) {
this.socialSignInProvider = socialSignInProvider;
return this;
}

public Builder username(String username) {
this.username = username;
return this;
}

public ExampleUserDetails build() {
ExampleUserDetails user = new ExampleUserDetails(username, password, authorities);

user.id = id;
user.firstName = firstName;
user.lastName = lastName;
user.role = role;
user.socialSignInProvider = socialSignInProvider;

return user;
}
}
}
The Role is a simple enum which specifies the “legal” user roles of our example application. Its source code looks as follows:
public enum Role {
ROLE_USER
}
The SocialMediaService is an enum which identifies the SaaS API provider which was used when user created an user account to our example application. Its source code looks as follows:
public enum SocialMediaService {
FACEBOOK,
TWITTER
}
Implementing the UserDetailsService interface
We can create our own implementation of the UserDetailsService interface by following these steps:
1.    Create a class which implements the UserDetailsService interface.
2.    Add a UserRepository field to created class.
3.    Create a constructor which takes a UserRepository as a constructor argument and annotate the constructor with the @Autowired annotation.
4.    Implement the loadUserByUsername(String username) method of the UserDetailsService interface. The implementation of this method consists of following steps:
1.    Get the user by calling the findByEmail() method of the UserRepository interface. This method returns the user whose email matches with the username given as a method parameter.
2.    If the user is not found, throw a new UsernameNotFoundException.
3.    Create a new ExampleUserDetails object.
4.    Return the created object.
The source code of the RepositoryUserDetailsService class looks as follows:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class RepositoryUserDetailsService implements UserDetailsService {

private UserRepository repository;

@Autowired
public RepositoryUserDetailsService(UserRepository repository) {
this.repository = repository;
}

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = repository.findByEmail(username);

if (user == null) {
throw new UsernameNotFoundException("No user found with username: " + username);
}

ExampleUserDetails principal = ExampleUserDetails.getBuilder()
.firstName(user.getFirstName())
.id(user.getId())
.lastName(user.getLastName())
.password(user.getPassword())
.role(user.getRole())
.socialSignInProvider(user.getSignInProvider())
.username(user.getEmail())
.build();

return principal;
}
}
The UserRepository is a simple Spring Data JPA repository, and its source code looks as follows:
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {

public User findByEmail(String email);
}
The User is the only entity of our example application, and it contains the information of a user who has created user account to our example application. The relevant part of its source code looks as follows:
import javax.persistence.*;

@Entity
@Table(name = "user_accounts")
public class User extends BaseEntity<Long> {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "email", length = 100, nullable = false, unique = true)
private String email;

@Column(name = "first_name", length = 100,nullable = false)
private String firstName;

@Column(name = "last_name", length = 100, nullable = false)
private String lastName;

@Column(name = "password", length = 255)
private String password;

@Enumerated(EnumType.STRING)
@Column(name = "role", length = 20, nullable = false)
private Role role;

@Enumerated(EnumType.STRING)
@Column(name = "sign_in_provider", length = 20)
private SocialMediaService signInProvider;

public User() {

}

//Getters and other methods are omitted for the sake of clarity.
}
Implementing the SocialUserDetailsService interface
We can implement the SocialUserDetailsService interface by following these steps:
1.    Create a class which implements the SocialUserDetailsService.
2.    Add a UserDetailsService field to the created class.
3.    Create a constructor which takes a UserDetailsService object as a constructor parameter, and annotate the constructor with the @Autowired annotation.
4.    Implement the loadUserByUserId(String userId) method of the SocialUserDetailsInterface.
5.    Get the correct UserDetails object by calling the loadUserByUsername() method and pass the user id as a method parameter. We can do this because our application uses the username of the user as the user id.
6.    Cast the returned object to SocialUserDetails object and return it.
The source code of the SimpleSocialUserDetailsService class looks as follows:
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.social.security.SocialUser;
import org.springframework.social.security.SocialUserDetails;
import org.springframework.social.security.SocialUserDetailsService;


public class SimpleSocialUserDetailsService implements SocialUserDetailsService {

private UserDetailsService userDetailsService;

public SimpleSocialUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}

@Override
public SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException, DataAccessException {
UserDetails userDetails = userDetailsService.loadUserByUsername(userId);
return (SocialUserDetails) userDetails;
}
}
That is all. We are now ready to configure the application context of our application. Let’s find out how we can do that.
Configuring the Application Context
This section describes how we can configure the application context of our example application by using Java configuration. The application context configuration has been divided into multiple configuration classes by following these guidelines:
1.    Each configuration class contains configuration which is associated with a specific part of our example application. This make it easy to find out the relevant configuration if we have to check something out or change something a few months (or years) after we created the initial configuration.
2.    The configuration has been divided in a way which makes it easy to write unit tests for the web layer by using Spring MVC Test. We will talk more about this in the third part of this tutorial where we will write unit tests for the web layer of our application.
3.    The configuration makes it easy remove dependencies to external resources when we are writing integration tests for our application. We will talk more about this in the fourth part of this tutorial which describes how we can write integration tests for our application.
If you want to use XML configuration, you can take look at the example application of this blog post which has a working XML configuration as well (no web.xml though).
Let’s start by configuring the persistence layer of our application.
Configuring the Persistence Layer
The persistence layer of our application stores the user account information and provides a way to access this information. This important for two reasons:
§  We can provide a way to sign in by using username and password.
§  We can store application specific information and link this information to the user who uses social sign in.
Let’s find out how we can configure it by using both Java configuration class.
The persistence layer of example application uses Spring Data JPA 1.3.4. I will keep this section as thin as possible. If you want to learn more about Spring Data JPA, you can read my Spring Data JPA tutorial. I have also written a book about Spring Data which should help you to get started in no time.
We can configure our persistence layer by following these steps:
1.    Create the configuration class and annotate the created class with the @Configuration annotation.
2.    Annotate the class with the @EnableJpaRepositories annotation and set the base package of our Spring Data JPA repositories.
3.    Enable the Spring transaction management by annotating the configuration class with the@EnableTransactionManagement annotation.
4.    Add an Environment field to the class and annotate the field with the @Autowired annotation. We don’t need to configure the properties file by using the @PropertySource annotation because it is already configured in the “parent” application context configuration class.
5.    Configure the data source bean. This bean provides database connections to the entity manager but it has also another purpose. It is used by Spring Social when it persists connections to the database and loads them from the database.
6.    Configure the transaction manager bean.
7.    Configure the entity manager factory bean.
The source code of the PersistenceContext class looks as follows:


import com.jolbox.bonecp.BoneCPDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableJpaRepositories(basePackages = {
"net.petrikainulainen.spring.social.signinmvc.user.repository"
})
@EnableTransactionManagement
public class PersistenceContext {

@Resource
private Environment env;

@Bean
public DataSource dataSource() {
BoneCPDataSource dataSource = new BoneCPDataSource();

dataSource.setDriverClass(env.getRequiredProperty("db.driver"));
dataSource.setJdbcUrl(env.getRequiredProperty("db.url"));
dataSource.setUsername(env.getRequiredProperty("db.username"));
dataSource.setPassword(env.getRequiredProperty("db.password"));

return dataSource;
}

@Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();

entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManagerFactoryBean.setPackagesToScan({
"net.petrikainulainen.spring.social.signinmvc.common.model",
"net.petrikainulainen.spring.social.signinmvc.user.model"
});

Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.dialect", env.getRequiredProperty("hibernate.dialect"));
jpaProperties.put("hibernate.format_sql", env.getRequiredProperty("hibernate.format_sql"));
jpaProperties.put("hibernate.hbm2ddl.auto", env.getRequiredProperty("hibernate.hbm2ddl.auto"));
jpaProperties.put("hibernate.ejb.naming_strategy", env.getRequiredProperty("hibernate.ejb.naming_strategy"));
jpaProperties.put("hibernate.show_sql", env.getRequiredProperty("hibernate.show_sql"));

entityManagerFactoryBean.setJpaProperties(jpaProperties);

return entityManagerFactoryBean;
}
}


Let’s move on and find out how we can create the security configuration for our application.
Configuring Spring Security
Spring Security provides authentication mechanism for users who uses either form login or social sign in, and it is also responsible of authorization.
We can configure Spring Security by following these steps:
1.    Create the configuration class and annotate the created class with the @Configuration annotation.
2.    Annotate the class with the @EnableWebSecurity annotation. This makes it possible to configure Spring Security by implementing the WebSecurityConfigurer interface.
3.    Ensure that our configuration class extends the WebSecurityConfigurerAdapter class which is a base class for creating WebSecurityConfigurer instances. After we have done this, we can customize the security configuration by overriding methods.
4.    Add an UserRepository field to the configuration and annotate the field with the @Autowiredannotation.
5.    Override the configure(WebSecurity web) method of the WebSecurityConfigurerAdapter class. Ensure that Spring Security ignores requests made to static resources such as CSS and Javascript files.
6.    Override the configure(HttpSecurity http) method of the WebSecurityConfigurerAdapter class and implement it by following these steps:
1.    Configure form login by following these steps:
1.    Set the login page url to ‘/login’.
2.    Set the url which processes login form submissions to ‘/login/authenticate’.
3.    Set the login failure url to ‘/login?error=bad_credentials’.
2.    Configure the logout function by following these steps:
1.    Ensure that a cookie called JSESSIONID is deleted after logout.
2.    Set the logout url to ‘/logout’.
3.    Set the logout success url to ‘/login’.
3.    Configure url based authorization. The main point of this phase is to ensure that anonymous users can access all urls which are related to the sign in / registration process, and protect the rest of our application from anonymous users.
4.    Add the SocialAuthenticationFilter to the Spring Security filter chain. We can do this by creating a new SpringSocialConfigurer object and ensuring that this object is used when Spring Security is configured.
7.    Configure the PasswordEncoder bean which is used to hash the password of the user (if the user uses form registration and login). We can do this by creating a new BCryptPasswordEncoder object and returning the created object.
8.    Configure the UserDetailsService bean. We can do this by creating a newRepositoryUserDetailsService object and passing the UserRepository as a constructor argument.
9.    Override the configure(AuthenticationManagerBuilder auth) method of theWebSecurityConfigurerAdapter class. We use this method for configuring authentication requests if the user uses form login. Implement this method by following these steps:
1.    Pass the UserDetailsService bean to the AuthenticationManagerBuilder object given as a method parameter.
2.    Pass the PasswordEncoder bean to the AuthenticationManagerBuilder object given as a method parameter.
10. Configure the SocialUserDetailsService bean. We can do this by creating a newSimpleSocialUserDetailsService object and passing the UserDetailsService bean as a constructor argument. This bean loads the user specific data when social sign in is used.
The source code of our application context configuration class looks as follows:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.social.security.SocialUserDetailsService;
import org.springframework.social.security.SpringSocialConfigurer;

@Configuration
@EnableWebSecurity
public class SecurityContext extends WebSecurityConfigurerAdapter {

@Autowired
private UserRepository userRepository;

@Override
public void configure(WebSecurity web) throws Exception {
web
//Spring Security ignores request to static resources such as CSS or JS files.
.ignoring()
.antMatchers("/static/**");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
//Configures form login
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login/authenticate")
.failureUrl("/login?error=bad_credentials")
//Configures the logout function
.and()
.logout()
.deleteCookies("JSESSIONID")
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
//Configures url based authorization
.and()
.authorizeRequests()
//Anyone can access the urls
.antMatchers(
"/auth/**",
"/login",
"/signin/**",
"/signup/**",
"/user/register/**"
).permitAll()
//The rest of the our application is protected.
.antMatchers("/**").hasRole("USER")
//Adds the SocialAuthenticationFilter to Spring Security's filter chain.
.and()
.apply(new SpringSocialConfigurer());
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder());
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(10);
}

@Bean
public SocialUserDetailsService socialUserDetailsService() {
return new SimpleSocialUserDetailsService(userDetailsService());
}

@Bean
public UserDetailsService userDetailsService() {
return new RepositoryUserDetailsService(userRepository);
}
}

Let’s move on and find out how we can configure Spring Social.
Configuring Spring Social
Spring Social provides integrations with SaaS API providers such as Facebook and Twitter. We can configure Spring Social by following these steps:
1.    Create the application context configuration class which implements the SocialConfigurer interface and annotate the created class with the @Configuration annotation. The SocialConfigurer interface declares callback methods which can be used to configure Spring Social.
2.    Annotate the class with the @EnableSocial annotation. This enables Spring Social and imports theSocialConfiguration configuration class.
3.    Add a DataSource field to the configuration class and annotate the field with the @Autowiredannotation.
4.    Add the addConnectionFactories() method of the SocialConfigurer interface to the created configuration class. This method takes two method parameters which are described in the following:
1.    The first parameter is a ConnectionFactoryConfigurer object which can be used to register connection factories.
2.    The second parameter is an Environment object which represents the environment in which our example application is running.
5.    Implement the addConnectionFactories() method by following these steps:
1.    Create a new TwitterConnectionFactory object, and pass the consumer key and the consumer secret as constructor arguments.
2.    Register the created TwitterConnectionFactory object by calling the addConnectionFactory()method of the ConnectionFactoryConfigurer interface. Pass the createdTwitterConnectionFactory object as a method parameter.
3.    Create a new FacebookConnectionFactory object, and pass the application id and the application secret as constructor arguments.
4.    Register the created FacebookConnectionFactory object by calling the addConnectionFactorymethod of the ConnectionFactoryConfigurer interface. Pass the createdFacebookConnectionFactory object as a method parameter.
6.    Add the getUserIdSource() method of the SocialConfigurer interface to the created class. TheUserIdSource object returned by this method is responsible of determining the correct account id of the user. Because our example application uses the username of the user as an account id, we have to implement this method by returning a new AuthenticationNameUserIdSource object.
7.    Add the getUsersConnectionRepository() method of the SocialConfigurer interface to the created class. This method takes a ConnectionFactoryLocator object as a method parameter and returns aUsersConnectionRepository object.
8.    Implement the getUsersConnectionRepository() method by following these steps:
1.    Create a new JdbcUsersConnectionRepository object and pass the following objects as constructor arguments:
1.    The first argument is a DataSource object. We pass the value of the dataSource field as the first method parameter.
2.    The second argument is a ConnectionFactoryLocator object. We pass the value of theconnectionFactoryLocator method parameter as the second method parameter.
3.    The third parameter is a TextEncryptor object which encrypts the authorization details of the connection established between a SaaS API provider and our application. We create this object by calling the noOpText() method of the Encryptors class. This means that our example application stores these details as plaintext. This is handy during the development phase butwe should not use it in production.
2.    Return the created object.
9.    Configure the ConnectController bean. The method which configures this bean has two parameters. The first parameter is the ConnectionFactoryLocator bean. The second parameter is the usedConnectionRepository bean. Pass these parameters as constructor arguments when you are creating a new ConnectController object.
The source code of our configuration class looks as follows:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.social.UserIdSource;
import org.springframework.social.config.annotation.ConnectionFactoryConfigurer;
import org.springframework.social.config.annotation.EnableSocial;
import org.springframework.social.config.annotation.SocialConfigurer;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.ConnectionRepository;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository;
import org.springframework.social.connect.web.ConnectController;
import org.springframework.social.facebook.connect.FacebookConnectionFactory;
import org.springframework.social.security.AuthenticationNameUserIdSource;
import org.springframework.social.twitter.connect.TwitterConnectionFactory;

import javax.sql.DataSource;

@Configuration
@EnableSocial
public class SocialContext implements SocialConfigurer {

@Autowired
private DataSource dataSource;

@Override
public void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) {
cfConfig.addConnectionFactory(new TwitterConnectionFactory(
env.getProperty("twitter.consumer.key"),
env.getProperty("twitter.consumer.secret")
));
cfConfig.addConnectionFactory(new FacebookConnectionFactory(
env.getProperty("facebook.app.id"),
env.getProperty("facebook.app.secret")
));
}

@Override
public UserIdSource getUserIdSource() {
return new AuthenticationNameUserIdSource();
}

@Override
public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
return new JdbcUsersConnectionRepository(
dataSource,
connectionFactoryLocator,
Encryptors.noOpText()
);
}

@Bean
public ConnectController connectController(ConnectionFactoryLocator connectionFactoryLocator, ConnectionRepository connectionRepository) {
return new ConnectController(connectionFactoryLocator, connectionRepository);
}
}

Our next step is to configure the web layer of our application. Let’s get to work.
Configuring the Web Layer
We can configure the web layer of our application by following these steps:
1.    Create the configuration class by following these steps:
1.    Extend the WebMvcConfigurerAdapter class.
2.    Annotate the created class with the @Configuration annotation.
2.    Ensure that all controller classes are found by annotating the class with the @ComponentScanannotation and setting the base packages of our controllers.
3.    Enable the annotation driven web mvc by annotating the class with the @EnableWebMvc annotation.
4.    Ensure that static resources are served by container’s default servlet.
1.    Configure the static resources by overriding the addResourceHandlers() method of theWebMvcConfigurerAdapter class.
2.    Ensure that requests made to static resources are delegated forward to the container’s default servlet. This is done by overriding the configureDefaultServletHandling() method of theWebMvcConfigurerAdapter class.
5.    Configure the exception resolver bean.
6.    Configure the ViewResolver bean.
The source code of the WebAppContext class looks as follows:


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import java.util.Properties;

@Configuration
@ComponentScan(basePackages = {
"net.petrikainulainen.spring.social.signinmvc.common.controller",
"net.petrikainulainen.spring.social.signinmvc.security.controller",
"net.petrikainulainen.spring.social.signinmvc.user.controller"
})
@EnableWebMvc
public class WebAppContext extends WebMvcConfigurerAdapter {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}

@Bean
public SimpleMappingExceptionResolver exceptionResolver() {
SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();

Properties exceptionMappings = new Properties();

exceptionMappings.put("java.lang.Exception", "error/error");
exceptionMappings.put("java.lang.RuntimeException", "error/error");

exceptionResolver.setExceptionMappings(exceptionMappings);

Properties statusCodes = new Properties();

statusCodes.put("error/404", "404");
statusCodes.put("error/error", "500");

exceptionResolver.setStatusCodes(statusCodes);

return exceptionResolver;
}

@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");

return viewResolver;
}
}

Let’s find out how we can tie this all together and create a “parent” application context configuration class for our application.
Tieing It All Together
The last application context configuration class has three responsibilities:
1.    It configures general components used throughout our example application.
2.    It ensures that the service classes of our application are found during the classpath scan.
3.    It is the root application context configuration class of our application.
We can create this configuration class by following these steps:
1.    Create the configuration class and annotate the created class with the @Configuration annotation.
2.    Ensure that our service classes are found during the component scan by annotating the class with@ComponentScan annotation and setting the base package of our services.
3.    Import the other application context configuration classes by annotating the class with the @Importannotation.
4.    Annotate the class with the @PropertySource annotation, and configure it to look for a properties file called application.properties from the classpath. This ensures that the configuration properties can be accessed in the imported application context configuration classes.
5.    Configure the MessageSource bean.
6.    Configure the PropertySourcesPlaceholderConfigurer bean.
The source code the ExampleApplicationContext class looks as follows:

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.context.support.ResourceBundleMessageSource;

@Configuration
@ComponentScan(basePackages = {
"net.petrikainulainen.spring.social.signinmvc.user.service"
})
@Import({WebAppContext.class, PersistenceContext.class, SecurityContext.class, SocialContext.class})
@PropertySource("classpath:application.properties")
public class ExampleApplicationContext {

@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();

messageSource.setBasename("i18n/messages");
messageSource.setUseCodeAsDefaultMessage(true);

return messageSource;
}

@Bean
public PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}

We have now configured the application context of our example application. However, we still have to configure our web application. Let’s see how we can do this by using Java configuration.
Configuring the Web Application
Our last step is to configure our example application. We can do this without web.xml as long as our application is deployed to a servlet 3.0 compliant container.
We can configure the web application by following these steps:
1.    Create a class which implements the WebApplicationInitializer interface.
2.    Configure our application by overriding the onStartup() method of the WebApplicationInitializerinterface. We can implement this method by following these steps:
1.    Create the root context of the application and register the ExampleApplicationContext class to the created root context.
2.    Configure the dispatcher servlet.
3.    Configure character encoding filter.
4.    Configure the Spring Security filter chain.
5.    Configure Sitemesh.
6.    Add the context loader listener to the servlet context.
The source code of the ExampleApplicationConfig class looks as follows:

import org.sitemesh.config.ConfigurableSiteMeshFilter;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.*;
import java.util.EnumSet;

public class ExampleApplicationConfig implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(ExampleApplicationContext.class);

ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");

EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD);

CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);

FilterRegistration.Dynamic characterEncoding = servletContext.addFilter("characterEncoding", characterEncodingFilter);
characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*");

FilterRegistration.Dynamic security = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
security.addMappingForUrlPatterns(dispatcherTypes, true, "/*");

FilterRegistration.Dynamic sitemesh = servletContext.addFilter("sitemesh", new ConfigurableSiteMeshFilter());
sitemesh.addMappingForUrlPatterns(dispatcherTypes, true, "*.jsp");

servletContext.addListener(new ContextLoaderListener(rootContext));
}
}

[ Reference from : Petri Kainulainen ]
Read more ...
Designed By