CCM NG: JavaDoc for the AuthorizationInterceptor and the supporting annotations
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3747 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
a84c6ad626
commit
bd56f40876
|
|
@ -31,9 +31,11 @@ import javax.interceptor.AroundInvoke;
|
||||||
import javax.interceptor.Interceptor;
|
import javax.interceptor.Interceptor;
|
||||||
import javax.interceptor.InvocationContext;
|
import javax.interceptor.InvocationContext;
|
||||||
|
|
||||||
import org.libreccm.security.PermissionChecker;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A CDI interceptor which can be used to secure methods of CDI beans. To use
|
||||||
|
* the interceptor annotation the method to secure with
|
||||||
|
* {@link AuthorizationRequired} and one or more {@link RequiresRole} and/or
|
||||||
|
* {@link RequiresPrivilege} annotations.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
|
|
@ -41,37 +43,68 @@ import org.libreccm.security.PermissionChecker;
|
||||||
@Interceptor
|
@Interceptor
|
||||||
public class AuthorizationInterceptor {
|
public class AuthorizationInterceptor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A logger for providing some informations what the interceptor is doing.
|
||||||
|
*/
|
||||||
private static final Logger LOGGER = LogManager.getLogger(
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
AuthorizationInterceptor.class);
|
AuthorizationInterceptor.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current subject
|
||||||
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private Subject subject;
|
private Subject subject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An instance of the {@link PermissionChecker} bean. The interceptor uses
|
||||||
|
* the methods of the {@code PermissionChecker} class to check if the
|
||||||
|
* current subject has the required roles and permissions.
|
||||||
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private PermissionChecker permissionChecker;
|
private PermissionChecker permissionChecker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the CDI container when a method annotated with
|
||||||
|
* {@link AuthorizationRequired} is called.
|
||||||
|
*
|
||||||
|
* @param context The invocation context of the method.
|
||||||
|
*
|
||||||
|
* @return The return value of the called method.
|
||||||
|
*
|
||||||
|
* @throws Exception If any exception occurs.
|
||||||
|
*/
|
||||||
@AroundInvoke
|
@AroundInvoke
|
||||||
public Object intercept(final InvocationContext context) throws Exception {
|
public Object intercept(final InvocationContext context) throws Exception {
|
||||||
LOGGER.debug("Intercepting method invocation");
|
LOGGER.debug("Intercepting method invocation");
|
||||||
|
|
||||||
|
//Get the method which call was intercepted.
|
||||||
final Method method = context.getMethod();
|
final Method method = context.getMethod();
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"The authoriziation interceptor can only be used for method");
|
"The authoriziation interceptor can only be used for method");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the method has a RequiresRole annotation. If yes, check
|
||||||
|
// if the current subject is assigned to the required role.
|
||||||
if (method.isAnnotationPresent(RequiresRole.class)) {
|
if (method.isAnnotationPresent(RequiresRole.class)) {
|
||||||
final String requiredRole = method.getAnnotation(RequiresRole.class)
|
final String requiredRole = method.getAnnotation(RequiresRole.class)
|
||||||
.value();
|
.value();
|
||||||
subject.checkRoles(requiredRole);
|
subject.checkRoles(requiredRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the RequiresPrivilege annotation is present on the
|
||||||
|
// method level. If yes check if the current subject has a permission
|
||||||
|
// granting the required privilege.
|
||||||
if (method.isAnnotationPresent(RequiresPrivilege.class)) {
|
if (method.isAnnotationPresent(RequiresPrivilege.class)) {
|
||||||
final String requiredPrivilege = method.getAnnotation(
|
final String requiredPrivilege = method.getAnnotation(
|
||||||
RequiresPrivilege.class).value();
|
RequiresPrivilege.class).value();
|
||||||
permissionChecker.checkPermission(requiredPrivilege);
|
permissionChecker.checkPermission(requiredPrivilege);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if one or more parameters are annotated with the
|
||||||
|
// RequiredPrivilege annotation. If yes check if the parameter is
|
||||||
|
// of type CcmObject and check if the current subject has a permission
|
||||||
|
// granting the required privilege on the provided CcmObject instance.
|
||||||
final Annotation[][] annotations = method.getParameterAnnotations();
|
final Annotation[][] annotations = method.getParameterAnnotations();
|
||||||
final Object[] parameters = context.getParameters();
|
final Object[] parameters = context.getParameters();
|
||||||
if (parameters != null && parameters.length > 0
|
if (parameters != null && parameters.length > 0
|
||||||
|
|
@ -84,21 +117,27 @@ public class AuthorizationInterceptor {
|
||||||
return context.proceed();
|
return context.proceed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for checking the parameter permissions.
|
||||||
|
*
|
||||||
|
* @param parameter The parameter to check.
|
||||||
|
* @param annotations All annotations of the parameter.
|
||||||
|
*/
|
||||||
private void checkParameterPermission(final Object parameter,
|
private void checkParameterPermission(final Object parameter,
|
||||||
final Annotation[] annotations) {
|
final Annotation[] annotations) {
|
||||||
if (parameter instanceof CcmObject
|
if (parameter instanceof CcmObject
|
||||||
&& annotations != null
|
&& annotations != null
|
||||||
&& annotations.length > 0) {
|
&& annotations.length > 0) {
|
||||||
final CcmObject object = (CcmObject) parameter;
|
final CcmObject object = (CcmObject) parameter;
|
||||||
|
|
||||||
String requiredPrivilege = null;
|
String requiredPrivilege = null;
|
||||||
for(Annotation annotation : annotations) {
|
for (Annotation annotation : annotations) {
|
||||||
if (annotation instanceof RequiresPrivilege) {
|
if (annotation instanceof RequiresPrivilege) {
|
||||||
requiredPrivilege = ((RequiresPrivilege) annotation).value();
|
requiredPrivilege = ((RequiresPrivilege) annotation).value();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requiredPrivilege != null && !requiredPrivilege.isEmpty()) {
|
if (requiredPrivilege != null && !requiredPrivilege.isEmpty()) {
|
||||||
permissionChecker.checkPermission(requiredPrivilege, object);
|
permissionChecker.checkPermission(requiredPrivilege, object);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ import java.lang.annotation.Target;
|
||||||
import javax.interceptor.InterceptorBinding;
|
import javax.interceptor.InterceptorBinding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Use this annotation to secure a method by the
|
||||||
|
* {@link AuthorizationInterceptor}.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.security;
|
package org.libreccm.security;
|
||||||
|
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Inherited;
|
import java.lang.annotation.Inherited;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
|
|
@ -25,6 +27,17 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This annotation is used together with the {@link AuthorizationRequired}
|
||||||
|
* annotation to limit access to methods based on the permissions granted to a
|
||||||
|
* user. The annotation can be used to annotation an method or a parameter of
|
||||||
|
* the type {@link CcmObject}.
|
||||||
|
*
|
||||||
|
* If used on the method level the current subject must have a permission
|
||||||
|
* granting the privilege provided by this annotation to call the method.
|
||||||
|
*
|
||||||
|
* If used on a parameter of type {@link CcmObject} the current subject must
|
||||||
|
* have a permission granting the privilege provided by this annotation for the
|
||||||
|
* particular instance of {@code CcmObject}.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
|
|
@ -32,7 +45,7 @@ import java.lang.annotation.Target;
|
||||||
@Target({ElementType.METHOD, ElementType.PARAMETER})
|
@Target({ElementType.METHOD, ElementType.PARAMETER})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface RequiresPrivilege {
|
public @interface RequiresPrivilege {
|
||||||
|
|
||||||
String value();
|
String value();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,10 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This annotation is used together with the {@link AuthorizationRequired}
|
||||||
|
* annotation to limit access to methods based on the roles assigned to a user.
|
||||||
|
* To call a method annotation with this annotation the current subject must be
|
||||||
|
* assigned to the role provided by this annotation.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
|
|
@ -32,7 +36,7 @@ import java.lang.annotation.Target;
|
||||||
@Target({ElementType.METHOD, ElementType.PARAMETER})
|
@Target({ElementType.METHOD, ElementType.PARAMETER})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface RequiresRole {
|
public @interface RequiresRole {
|
||||||
|
|
||||||
String value();
|
String value();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue