4

I am trying use hasPermission in my jsp pages from my spring project. I already use this with no problem in the methods from my controller / service classes. Reading the article:

http://docs.spring.io/spring-security/site/docs/4.0.0.M1/reference/htmlsingle/#the-accesscontrollist-tag

from official documentation, I understood that for do that I nwill need implement a class derived from DefaultPermission which would be loaded from a custom AclService class.

My problem it's i can't find any information of how implement all that classes, and even don't know if this approach it's the only one or if I understood the subject in the right way (the official documentation is very brief about this subject, and in the rest of internet i can't find more information).

Anyone can point me in the right direction here? Maybe indicate some tutorial or sample of code.

UPDATE

Reading other topics here from StackOverflow, I found this sugestion:

This is what I have done. I created my own permission evaulator:
>     public class MyPermissionEvaluator implements PermissionEvaluator {
>     ...
>     }
Then I configured spring to use that evaulator via
>     <beans:bean id="expressionHandler"
>         class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
>           <beans:property name="permissionEvaluator" ref="permissionEvaluator"/>
>     </beans:bean>
>     
>     <beans:bean id="webExpressionHandler" 
>         class="com.bulb.learn.webapp.security.CustomWebSecurityExpressionHandler">
>         <beans:property name="permissionEvaluator" ref="permissionEvaluator"/>
>     </beans:bean>
>     
>     <beans:bean id="permissionEvaluator" class="my.domain.MyPermissionEvaluator" />
That way all expression handlers have access to my evaulator.

Then, in JSP (actually, I am using jspx), I can make tags like this:
>     <sec:authorize access="hasPermission(#childUnit, 'read')">
>          ...
>     </sec:authorize>
Hope that gets you heading in the right direction.

As I already have a Custom PermissionEvaluator, I try this method. It works partially, but now, even when the user has the permission, the element inside the tag isn't displayed. Also, the eclipse indicate an error related to this tag ('Syntax error on token(s), misplaced construct(s)'), despite the application being built and executed without errors.

In the console, this error is displayed:

un 03, 2014 7:48:40 PM org.springframework.security.access.expression.DenyAllPermissionEvaluator hasPermission
Advertência: Denying user klebermo permission 'cadastra_usuario' on object null
Jun 03, 2014 7:48:40 PM org.springframework.security.access.expression.DenyAllPermissionEvaluator hasPermission
Advertência: Denying user klebermo permission 'altera_usuario' on object null
Jun 03, 2014 7:48:40 PM org.springframework.security.access.expression.DenyAllPermissionEvaluator hasPermission
Advertência: Denying user klebermo permission 'remove_usuario' on object null
Jun 03, 2014 7:48:45 PM org.springframework.security.access.expression.DenyAllPermissionEvaluator hasPermission
Advertência: Denying user klebermo permission 'cadastra_permissao' on object null
Jun 03, 2014 7:48:45 PM org.springframework.security.access.expression.DenyAllPermissionEvaluator hasPermission
Advertência: Denying user klebermo permission 'altera_permissao' on object null
Jun 03, 2014 7:48:45 PM org.springframework.security.access.expression.DenyAllPermissionEvaluator hasPermission
Advertência: Denying user klebermo permission 'remove_permissao' on object null
Jun 03, 2014 7:48:57 PM org.springframework.security.access.expression.DenyAllPermissionEvaluator hasPermission
Advertência: Denying user klebermo permission 'cadastra_usuario' on object null
Jun 03, 2014 7:48:57 PM org.springframework.security.access.expression.DenyAllPermissionEvaluator hasPermission
Advertência: Denying user klebermo permission 'altera_usuario' on object null
Jun 03, 2014 7:48:57 PM org.springframework.security.access.expression.DenyAllPermissionEvaluator hasPermission
Advertência: Denying user klebermo permission 'remove_usuario' on object null

In the Internet, I found some articles sugesting I should implement a Interface for WebSecurityExpressionHandler.

Anyone know what the right step here?

UPDATE 2

Previously, I was using this tag:

<sec:accesscontrollist hasPermission="1,2" domainObject="${someObject}">

This will be shown if the user has either of the permissions represented by the values "1" or "2" on the given object.

</sec:accesscontrollist>

where no error was displayed in the console, but still doesn't work. My question which object I need implement to atribute domainObject of the tag?

Aleksandr M
  • 24,264
  • 12
  • 69
  • 143
Kleber Mota
  • 8,521
  • 31
  • 94
  • 188
  • @see http://docs.spring.io/spring-security/site/docs/4.0.0.M1/reference/htmlsingle/#taglibs JSP Tag Libraries e.g This content will only be visible to users who have the "supervisor" authority in their list of GrantedAuthoritys. – ronielhcuervo Jun 03 '14 at 14:58
  • 1
    I already have this tag in my code, following the instructions in the link (which I already have seen). And I don't want use hasRole, but hasPermission: I have roles and permissions in my application (each Role can have several Permissions, and the user can create new Roles to associate the Permissions need be associated). – Kleber Mota Jun 03 '14 at 16:01
  • 1
    look at http://krams915.blogspot.com/2011/01/spring-security-3-full-acl-tutorial.html and this Q. http://stackoverflow.com/questions/7481869/spring-security-how-acl-grants-permissions – ronielhcuervo Jun 03 '14 at 16:56
  • 1
    I have this class PermissionEvaluator in my project, and I use the annotation @PreAuthorize with the parameter hasPermission in my methods (in controller and service classes). But I am not capable to use in my JSP pages. See my configuration here: https://github.com/klebermo/lojavirtual/tree/master/src/main/java/com/spring/webapp/lojavirtual/config/security – Kleber Mota Jun 03 '14 at 17:19

3 Answers3

7

Your CustomPermissionEvaluator is not being called.

Try following code in your SecurityConfig.java.

...
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;

...
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  ...

  @Override
  public void configure(WebSecurity web) throws Exception {
    DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
    handler.setPermissionEvaluator(new CustomPermissionEvaluator());
    web.expressionHandler(handler);
  }
}

