Spring MVC Security JSP taglib example

Spring Security provides jsp taglibs for customizing User Interface according the authenticated user’s role. We can make it possible to show some user interface portion to user with role admin and not to others.

Including Spring Security JSP Taglib

We have to add Spring Security Taglib to our jsp file to use this feature of role based user interface modification:
<%@ taglib prefix="sec"
uri="http://www.springframework.org/security/tags"%>

Authorize tag in Spring Security taglib

Authorize tag is used for role based user interface creation. For example, if we want to create a jsp portion that will be visible to user with role “ROLE_ADMIN”, it will like following code:
<sec:authorize access="hasRole('ADMIN')">
 <label><a href="#">Edit this page</a> | This part is
visible only to ADMIN</label>
 </sec:authorize>
If we put this code to jsp, the message will be shown only to the users with role “ROLE_ADMIN”. access” attribute is used to specify the Spring Security EL Expression and if the expression returns true for the loged in user only then the HTML code within “<sec:authorize/>” tag will be shown to user. The expression in access attribute is send to WebSecurityExpressionHandler defined in the web context. So we have to add WebSecurityExpressionHandler to out security context. It can be done in two ways:
  • Use default WebSecurityExpressionHandler, which will be only available if we specify use-expressions=”true” in our Spring Security Configuration file under <http/> tag.
  • Register your WebSecurityExpressionHandler in Spring Security Configuration file.

Common built-in expressions

Following are the common expressions that can be used in access attribute of “<sec:authorize/>” tag:
  • hasRole([role]) : Returns true only if the login user has the role specified in [role].
  • hasAnyRole([role1,role2]) : Returns true only if the login user has atleast one role specified in [role1,role2]. The roles will be specified in comma separated format.
  • isAnonymous() : Returns true only is the login user is an anonymous user.
  • isAuthenticated() : Returns true if the user is not an anonymous user.
  • isFullyAuthenticated() : Returns true if the user is not an anonymous user or a remember me user.
  • isRememberMe() : Returns true if the user is a remember me user.
you can user previous post Spring MVC security with hibernate integration authentication example using Java configuration and just modify welcome.jsp user /WEB-INF/views folder as below:

you also need to put spring-security-taglibs-4.0.2.RELEASE.jar uder WEB-INF/lib

Modified welcome.jsp
<%@ page language="java" contentType="text/html;
charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c"
uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec"
uri="http://www.springframework.org/security/tags"%>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
 <title>Welcome page</title>
</head>
<body>
 Dear <strong>${user}</strong>, Welcome to Home Page.
 <a href="<c:url value="/logout" />">Logout</a>
 
 <br/>
 <br/>
 <div>
 <label>View all information| This part is visible to Everyone</label>
 </div>
 
 <br/>
 <div>
 <sec:authorize access="hasRole('ADMIN')">
 <label><a href="#">Edit this page</a> | This part is
visible only to ADMIN</label>
 </sec:authorize>
 </div>
 <br/>
 <div>
 <sec:authorize access="hasRole('API')">
 <label><a href="#">Start backup</a> | This part is
visible only to one who has API rights.</label>
 </sec:authorize>
 </div>
 
 <br/>
 <div>
 <sec:authorize access="hasRole('ADMIN') and
hasRole('API')">
 <label><a href="#">Start backup</a> | This part is
visible only to one who is both ADMIN & API</label>
 </sec:authorize>
 </div>
</html>



Keep visiting TutorialsDesk for more tutorials and practical programming examples on Spring MVC. Hope we are able to explain you Spring MVC Security JSP taglib example, if you have any questions or suggestions please write to us using contact us form.

Please share us on social media if you like the tutorial.

Spring MVC Method level security using @PreAuthorize and @PostAuthorize

Spring security provides method level security using @PreAuthorize and @PostAuthorize. This is expression-based access control. @PreAuthorize can check for authorization before entering into method. @PreAuthorize is checked on the basis of role or the argument which is passed to the method. @PostAuthorize checks for authrorisation after method execution. @PostAuthorize can be authorized on the basis of logged in roles, return object by method and passed argument to the method. For the returned object spring security provides built-in keyword i.e. returnObject.

