View Javadoc

1   /* Copyright 2004, 2005 Acegi Technology Pty Limited
2    *
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    *     http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  package org.acegisecurity.taglibs.authz;
17  
18  import org.acegisecurity.Authentication;
19  
20  import org.acegisecurity.context.SecurityContext;
21  import org.acegisecurity.context.SecurityContextHolder;
22  import org.acegisecurity.userdetails.UserDetails;
23  
24  import java.io.IOException;
25  
26  import java.lang.reflect.InvocationTargetException;
27  import java.lang.reflect.Method;
28  
29  import java.util.HashSet;
30  import java.util.Set;
31  
32  import javax.servlet.jsp.JspException;
33  import javax.servlet.jsp.tagext.Tag;
34  import javax.servlet.jsp.tagext.TagSupport;
35  
36  
37  /***
38   * An {@link javax.servlet.jsp.tagext.Tag} implementation that allows
39   * convenient access to the current <code>Authentication</code> object.
40   * 
41   * <p>
42   * Whilst JSPs can access the <code>SecurityContext</code> directly, this tag
43   * avoids handling <code>null</code> conditions. The tag also properly
44   * accommodates <code>Authentication.getPrincipal()</code>, which can either
45   * be a <code>String</code> or a <code>UserDetails</code>.
46   * </p>
47   *
48   * @author Ben Alex
49   * @version $Id: AuthenticationTag.java,v 1.10 2005/11/29 13:10:10 benalex Exp $
50   */
51  public class AuthenticationTag extends TagSupport {
52      //~ Static fields/initializers =============================================
53  
54      private final static Set methodPrefixValidOptions = new HashSet();
55  
56      static {
57          methodPrefixValidOptions.add("get");
58          methodPrefixValidOptions.add("is");
59      }
60  
61      //~ Instance fields ========================================================
62  
63      private String methodPrefix = "get";
64      private String operation = "";
65  
66      //~ Methods ================================================================
67  
68      public void setMethodPrefix(String methodPrefix) {
69          this.methodPrefix = methodPrefix;
70      }
71  
72      public String getMethodPrefix() {
73          return methodPrefix;
74      }
75  
76      public void setOperation(String operation) {
77          this.operation = operation;
78      }
79  
80      public String getOperation() {
81          return operation;
82      }
83  
84      public int doStartTag() throws JspException {
85          if ((null == operation) || "".equals(operation)) {
86              return Tag.SKIP_BODY;
87          }
88  
89          validateArguments();
90  
91          if ((SecurityContextHolder.getContext() == null)
92              || !(SecurityContextHolder.getContext() instanceof SecurityContext)
93              || (((SecurityContext) SecurityContextHolder.getContext())
94              .getAuthentication() == null)) {
95              return Tag.SKIP_BODY;
96          }
97  
98          Authentication auth = SecurityContextHolder.getContext()
99                                                     .getAuthentication();
100 
101         if (auth.getPrincipal() == null) {
102             return Tag.SKIP_BODY;
103         } else if (auth.getPrincipal() instanceof UserDetails) {
104             writeMessage(invokeOperation(auth.getPrincipal()));
105 
106             return Tag.SKIP_BODY;
107         } else {
108             writeMessage(auth.getPrincipal().toString());
109 
110             return Tag.SKIP_BODY;
111         }
112     }
113 
114     protected String invokeOperation(Object obj) throws JspException {
115         Class clazz = obj.getClass();
116         String methodToInvoke = getOperation();
117         StringBuffer methodName = new StringBuffer();
118         methodName.append(getMethodPrefix());
119         methodName.append(methodToInvoke.substring(0, 1).toUpperCase());
120         methodName.append(methodToInvoke.substring(1));
121 
122         Method method = null;
123 
124         try {
125             method = clazz.getMethod(methodName.toString(), (Class[]) null);
126         } catch (SecurityException se) {
127             throw new JspException(se);
128         } catch (NoSuchMethodException nsme) {
129             throw new JspException(nsme);
130         }
131 
132         Object retVal = null;
133 
134         try {
135             retVal = method.invoke(obj, (Object[]) null);
136         } catch (IllegalArgumentException iae) {
137             throw new JspException(iae);
138         } catch (IllegalAccessException iae) {
139             throw new JspException(iae);
140         } catch (InvocationTargetException ite) {
141             throw new JspException(ite);
142         }
143 
144         if (retVal == null) {
145             retVal = "";
146         }
147 
148         return retVal.toString();
149     }
150 
151     protected void validateArguments() throws JspException {
152         if ((getMethodPrefix() != null) && !getMethodPrefix().equals("")) {
153             if (!methodPrefixValidOptions.contains(getMethodPrefix())) {
154                 throw new JspException(
155                     "Authorization tag : no valid method prefix available");
156             }
157         } else {
158             throw new JspException(
159                 "Authorization tag : no method prefix available");
160         }
161     }
162 
163     protected void writeMessage(String msg) throws JspException {
164         try {
165             pageContext.getOut().write(String.valueOf(msg));
166         } catch (IOException ioe) {
167             throw new JspException(ioe);
168         }
169     }
170 }