WebApplicationInitializer

...
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

...
public class AnnotationConfigDispatcherServletInitializer extends
    AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class[] {
      SecurityConfig.class,
    };
  }
}
Shinichi Kai
  • 4,415
  • 2
  • 21
  • 25
  • How can I make sure that `configure(WebSecurity web)` gets called on startup or is there a way to do what you show here in pure XML? Like just inject my `CustomPermissionEvaluator` into the `WebSecurity` bean? – Stefan Falk Dec 07 '15 at 16:54
  • 1
    You can use `AbstractAnnotationConfigDispatcherServletInitializer` to make sure `configure(WebSecurity web)` gets called on startup. I have edited my answer. – Shinichi Kai Dec 10 '15 at 15:01
1
<sec:accesscontrollist hasPermission="1,2" domainObject="${someObject}">

someObject represents the object to which the acl should be applied. So in your case the childUnit bean.

FYI I have done something similar, without using acl, and we wired up a parameternamediscoverer.

Community
  • 1
  • 1
NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
  • I don't have a bean `childUnit` yet, that's only the example I found. I try implement in my application the same, but I am facing the issue I describe above (first update). Do you know where I should implement this `childUnit` bean? By the way, But your example looks promissor too. I will give a try. – Kleber Mota Jun 04 '14 at 13:47
  • the childunit is an example of whatever you want to secure access to ... in your case whatever bean is accessed in your jsp. Normal roles security allows permission setting by role, hwoever usign acl allows each item in your system to have different security access (trya nd avoid it if you can - have yet to see a business case where this was needed (and actually used in the long term)). We did one, but no one could be bothered keeping the lists up to date. – NimChimpsky Jun 04 '14 at 13:50
0

In my case, i have some ArrayList of String in httpsession. i need to show a button the user, only if the button function name is available in that list. i have implement it via Spring Security ACL.

For that add ACL + spring security core jar in the classpath.

<dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>${spring.security.version}</version>
    </dependency>       
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>${spring.security.version}</version>
    </dependency>       
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-acl</artifactId>
        <version>${spring.security.version}</version>
    </dependency>

then, i have added the bean in xml.

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

then the handler class BasePermissionEvaluator, this class will evaluate, if that button has permission,

public class BasePermissionEvaluator implements PermissionEvaluator{
 @Override
 public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {

  boolean hasPermission = true;
  // targetDomainObject [101001, 102001, 103001, 201001, 202001, 203001, 204001, 205001, 206001, 301001, 302001, 303001]permission : 303001
    @SuppressWarnings("unchecked")
    List<String> functionList =(List<String>) targetDomainObject;       
    if(!functionList.contains(permission.toString())) {
        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");
 }
}

Finally in the jsp,

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

<sec:accesscontrollist hasPermission="101001"   domainObject="${USER_FUNCTIONS}"> 
                    <button type="reset" id ="clearMPId"><spring:message code="mp.clear"/></button>
  </sec:accesscontrollist>   

Hope it helps.

Siva Anand
  • 2,872
  • 2
  • 18
  • 9