We need to define @PreAuthorize and @PostAuthorize in the interface of the service layer.

STEP 1:- Open Eclipse and Create Dynamic Web Project named SpringSecurityMethodLevelXMLConfig 

STEP 2:- Make sure you use Target Runtime as Apache Tomcat 7.0. 

STEP 3:- copy below jars to WEB-INF/lib folder.
  • aopalliance-1.0.jar
  • commons-logging-1.2.jar
  • spring-aop-4.1.4.RELEASE.jar
  • spring-beans-4.1.4.RELEASE.jar
  • spring-context-4.1.4.RELEASE.jar
  • spring-core-4.1.4.RELEASE.jar
  • spring-expression-4.1.4.RELEASE.jar
  • spring-security-config-4.0.2.RELEASE.jar
  • spring-security-core-4.0.2.RELEASE.jar
  • spring-security-taglibs-4.0.2.RELEASE.jar
  • spring-security-web-4.0.2.RELEASE.jar
  • spring-web-4.1.4.RELEASE.jar
  • spring-webmvc-4.1.4.RELEASE.jar
STEP 4:- Create Spring Configuration Bean file. /WebContent/WEB-INF/dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:context="http://www.springframework.org/schema/context"
 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
 http://www.springframework.org/schema/mvc 
 http://www.springframework.org/schema/mvc/spring-mvc.xsd
 http://www.springframework.org/schema/context 
 http://www.springframework.org/schema/context/spring-context.xsd">
 
 <context:component-scan base-package="com.tutorialsdesk.controller" />
 
 <bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
 <property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
 <property name="prefix" value="/WEB-INF/views/" />
 <property name="suffix" value=".jsp" />
 </bean>
 
 <mvc:annotation-driven/>
 
</beans>

STEP 5:- Create Spring security configuration file. /WebContent/WEB-INF/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.xsd
 http://www.springframework.org/schema/security 
 http://www.springframework.org/schema/security/spring-security.xsd">
 
 <http auto-config="true" >
 <intercept-url pattern="/home"
access="hasAnyRole('ROLE_READ','ROLE_WRITE','ROLE_NONE')"
/>
<!-- access denied page-->
 <access-denied-handler error-page="/Access_Denied" />
 
 <form-login 
 login-processing-url="/login"
 login-page="/login" 
 default-target-url="/home" 
 username-parameter="username"
 password-parameter="password"
 authentication-failure-url="/login?error"/> 
 
 </http>
 
 <authentication-manager >
 <authentication-provider>
 <user-service>
 <user name="admin" password="123456"
authorities="ROLE_READ,ROLE_WRITE" />
 <user name="reader" password="123456"
authorities="ROLE_READ" />
 <user name="user" password="123456"
authorities="ROLE_NONE" />
 </user-service>
 </authentication-provider>
 </authentication-manager>
 
 <!-- <global-method-security secured-annotations="enabled"/> -->
 <global-method-security pre-post-annotations="enabled"/>
 
 <beans:bean id="customService"
class="com.tutorialsdesk.service.CustomServiceImpl" />
 
</beans:beans>

In order to enable Spring Method level Security, we need to add <global-method-security pre-post-annotations="enabled"/> in security context file, as shown above.

STEP 6 :- Map Spring configuration files in /WebContent/WEB-INF/web.xml file as below :-
<?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"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
 <display-name>SpringSecurityMethodLevelXMLConfig</display-name>
 <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>/</url-pattern>
 </servlet-mapping>
 
 <context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>
 /WEB-INF/spring-security.xml
 </param-value>
 </context-param>
 
 <listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 
 <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>

STEP 7 :- Create Model Class.
  • Package: com.tutorialsdesk.model
  • Filename: Folder.java
package com.tutorialsdesk.model;

public class Folder {

 private String folderName;
 private String owner;
 public Folder(String folderName, String owner) {
 super();
 this.folderName = folderName;
 this.owner = owner;
 }
 public String getFolderName() {
 return folderName;
 }
 public void setFolderName(String folderName) {
 this.folderName = folderName;
 }
 public String getOwner() {
 return owner;
 }
 public void setOwner(String owner) {
 this.owner = owner;
 }
 
}

