Package es.internna.jee.security.impl

Source Code of es.internna.jee.security.impl.SecurityInterceptor

package es.internna.jee.security.impl;

import java.lang.reflect.AnnotatedElement;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import es.internna.jee.security.api.RoleMembershipManagement;

/**
*
* Interceptor that implements the security roles defined using the annotations from the JSR 250
* Annotations currently supported are: @RolesAllowed, @PermitAll, @DenyAll
*
* @author Jose Noheda
*
*/
@Aspect
public class SecurityInterceptor {
   
    private Log log = LogFactory.getLog(SecurityInterceptor.class);
    private final String[] executionResults = {"Undefined", "Forbidden", "Permitted"};
   
    private RoleMembershipManagement roleMembershipManagement;

    /**
    * Detect the current roles of the user
    */
    public void setRoleMembershipManagement(RoleMembershipManagement roleMembershipManagement) {
        this.roleMembershipManagement = roleMembershipManagement;
    }

    /**
    * Only a Method can be annoted with @DenyAll (<a href='http://java.sun.com/javaee/5/docs/api/javax/annotation/security/DenyAll.html' target='_top'>@DenyAll</a>)
    * Methods with this annotation should always throw a SecurityException.
    */
    @Before("@annotation(javax.annotation.security.DenyAll)")
    public void deny(JoinPoint jp) throws Throwable {
        if (log.isDebugEnabled()) log.debug("Method is annotated with @DenyAll. Cannot proceed");
        throw new SecurityException();
    }
   
    /**
    * RolesAllowed can be applied to a Method or a Class (<a href='http://java.sun.com/javaee/5/docs/api/javax/annotation/security/RolesAllowed.html' target='_top'>@RolesAllowed</a>)
    * Methods with this annotation should check the current user roles before deciding to allow access.
    */
    @Before("@annotation(javax.annotation.security.RolesAllowed) || @annotation(javax.annotation.security.PermitAll)")
    public void checkRoles(JoinPoint jp) throws SecurityException {
        if (log.isDebugEnabled()) log.debug("Aspect: SecurityInterceptor [" + this.hashCode() + "] has been fired");
        int permitted = -1;
        try {
            MethodSignature met = (MethodSignature) jp.getSignature();
            permitted = checkPermission(jp.getSourceLocation().getWithinType().getMethod(met.getMethod().getName(), met.getMethod().getParameterTypes()));
            if(permitted == -1) permitted = checkPermission(jp.getSourceLocation().getWithinType());
        } catch (Exception ex) {
            if (log.isDebugEnabled()) log.debug(ex);
        } finally {
            if (log.isDebugEnabled()) log.debug("Aspect: SecurityInterceptor [" + this.hashCode() + "] execution result is " + executionResults[permitted + 1]);
            if(permitted == 0) throw new SecurityException();
        }
    }
   
    /**
    * This function returns
    *    -1 if the object is not annotated (so no operation should be done)
    *    0 if access should be denied
    *    1 if the access should be allowed
    */
    private int checkPermission(AnnotatedElement targetObject) {
        int perm = -1;
        if (log.isDebugEnabled()) log.debug("Checking user credentials to execute " + targetObject);
        if (targetObject != null) {
            RolesAllowed rolesAllowed = targetObject.getAnnotation(RolesAllowed.class);
            if (rolesAllowed != null) {
                if (log.isDebugEnabled()) log.debug("Detected roles for object " + rolesAllowed);
                for (String role : rolesAllowed.value()) {
                    if (perm != 1) {
                        perm = this.roleMembershipManagement.isInRole(role) ? 1 : 0;
                        if (log.isDebugEnabled() & (perm == 1)) log.debug("Authenticated user is member of role: " + role);
                    }
                }
                if (log.isDebugEnabled() & (perm == 0)) log.debug("User is NOT member of any of the authorized roles");
            } else {
                if (targetObject.getAnnotation(PermitAll.class) != null) {
                    perm = 1;
                    if (log.isDebugEnabled()) log.debug("Object (" + targetObject + ") allowed by @PermitAll annotation");
                }
            }
        }
        return perm;
    }
}
TOP

Related Classes of es.internna.jee.security.impl.SecurityInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.