Hi,
In my recent project I have working on securing spring
methods exposed by controllers via @RequestMappings.
PROBLEM TAKEN
I have to cross check the permissions/authorities assigned
to the user who has logged-in to the system.
If the authority mentioned above the method matches then execution goes
successfully else exception is throws.
TECHNOLOGY STACK
·
Spring
·
Hibernate
·
Tomcat
·
Maven
·
jQuery
SOLUTION APPROACH
I made the class that checks the user who is logged-in at
present (I made the UserInfo object to be flowed in each request object after
successful authentication. For details
please refer my blog http://sv-technical.blogspot.in/2013/07/spring-how-to-make-bean-object.html).
Ingredients to cook above code are:
Firstly I made my custom class extending org.springframework.security.access.PermissionEvaluator
as BasePermissionEvaluator. This class stores the object of UserInfo
(refer blog mentioned above for details) and has below structure.
BasePermissionEvaluator.java
public class BasePermissionEvaluator
implements PermissionEvaluator
{
@Autowired
private UserInfo userInfo;
/**
*
@return the userInfo
*/
public UserInfo getUserInfo()
{
return userInfo;
}
/**
*
@param userInfo the userInfo to set
*/
public void setUserInfo(UserInfo userInfo)
{
this.userInfo = userInfo;
}
@Override
public boolean hasPermission(Authentication authentication, Object
targetDomainObject, Object permission)
{
boolean hasPermission = false;
if (authentication != null && permission instanceof String)
{
hasPermission = userInfo.hasPermission((String)permission);
} else
{
hasPermission = false;
}
return hasPermission;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable
targetId, String targetType, Object permission)
{
throw new RuntimeException("Id and Class permissions are not
supperted by this application");
}
}
Corresponding applicationContext.xml
entries
<security:global-method-security pre-post-annotations="enabled">
<security:expression-handler ref="expressionHandler"
/>
</security:global-method-security>
<bean
id="webExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"
/>
<bean id="expressionHandler"
class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<property name="permissionEvaluator"
ref="permissionEvaluator" />
</bean>
<bean id="permissionEvaluator"
class=" BasePermissionEvaluator"
/>
If the exception is thrown by any of the
method then handles it using below entries
<bean
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">/pages/common/error</prop>
</props>
</property>
</bean>
Here you are supposed to create on
error.jsp inside pages/common folder of you context root folder.
Below
is one of the Controller’s methods secured via @PreAuthorize annotation.
@RequestMapping(value = "service/user/list.do", method =
RequestMethod.GET)
@PreAuthorize("hasPermission('null','can-view-users')")
public @ResponseBody
List<User> list()
{
return userService.list();
}
Error.jsp
<%@ page isErrorPage="true"
%>
<!doctype html>
<html>
<head>
<meta
charset="utf-8">
<title>vCare
- for you</title>
<link
rel="stylesheet" type="text/css"
href="<%=ctx%>/content/css/bootstrap.css" />
<link
rel="stylesheet" type="text/css"
href="<%=ctx%>/content/css/bootstrap-responsive.css" />
<link
rel="stylesheet" type="text/css" href="<%=ctx%>/content/css/default.css"
/>
<script
type="text/javascript"
src="<%=ctx%>/content/scripts/jquery-1.8.2.js"></script>
<script
type="text/javascript"
src="<%=ctx%>/content/scripts/bootstrap.min.js"></script>
</head>
<body>
<div
class="header">
<div
class="wrapper row-fluid">
<div
class="span12">
<div
class="logo">
<a
href="#">
<img
src="<%=ctx%>/content/images/logo-150-60.png"
border="0" />
</a>
</div>
</div>
</div>
</div>
<div
class="main-content">
<div
class="wrapper">
<div
class="error-wrap">
<h1>Error</h1>
<h3>Sorry,
an error occurred.</h3>
<hr
/>
<p>Below
are the details: </p>
<div
class="alert alert-error">
<%=exception.getMessage()%>
</div>
<hr
/>
<a
class="btn btn-success" href="<%=request.getContextPath
()%>/">Go Back</a>
</div>
</div>
</div>
</body>
</html>
Please let me know if you need any other help or more
information.
Thanks
Shailendra
No comments:
Post a Comment