Sunday, 27 July 2014

Spring Security Using MySql and JDBC

Add and configure <form-login>

Add and configure form-login in spring security configuration file.
When the user able to access the secure URL then the custom login page will be served using <form-login>

Spring-Security.xml

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

<http auto-config="true" use-expressions="true">
<intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" />
<form-login  login-page="/login"   
                                     default-target-url="/welcome" 
                                     authentication-failure-url="/login?error" 
username-parameter="j_username"     
                                     password-parameter="j_password" />
<logout logout-success-url="/login?logout"  />
<!-- enable csrf protection -->
<csrf/>
</http>
<authentication-manager>
 <authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
 users-by-username-query=
   "select username,password, enabled from users where username=?"
 authorities-by-username-query=
   "select username, role from user_roles where username =?  " />
 </authentication-provider>
</authentication-manager>
</beans:beans>

data-source-ref : Data source will be configured using data-source-ref attributes. The reference data source will refer to the Spring Context data source.

users-by-user-name-query : This attribute will take the username as the input parameter and select username, password and enable property of the user.
authorities-by-user-name-query : This attribute will take the username as the input parameter and select username and the role of the user.

web.xml

This is file is an XML document that defines everything about your application that server need to know.
Servlets, filters, listeners, initialization parameters, container-managed security constraints, resources, welcome pages, etc.

<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>Spring MVC Application</display-name>

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

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

        <!-- Loads Spring Security config file -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
    /WEB-INF/Spring-Context.xml
/WEB-INF/Spring-Security.xml
</param-value>
</context-param>

<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

springSecurityFilterChain : 

Spring Security maintains a filter chain internally where each of the filters has a particular responsibility and filters are added or removed from the configuration depending on which services are required.

DelegatingFilterProxy is used to delegate the Filter's methods to a bean which is obtained from the Spring application context.

contextConfigLocation:

We need to use the path relative to the current working directory.

We can define the context two ways.

1. First we need to define the two context files separately.

<context-param>
  <param-name>contextConfigLocation</param-name>
    <param-value>
      /WEB-INF/Spring-Context.xml
      /WEB-INF/Spring-Security.xml
    </param-value>

</context-param>

2. Second we need to define the two context files in one line.

 <context-param>
  <param-name>contextConfigLocation</param-name>
    <param-value>
      /WEB-INF/Spring-*.xml
    </param-value>
</context-param>
Custom Table Definition in MySql :

We need to create the following tables in MySql to authenticate the user.

create table users(
    username varchar(50) primary key,
    password varchar(50) not null,
    name varchar(300) not null,
    address varchar(1000),
    enabled boolean not null
) engine = InnoDb;

create table user_roles(
    role_id integer primary key,
    role varchar(50) not null,
) engine = InnoDb;

create table authority (
    username varchar(50) not null,
    role_id integer not null,
    foreign key (username) references users (username),
    foreign key (role_id) references user_roles(role_id)
) engine = InnoDb;

For creating the data base we need to execute the following insert queries.

insert into users values('admin','admin','Jency Marker','23 Street, Washington',1);
insert into user_roles values(1,'ROLE_ADMIN');
insert into authority values('admin',1);

JSP View Security

Spring Security has it's own taglibs to provide security in JSP.
To use the tag we need to include the security in JSP.

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

authorize tag :

  This tag will determine the content will evaluate or not, depending upon the user ROLE.
  sec:authorize will contain two properties access and url.

access :

The Role will be evaluated depending upon the access attribute.

<sec:authorize access="hasRole('ROLE_ADMIN')">
This content will only be visible to admin.
</sec:authorize>

url :

If the user is allowed to invoke that URL, then the tag body will be evaluated, otherwise it is skipped.

<sec:authorize url="/admin">
 This content will only be visible to admin.

</sec:authorize>

authentication tag :

    This tag allows access to the current Authentication object stored in the security context.
    This will render the property of the object directly in the JSP page.
   
     <sec:authentication  property = "authentication.username />

    This will access username property of the authentication object.

JSP

We need to create the JSP page for the custom login.

login.jsp


<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%@page session="true"%>

<html>

<head>

<title>Login Page</title>

<style>

.error {

padding: 15px;

margin-bottom: 20px;

border: 1px solid transparent;

border-radius: 4px;
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
}
.msg {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
}
#login-box {
width: 300px;
padding: 20px;
margin: 100px auto;
background: #fff;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border: 1px solid #000;
}
</style>
</head>
<body onload='document.loginForm.username.focus();'>
<h1>Spring Security Login Form (Database Authentication)</h1>
<div id="login-box">
<h3>Login with Username and Password</h3>
<c:if test="${not empty error}">
<div class="error">${error}</div>
</c:if>
<c:if test="${not empty msg}">
<div class="msg">${msg}</div>
</c:if>
<form name='loginForm'
 action="<c:url value='/j_spring_security_check' />" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='j_username'></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='j_password' /></td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit"
 value="submit" /></td>
</tr>
 </table>
 <input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>
</div>

welcome.jsp

    This JSP page will display when the login is success full.

 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@page session="true"%>
<html>
<body>
<h1>Title : ${title}</h1>
<h1>Message : ${message}</h1>
<c:url value="/j_spring_security_logout" var="logoutUrl" />
<form action="${logoutUrl}" method="post" id="logoutForm">
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>
<script>
function formSubmit() {
document.getElementById("logoutForm").submit();
}
</script>
<c:if test="${pageContext.request.userPrincipal.name != null}">
<h2>
Welcome : ${pageContext.request.userPrincipal.name} | <a
href="javascript:formSubmit()"> Logout</a>
</h2>
</c:if>

<sec:authorize access="hasRole("ROLE_ADMIN")">
       Content for admin only.
</sec:authorize>
</body>
</html>

Login Controller :

We need to configure the Login Controller depending upon the access URL and error URL.

import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class MainController {

@RequestMapping(value = "/welcome**", method = RequestMethod.GET)
public ModelAndView welcomePage() {

 ModelAndView model = new ModelAndView("welcome");
 model.addObject("message", "This page is for ROLE_ADMIN only!");
 return model;
}

@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {

 ModelAndView model = new ModelAndView("login");
 if (error != null) {
model.addObject("error", "Invalid username and password!");
 }

 if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
 }
 return model;
}
}

   
Continue to next blog...............

No comments:

Post a Comment

Spring 3 Rest Web Service Batch Update with JQuery & Ajax Integration

                      Spring 3  Rest Web Service Batch Update with JQuery & Ajax Integration Hi     In this blog I will describe the...