STEP 8 :- Create Service Interface.
  • Package: com.tutorialsdesk.service
  • Filename: CustomService.java
package com.tutorialsdesk.service;

import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;

import com.tutorialsdesk.model.Folder;

public interface CustomService {
 
 @PreAuthorize ("hasRole('ROLE_WRITE')")
 public void addFolder(Folder folder);

 @PostAuthorize ("hasRole('ROLE_READ')")
 public Folder getFolder();
 
 @PostAuthorize ("returnObject.owner == authentication.name")
 public Folder getFolderByOwnerName();

 @PreAuthorize ("#folder.owner == authentication.name")
 public void deleteFolder(Folder folder);
 
}

Look at the interface how to define @PreAuthorize and @PostAuthorize. authentication and principal keyword can directly be used to access user information. # is used to access argument of the method. Take attention on @PostAuthorize, built-in keyword returnObject has been used. Here returnObject is equivalent to Book instance returned by the method.

STEP 9 :- Create Service Impl Class.
  • Package: com.tutorialsdesk.service
  • Filename: CustomServiceImpl.java
package com.tutorialsdesk.service;

import org.springframework.stereotype.Service;

import com.tutorialsdesk.model.Folder;

@Service
public class CustomServiceImpl implements CustomService {

 @Override
 public void addFolder(Folder folder) {
 System.out.println("You have successfully added Folder.");
 
 }

 @Override
 public Folder getFolder() {
 Folder folder = new Folder("PQR","reader");
 return folder;
 }

 @Override
 public Folder getFolderByOwnerName() {
 Folder folder = new Folder("XYZ","admin");
 return folder;
 }
 
 @Override
 public void deleteFolder(Folder folder) {
 System.out.println("Folder deleted");
 
 }

}

STEP 10 :- Create Controller Class.
  • Package: com.tutorialsdesk.controller
  • Filename: IndexController.java
package com.tutorialsdesk.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import
org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.tutorialsdesk.model.Folder;
import com.tutorialsdesk.service.CustomService;

@Controller
public class IndexController {

 @Autowired
 private CustomService customService;
 
 @RequestMapping(value = {"/", "/login" }, method =
RequestMethod.GET)
 public String loginPage(ModelMap model, @RequestParam(value = "error",
required = false) String error) {
 
 if (error != null) {
 model.addAttribute("error", "Invalid username and password!");
 }
 return "login";
 }
 
 @RequestMapping(value = { "/home" }, method = RequestMethod.GET)
 public String homePage(ModelMap model) {
 return "welcome";
 }
 
 @RequestMapping(value = { "/secureRead" }, method = RequestMethod.GET)
 public String secureReadPage(ModelMap model) {
 
 Folder folder=customService.getFolder();
 
 model.addAttribute("folder", folder.getFolderName());
 
 return "secure";
 }
 
 @RequestMapping(value = { "/secureWrite" }, method = RequestMethod.GET)
 public String secureWritePage(ModelMap model) {

 customService.getFolder();
 
 Folder folder=customService.getFolderByOwnerName();
 
 model.addAttribute("folder", folder.getFolderName());
 
 Folder folder1 = new Folder("ABC","reader");
 customService.addFolder(folder1);
 
 model.addAttribute("addedfolder", folder1.getFolderName());
 
 Folder folder2 = new Folder("XYZ","admin");
 customService.deleteFolder(folder2);
 
 model.addAttribute("deletedfolder", folder2.getFolderName());
 
 return "secure";
 }
 
 @RequestMapping(value="/logout", method = RequestMethod.GET)
 public String logoutPage (ModelMap model,HttpServletRequest request,
HttpServletResponse response) {
 Authentication auth = SecurityContextHolder.getContext().getAuthentication();
 if (auth != null){ 
 new SecurityContextLogoutHandler().logout(request, response, auth);
 }
 model.addAttribute("msg", "You've been logged out
successfully.");
 return "login";
 }
 
 @RequestMapping(value = "/Access_Denied", method = RequestMethod.GET)
 public String accessDeniedPage(ModelMap model) {
 model.addAttribute("user", getPrincipal());
 return "accessDenied";
 }

 private String getPrincipal(){
 String userName = null;
 Object principal =
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
 
 if (principal instanceof UserDetails) {
 userName = ((UserDetails)principal).getUsername();
 } else {
 userName = principal.toString();
 }
 return userName;
 }
}

STEP 11 :- Create jsp files in /WebContent/WEB-INF/views folder
  • Filename: 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 (Method Level Security)</h1>

