Sunday, 27 July 2014

Spring Security for Redirecting to Multiple Views

                                            Spring Security for Redirecting to Multiple Views

We need to direct to different pages based upon the different users after login success.

For admin pages we need to redirect to admin.jsp after login success based upon the access ROLE_ADMIN.

For user pages we need to redirect to user.jsp after login success based upon the access ROLE_USER.

Spring security Authentication success handler is used to decide what to do after success full authentication.

DB Schema :

Create tables in the database. Two tables user and role need to be created.

Table structure for `tbl_users`
-- ----------------------------
DROP TABLE IF EXISTS `tbl_users`;
CREATE TABLE `tbl_users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) NOT NULL,
  `password` varchar(20) NOT NULL,
  `enabled` int(1) NOT NULL,
  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Table structure for `tbl_user_role`
-- ----------------------------
DROP TABLE IF EXISTS `tbl_user_role`;
CREATE TABLE `tbl_user_role` (
  `userid` int(11) NOT NULL,
  `rolename` varchar(100) NOT NULL

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Role table contains the roles of the particular user.
User table contains the detail information about the user.

Spring-security.xml

<http auto-config="true">
 <intercept-url pattern="/admin**" access="ROLE_ADMIN" />
 <intercept-url pattern="/admin**" access="ROLE_USER" />
 <form-login 
login-page="/login" 
       default-target-url="/welcome" 
authentication-failure-url="/login?error" 
username-parameter="j_username"
password-parameter="j_password" 
authentication-success-handler-ref="myAuthenticationSuccessHandler"/>
 <logout logout-success-url="/login?logout" />
 <!-- enable csrf protection -->
 <csrf/>
</http>

<authentication-manager>
 <authentication-provider>

           <!-- Select user and user_role from database -->

   <jdbc-user-service  data-source-ref="dataSource">
users-by-username-query="select username, password, enabled from tbl_users where username=?"
authorities-by-username-query="select u.username, r.rolename from tbl_users u, tbl_user_role r where u.id=r.userid and u.username=?"/>
 </authentication-provider>
</authentication-manager>
</http>
<beans:bean id="myAuthenticationSuccessHandler"

        class="com.sreemandira.satya.CustomAuthenticationSuccessHandler " /> 

JDBC user service implementation provides two attributes to match username with password and then username with granted role or authority.

1.  users-by-username-query

2.  authorities-by-username-query

authentication-success-handler-ref : This will be called after success full authentication. AuthenticationSuccessHandler interface will be called for creating custom authentication.

AuthenticationSuccessHandler will be used to provide  custom implementation of success handler.

Depending upon the ROLE of the user we need to redirect to different URL.


CustomAuthenticationSuccessHandler :

public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    protected Log logger = LogFactory.getLog(this.getClass());

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
       boolean isUser = false;
        boolean isAdmin = false;

        // Access the user role after success full login
      
  User authUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        HttpSession session = httpServletRequest.getSession();  
        session.setAttribute("username", authUser.getUsername());  
        session.setAttribute("authorities", authentication.getAuthorities()); 

       //  Set response OK.

       response.setStatus(HttpServletResponse.SC_OK);

     //   Redirect the user based upon the user ROLE.

        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        for (GrantedAuthority grantedAuthority : authorities) {
            if (grantedAuthority.getAuthority().equals("ROLE_USER")) {
                isUser = true;
                break;
            } else if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) {
                isAdmin = true;
                break;
            }.
        }

        if (isUser) {
            return "/home.html";
        } else if (isAdmin) {
            return "/admin.html";
        } else {
            throw new IllegalStateException(); 
        }
    }
    }

}


SecurityContextHolder:

    This is the location where we store the present security context of the application, which includes the details of the principal currently using the application. Security Context will use the Thread Local to store these Details. So, Security Context will always available to the methods in the same thread of execution. Even if Security Context will not be passed as an  argument to the method.

Security Context will store the details of the principal currently using the application. Spring security uses Authentication to represent these information.

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof UserDetails) {
  String username = ((UserDetails)principal).getUsername();
} else {
  String username = principal.toString();
}

Authentication

  Authentication will represent a token for an authenticated  principal once the request has been processed by authenticate method of AuthenticationManager.

Once the request has been authenticated the authentication will be stored in the Thread Local of the Security Context managed by SecurityContextHolder.

Principal :

 Principal  will represent an entity, individual or a login id.

Granted Authority : 

Granted Authority is the permission or right. Permissions are expressed as Strings.

We can grant different Granted Authorities to the users by putting them to the security context.

Roles are just "permissions" with a naming convention  that a role is a GrantedAuthority that starts with the prefix ROLE_.

Granted Authority will check the ROLE and redirect to appropriate target URL based on the ROLE.

Admin user will determine the ROLE_ADMIN authority and redirect to admin page.

Home user will  determine the ROLE_USER authority and redirect to home page.




Spring Security Using MySql and JDBC

                                        Spring Security Using MySql and JDBC

Finally we need to configure Data Source in spring-context.xml file.

We need to configure Data Source using property driverClass, url, username and password.

We need to use spring's BasicDataSource for connecting to MySql Database.

Spring-Context.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
               http://www.springframework.org/schema/beans/spring-beans.xsd">

 <bean id="props" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations" value="classpath:prop/jdbc.properties"/>
</bean>

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

</beans>

driverClass : Driver class is used to communicate to MySql database.
url :  Location of the database in MySql server.
username : username credentials to communicate with MySql  database.
password :  password credentials to communicate with MySql  database.

jdbc.properties

In  Properties file we need to configure the key value for driverClass, url, username and password.

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/login
jdbc.username=root
jdbc.password=root123

In spring config file the string ${jdbc.username} is replaced at runtime with the value "root". All the properties for placeholders  are replaced at the runtime based on the matched key in the properties file.




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...............

Spring Security Using MySql and JDBC

                                         Spring  Security

Spring Security provides a comprehensive security solution for J2EE-based enterprise software applications.

As J2EE Servlet specification or EJB specification will lack the depth required for typical enterprise application and are not portable to EAR and WAR level. So after switching to the server environment we need to reconfigure our application's security in new target environment.

Spring  security is a powerful and highly customizable authentication and access control framework.

Features

Comprehensive and extensible support for both Authentication and Authorization.

Protection against attack like session fixation, click jacking,  cross site request etc.
Servlet  API integration.


Optional integration with Spring Web MVC.

Using Spring Security we will overcome all of these problems using customization security features.

Two major area of the Spring Security are  Authentication and Authorization.

Authentication

Authentication  is the process of establishing a principal is who they claim to be (user/ device/other system) can perform an action in your application.

Authorization

Authorization refers to the process of deciding whether a principal is allowed to perform an action within your application.

At an authentication level, Spring Security supports a wide range of authentication models. Most of these authentication models are either provided by third parties.

We can download the Spring security from Spring security site. Download the individual jars from the maven central repository. (http://projects.spring.io/spring-security/)

Maven Setup
  
A minimal Spring Security Maven set of dependencies for spring security project.


<dependencies>
  <!-- ... other dependency elements ... -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>3.2.4.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>3.2.4.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>3.2.4.RELEASE</version>
  </dependency>
 <dependency>

    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglib</artifactId>
    <version>3.2.4.RELEASE</version>
  </dependency>

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-ldap</artifactId>
    <version>3.2.4.RELEASE</version>
  </dependency>
 <dependency>

    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-acls</artifactId>
    <version>3.2.4.RELEASE</version>
  </dependency>

</dependencies>

Spring security core jar contains the core authentication and access control classes and interfaces, remoting support and API'S.

Spring security web will contain the filters and related web-security infrastructure code. This is used for spring security web and URL based access control

Spring security config is used for XML namespace configuration.

Spring security taglib is used to provide authentication in UI components.(JSP Page).

For LDAP we need to use LDAP authentication or LDAP user entities. We need to use org.springframework.security.ldap jar in the pom dependency.

 ACL implementation is used to apply the security to the domain object instances with in your application.  We need to use org.springframework.security.acls jar in pom dependency.

Namespace Configuration web.xml

web.xml file provides  a hook into spring security web infrastructure.

DelegatingFilterProxy is a spring spring framework class which delegates  to SpringSecurityFilterChain  defined as a spring bean in the application context.

SpringSecurityFilterChain is the internal infrastructure bean created by the namespace to handle web security.

Once we added to our web.xml file we can able to edit the application context XML file.(Adding http element).

web.xml 
<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>

Namespace Configuration Spring-Context.xml

Namespace configuration for Spring Context contains Minimal <http> configuration, Using Authentication Provider and Adding password Encoder.

<http> configuration provides support for accessing URL's and redirecting to appropriate view.
Authentication Provider will validate the user credentials  for the specific logged in user.
Password Encoder will encode the password using hash algorithm.

http Configuration
The http element is responsible for creating the FilterChainProxy and the Filter bean which it uses.
It also allows incorrect filter ordering as the filter positions are already predefined.
http element is the parent of all web related namespace  functionality.

The <intercept-url> element defines a pattern which is matched against the URLs(pattern) of incoming requests using an ant path style syntax.

The access attribute defines the access requirements for requests matching the given pattern.
Access is the comma separated list of roles and one of the role will make the request.

We can use multiple <intercept-url> elements to define different access requirements for different sets of URLs, but they will be evaluated in the order listed and the first match will be used.

<sec:http auto-config="true">
    <sec:intercept-url pattern="/foo/**" access="ROLE_BASIC" />
</sec:http>

http can use user expression as true along with auto-config.  We need to append hasRole in access.

<sec:http auto-config="true"  user-expression="true">
    <sec:intercept-url pattern="/foo/**" access="hasRole("ROLE_BASIC") />
</sec:http>

Form  Login

Form Login  XML configuration


 <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.1.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security-3.1.xsd">
           
    <http auto-config="true" user-expressions="true">
      <intercept-url pattern="/secured/*" access="hasRole("ROLE_USER" )/>
        <form-login login-page="/loginPage"
            username-parameter="username" password-parameter="password"
            default-target-url="/home" authentication-failure-url="/Login?error=1" />
        <logout logout-url="/logout" logout-success-url="/logoutPage" />        
    </http>
     
    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="satya" ="satya@123" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
</beans:beans>
form-login : form-login used to add UserNamePasswordAuthicationFilter to the filter stack and a LoginUrlAuthenticationEntryPoint to the application context to provide authentication.

If no attributes are supplied, a login page will be generated automatically at the URL /spring-security-login.

login-page : login-page  URL is used to redirect to the login page. This will map to the login page though the mapping URL and Login Controller.

default-target-url  : defaultTargetUrl  property is used by UserNamePasswordAuthenticationFilter   to redirect to the success page.

authentication-failure-url : authenticationFailureUrl   property is used by UserNamePasswordAuthenticationFilter   to redirect to the failure page.

authentication-success-handler-ref: This is an alternate to the default-target-url gives the full control over navigation flow after a success full authentication.

User-expressions : Enables the EL expressions in the access attribute.

log-out-url : The URL which will cause the logout. Defaults to "/j_spring_security_logout".

Authentication Manager

Authentication Manager will automatically registered internally. 
This will create an instance of Spring Security's Provider Manager class, which needs to be configured with a list of one or more AuthenticationProvider instances. 

authentication-manager :  Authentication Provider class provides authentication to the application.

authentication-provider :   Authentication provider is the child element of the authentication provider. 

Multiple instances of the authentication provider be  included inside  authentication manager.

Authentication provider class uses the ref attribute to configure custom pro-vider(3rd party) loads the user information from User Service and compares the username and password combination with the values supplied at the login. 

Method Level Security :tails

A secure web application will be more natural to secure the methods.  We will get Role based authorization in many internet application.

All the methods are defined as PreAuthorize annotations.

@PreAuthorize("hasRole('ROLE_USER')")
public void getUserDetails(String userID){ }

PreAuthorize will decide the method will actually invoke or not.

We need to enable the PreAuthorize  by the use of <global-method-security pre-post-annotations="enabled"/>  in the Spring  Context file

Login Page security continue to next blog..........................






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...