Archive

Archive for July, 2013

Spring Securty 3.2 with Custom Service

user table


CREATE TABLE 'user' (
'user_id' int(11) NOT NULL AUTO_INCREMENT,
'user_name' varchar(250) NOT NULL,
'password' varchar(250) DEFAULT NULL,
PRIMARY KEY ('user_id','user_name')
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1

 

role table


CREATE TABLE 'role' (
'role_id' int(11) NOT NULL AUTO_INCREMENT,
'role_name' varchar(250) NOT NULL,
PRIMARY KEY ('role_id','role_name')
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1

user_role join table

CREATE TABLE 'user_role' (
'user_id' int(11) NOT NULL,
'role_id' int(11) NOT NULL,
PRIMARY KEY ('user_id','role_id')
) ENGINE=InnoDB DEFAULT CHARSET=latin1

user and role has many to many relationship, and joining table is user_role

User.java

package com.java2practice.springsecurity.model;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="user")
public class User {
@Id
@GeneratedValue
@Column(name="user_id")
private Integer userId;

@Column(name="user_name")
private String userName;

@Column(name="password")
private String password;

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "user_role", joinColumns = {
@JoinColumn(name = "USER_ID", nullable = false, updatable = false) },
inverseJoinColumns = { @JoinColumn(name = "ROLE_ID",
nullable = false, updatable = false) })

private Set<Role> userRoles = new HashSet<Role>(0);

public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<Role> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<Role> userRoles) {
this.userRoles = userRoles;
}
}

Role.java

package com.java2practice.springsecurity.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="role")
public class Role {
@Id
@GeneratedValue
@Column(name="role_id")
private Integer roleId;

@Column(name="role_name")
private String roleName;

public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
}

UserDao.java

package com.java2practice.springsecurity.dao;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;

import com.java2practice.springsecurity.model.User;

public class UserDao {
Logger logger = Logger.getLogger(this.getClass());

@Resource
SessionFactory sessionFactory;

public User getUser(String userName){
logger.info("getUser called");
Session session = null;
try{
session = sessionFactory.openSession();
User user = (User) session.createCriteria(User.class).
add(Restrictions.eq("userName", userName)).uniqueResult();
return user;
}catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

Our service has to implement org.springframework.security.core.userdetails.UserDetailsService
it has one method
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
this method returns org.springframework.security.core.userdetails.UserDetails
UserDetails user = new User(“username”, “password”,true, true, true, true, authorities);
like this we can convert our User to Spring UserDetails.

UserDetailsServiceImpl.java


package com.java2practice.springsecurity.service;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.java2practice.springsecurity.dao.UserDao;
import com.java2practice.springsecurity.model.Role;

@SuppressWarnings("deprecation")
public class UserDetailServiceImpl implements UserDetailsService{

Logger logger = Logger.getLogger(getClass());

@Autowired
UserDao userDao;

@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
try{
logger.info("loadUserByUsername ");

com.java2practice.springsecurity.model.User userFromDB =  userDao.getUser(username);
logger.info("got user from database "+userFromDB);
List<GrantedAuthorityImpl> authorities = new ArrayList<GrantedAuthorityImpl>();

for(Role role : userFromDB.getUserRoles()){
authorities.add(new GrantedAuthorityImpl(role.getRoleName()));
}

UserDetails user = new User(userFromDB.getUserName(), userFromDB.getPassword(),
true, true, true, true, authorities);

return user;
}catch(Exception e){
logger.error("error "+e);
return null;
}
}
}

WebController.java

package com.java2practice.springsecurity.controller;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class WebController {
Logger logger = Logger.getLogger(this.getClass());

@RequestMapping("/home")
public String home(){
logger.info("webcontroller");
return "home";
}
}

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">

<context:annotation-config />

<context:property-placeholder location="classpath:db.properties" />

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean>

<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.java2practice.springsecurity.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>

</property>
</bean>

<!-- A custom service where Spring will retrieve users and their corresponding    access levels -->
<bean id="userDetailServiceImpl"   class="com.java2practice.springsecurity.service.UserDetailServiceImpl"     autowire="byName" />

<bean id="userDao" class="com.java2practice.springsecurity.dao.UserDao" autowire="byName" />

<!-- This is where we configure Spring-Security -->
<security:http auto-config="true" use-expressions="true">

<security:form-login login-page="/login.jsp"
authentication-failure-url="/login.jsp?error=true"
default-target-url="/home.html" />

</security:http>

<!-- Declare an authentication-manager to use a custom userDetailsService -->
<security:authentication-manager>
<security:authentication-provider
user-service-ref="userDetailServiceImpl">
</security:authentication-provider>
</security:authentication-manager>

</beans>

dispatcher-servlet.xml

<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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">

<context:component-scan base-package="com.java2practice.springsecurity.controller" />
<context:annotation-config />

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>

web.xml

<?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"
id="WebApp_ID" version="2.5">
<display-name>Spring4MVC</display-name>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

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

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

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

</web-app>

login.jsp

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>

<c:if test="${param.error}">
Error occurred ${param.error }
</c:if>

</h1>
Login
<form action="j_spring_security_check" method="post">

<p>

<label for="j_username">Username</label> <input id="j_username"
name="j_username" type="text" />
</p>
<p>

<label for="j_password">Password</label> <input id="j_password"
name="j_password" type="password" />
</p>
<input type="submit" value="Login" />

</form>
</body>
</html>

home.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Home</title>
</head>
<body>

<h1>Welcome to Spring Security</h1>
</body>
</html>

Project Structure

spring_security_project_structure

Categories: Spring