 <div id="login-box">

 <h2>Login with Username and Password</h2>

 <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='/login' />" method='POST'>

 <table>
 <tr>
 <td>User:</td>
 <td><input type='text' name='username'></td>
 </tr>
 <tr>
 <td>Password:</td>
 <td><input type='password' name='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>

</body>
</html>

  • Filename: welcome.jsp
<%@ page language="java" contentType="text/html;
charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c"
uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec"
uri="http://www.springframework.org/security/tags"%>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
 <title>Welcome page</title>
</head>
<body>
 Dear <strong>${user}</strong>, Welcome to Home Page.
 <a href="<c:url value="/logout" />">Logout</a>
 
 <br/>
 <br/>
 <div>
 <label>View all information| This part is visible to Everyone</label>
 </div>
 <br/>
 <br/>
 <div>
 Please click this to visit to Read 
 <a href="<c:url value="/secureRead"
/>">Secure</a> Page.
 </div>
 <br/>
 <div>
 Please click this to visit to Write
 <a href="<c:url value="/secureWrite"
/>">Secure</a> Page.
 </div>
 <br/>
 <div>
 <sec:authorize access="hasRole('ADMIN')">
 <label><a href="#">Edit this page</a> | This part is
visible only to ADMIN</label>
 </sec:authorize>
 </div>
 <br/>
 <div>
 <sec:authorize access="hasRole('API')">
 <label><a href="#">Start backup</a> | This part is
visible only to one who has API rights.</label>
 </sec:authorize>
 </div>
 
 <br/>
 <div>
 <sec:authorize access="hasRole('ADMIN') and
hasRole('API')">
 <label><a href="#">Start backup</a> | This part is
visible only to one who is both ADMIN & API</label>
 </sec:authorize>
 </div>
</html>

  • Filename: secure.jsp
<%@ page language="java" contentType="text/html;
charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c"
uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec"
uri="http://www.springframework.org/security/tags"%>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
 <title>Welcome page</title>
</head>
<body>
 Dear <strong>${user}</strong>, Welcome to Secured Page.
 <a href="<c:url value="/home" />">Home</a>
 <a href="<c:url value="/logout" />">Logout</a>
 
 <br/>
 <br/>
 <div>
 <sec:authorize access="hasRole('READ')">
 <label>Folder : ${folder} </label>
 </sec:authorize>
 <br/>
 </div>
 <div>
 <sec:authorize access="hasRole('WRITE')">
 <c:if test="${not empty folder}">
 <label>Folder : ${folder} </label>
 </c:if>
 <br/>
 <c:if test="${not empty addedfolder}">
 <label>Added Folder : ${addedfolder} </label>
 </c:if>
 <br/>
 <c:if test="${not empty deletedfolder}">
 <label>Deleted Folder : ${deletedfolder} </label>
 </c:if>
 </sec:authorize>
 </div>
 </body>
 </html>

  • Filename: accessDenied.jsp
<%@ page language="java" contentType="text/html;
charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c"
uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
 <title>AccessDenied page</title>
</head>
<body>
 Dear <strong>${user}</strong>, You are not authorized to access this page
 <br/><br/><a href="<c:url value="/home"
/>">Home</a> | <a href="<c:url
value="/logout" />">Logout</a>
</body>
</html>
STEP 12 :- Run your project enter below URL in your browser

http://localhost:8080/SpringSecurityMethodLevelXMLConfig/

Keep visiting TutorialsDesk for more tutorials and practical programming examples on Spring MVC. Hope we are able to explain you Spring MVC Method level security using @PreAuthorize and @PostAuthorize Example, if you have any questions or suggestions please write to us using contact us form.

Please share us on social media if you like the tutorial.