Monday, September 4, 2017

Spring security hasPermission is not working

Leave a Comment

I am trying to integrate Spring Security in my spring web application. Basically I need to hide some menus based on user permission. Here is what I did.

I added below JARS in classpath.

spring-security-acl-4.0.2.RELEASE.jar spring-security-config-4.0.2.RELEASE.jar spring-security-core-4.0.2.RELEASE.jar spring-security-taglibs-4.0.1.RELEASE.jar spring-security-web-4.0.2.RELEASE.jar 

Below are the entries in web.xml

<context-param>     <param-name>log4jConfiguration</param-name>     <param-value>/WEB-INF/web_log4j.xml</param-value> </context-param>  <listener>     <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class> </listener>  <servlet>     <servlet-name>dispatcher</servlet-name>     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>     <init-param>         <param-name>contextConfigLocation</param-name>         <param-value>/WEB-INF/spring-root.xml</param-value>     </init-param>     <load-on-startup>1</load-on-startup> </servlet> 

I wrote a class CustomPermissionEvaluator like below.

public class CustomPermissionEvaluator implements PermissionEvaluator{   @Override public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {     HttpServletRequest request = (HttpServletRequest) targetDomainObject;     Profile userProfile = (Profile) request.getSession().getAttribute("testprofile");     if (userProfile.getPermissionMap().get(String.valueOf(permission)) != null) {         return true;     } else {         return false;     } }  @Override public boolean hasPermission(Authentication arg0, Serializable arg1,         String arg2, Object arg3) {     // TODO Auto-generated method stub     return false; } 

}

After this I wrote SecurityConfig file.

@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {  @Override public void configure(WebSecurity web) throws Exception {     DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();     handler.setPermissionEvaluator(new CustomPermissionEvaluator());     web.expressionHandler(handler); } 

}

I have below entries in my spring-root.xml

<sec:global-method-security pre-post-annotations="enabled">     <sec:expression-handler ref="expressionHandler" /> </sec:global-method-security> <bean id="expressionHandler"     class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">     <property name="permissionEvaluator" ref="permissionEvaluator" /> </bean> <bean id="permissionEvaluator" class="main.java.com.config.CustomPermissionEvaluator" /> 

Now in my JSP file I am using below taglib.

and below code

<sec:authorize access="hasPermission('cadastra_categoria', #request)">                       <div id="TEST">                 </div>             </sec:authorize> 

But it is not working. Any suggesation will be appreciated.

3 Answers

Answers 1

"hasPermission('cadastra_categoria', #request)"

Actually, valid call has to have arguments swapped, first one must be target domain object and second - permission:

hasPermission(#request, 'cadastra_categoria') 

I assume you also double-checked you've imported sec taglib to your JSP as required

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

And finally as clarified in 2-nd part of this answer, define the following:

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;  public class AnnotationConfigDispatcherServletInitializer extends     AbstractAnnotationConfigDispatcherServletInitializer {    @Override   protected Class<?>[] getRootConfigClasses() {     return new Class[] {       SecurityConfig.class //your SecurityConfig     };   } } 

to make sure configure(WebSecurity web) is called during your web application startup

Answers 2

As i understand you question you have created CustomPermissionEvaluator class bit you are not checking with your Authenticated user permission.

I am directly writing the code CustomPermissionEvaluator for clear my point there might be any error:

public class CustomPermissionEvaluator implements PermissionEvaluator {

public boolean hasPermission(Authentication auth, Object targetDomainObject, Object permission) {     if ((auth == null) || (targetDomainObject == null) || !(permission instanceof String)){         return false;     }      Profile userProfile = (Profile) request.getSession().getAttribute("testprofile");     String targetType = userProfile.getPermissionMap().get(String.valueOf(permission));      return hasPrivilege(auth, targetType, permission.toString().toUpperCase()); }  private boolean hasPrivilege(Authentication auth, String targetType, String permission) {     for (GrantedAuthority grantedAuth : auth.getAuthorities()) {         if (grantedAuth.getAuthority().startsWith(targetType)) {             if (grantedAuth.getAuthority().contains(permission)) {                 return true;             }         }     }     return false; }  @Override public boolean hasPermission(Authentication arg0, Serializable arg1, String arg2, Object arg3) {     // TODO Auto-generated method stub     return false; } 

}

Answers 3

Please try hasAnyRole and check once i.e

<sec:authorize access="hasAnyRole('ROLE_NAME')"> TEST </sec:authorize> 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment