1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.security;
21
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 import javax.annotation.security.DenyAll;
26 import javax.annotation.security.PermitAll;
27 import javax.annotation.security.RolesAllowed;
28 import javax.faces.context.FacesContext;
29 import java.lang.annotation.Annotation;
30 import java.lang.reflect.AnnotatedElement;
31 import java.lang.reflect.Method;
32 import java.util.Arrays;
33 import java.util.Map;
34 import java.util.concurrent.ConcurrentHashMap;
35
36 public class AuthorizationUtils {
37 private static final Logger LOG = LoggerFactory.getLogger(AuthorizationUtils.class);
38
39 private static final Object NULL_VALUE = new Object();
40 private static final Map<String, Object> AUTHORISATION_CACHE = new ConcurrentHashMap<String, Object>();
41
42 public static boolean isAuthorized(FacesContext facesContext, String expression) {
43
44 Annotation securityAnnotation = getSecurityAnnotation(facesContext, expression);
45 if (securityAnnotation == null) {
46 return true;
47 }
48
49 if (securityAnnotation instanceof DenyAll) {
50 if (LOG.isDebugEnabled()) {
51 LOG.debug("DenyAll");
52 }
53 return false;
54 }
55 if (securityAnnotation instanceof RolesAllowed) {
56 String [] roles = ((RolesAllowed) securityAnnotation).value();
57 if (LOG.isDebugEnabled()) {
58 LOG.debug("RolesAllowed " + Arrays.asList(((RolesAllowed) securityAnnotation).value()));
59 }
60 for (String role : roles) {
61 boolean authorised = facesContext.getExternalContext().isUserInRole(role);
62 if (authorised) {
63 return true;
64 }
65 }
66 return false;
67 }
68 if (securityAnnotation instanceof PermitAll) {
69 if (LOG.isDebugEnabled()) {
70 LOG.debug("PermitAll");
71 }
72 return true;
73 }
74 return true;
75 }
76
77 private static Annotation getSecurityAnnotations(AnnotatedElement annotatedElement) {
78 Annotation annotation = annotatedElement.getAnnotation(RolesAllowed.class);
79 if (annotation != null) {
80 return annotation;
81 }
82 annotation = annotatedElement.getAnnotation(DenyAll.class);
83 if (annotation != null) {
84 return annotation;
85 }
86 annotation = annotatedElement.getAnnotation(PermitAll.class);
87 if (annotation != null) {
88 return annotation;
89 }
90 return null;
91 }
92
93 private static Annotation getSecurityAnnotation(FacesContext facesContext, String expression) {
94 if (AUTHORISATION_CACHE.containsKey(expression)) {
95 Object obj = AUTHORISATION_CACHE.get(expression);
96 if (obj instanceof Annotation) {
97 return (Annotation) obj;
98 }
99 return null;
100 } else {
101 Annotation securityAnnotation = null;
102 if (expression.startsWith("#{") && expression.endsWith("}")) {
103 expression = expression.substring(2, expression.length()-1);
104 int index = expression.lastIndexOf('.');
105 if (index != -1) {
106 String methodExpression = expression.substring(index+1, expression.length());
107 String beanExpression = expression.substring(0, index);
108
109 Object bean =
110 facesContext.getApplication().getVariableResolver().resolveVariable(facesContext, beanExpression);
111 if (bean != null) {
112 try {
113 Method method = bean.getClass().getMethod(methodExpression);
114 securityAnnotation = getSecurityAnnotations(method);
115 if (securityAnnotation == null) {
116 securityAnnotation = getSecurityAnnotations(bean.getClass());
117 }
118 } catch (NoSuchMethodException e) {
119 LOG.error("No Method " + methodExpression + " in class " + bean.getClass(), e);
120 }
121 }
122 }
123 }
124 if (securityAnnotation != null) {
125 AUTHORISATION_CACHE.put(expression, securityAnnotation);
126 } else {
127 AUTHORISATION_CACHE.put(expression, NULL_VALUE);
128 }
129 return securityAnnotation;
130 }
131 }
132 }
133