View Javadoc

1   /* Copyright 2004, 2005, 2006 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  
23  import org.acegisecurity.userdetails.UserDetails;
24  
25  import java.io.IOException;
26  
27  import java.lang.reflect.InvocationTargetException;
28  import java.lang.reflect.Method;
29  
30  import java.util.HashSet;
31  import java.util.Set;
32  
33  import javax.servlet.jsp.JspException;
34  import javax.servlet.jsp.tagext.Tag;
35  import javax.servlet.jsp.tagext.TagSupport;
36  
37  
38  /**
39   * An {@link javax.servlet.jsp.tagext.Tag} implementation that allows convenient access to the current
40   * <code>Authentication</code> object.<p>Whilst JSPs can access the <code>SecurityContext</code> directly, this tag
41   * avoids handling <code>null</code> conditions. The tag also properly accommodates
42   * <code>Authentication.getPrincipal()</code>, which can either be a <code>String</code> or a
43   * <code>UserDetails</code>.</p>
44   *
45   * @author Ben Alex
46   * @version $Id: AuthenticationTag.java 1784 2007-02-24 21:00:24Z luke_t $
47   */
48  public class AuthenticationTag extends TagSupport {
49      //~ Static fields/initializers =====================================================================================
50  
51      private static final Set methodPrefixValidOptions = new HashSet();
52  
53      static {
54          methodPrefixValidOptions.add("get");
55          methodPrefixValidOptions.add("is");
56      }
57  
58      //~ Instance fields ================================================================================================
59  
60      private String methodPrefix = "get";
61      private String operation = "";
62  
63      //~ Methods ========================================================================================================
64  
65      public int doStartTag() throws JspException {
66          if ((null == operation) || "".equals(operation)) {
67              return Tag.SKIP_BODY;
68          }
69  
70          validateArguments();
71  
72          if ((SecurityContextHolder.getContext() == null)
73              || !(SecurityContextHolder.getContext() instanceof SecurityContext)
74              || (((SecurityContext) SecurityContextHolder.getContext()).getAuthentication() == null)) {
75              return Tag.SKIP_BODY;
76          }
77  
78          Authentication auth = SecurityContextHolder.getContext().getAuthentication();
79  
80          if (auth.getPrincipal() == null) {
81              return Tag.SKIP_BODY;
82          } else if (auth.getPrincipal() instanceof UserDetails) {
83              writeMessage(invokeOperation(auth.getPrincipal()));
84  
85              return Tag.SKIP_BODY;
86          } else {
87              writeMessage(auth.getPrincipal().toString());
88  
89              return Tag.SKIP_BODY;
90          }
91      }
92  
93      public String getMethodPrefix() {
94          return methodPrefix;
95      }
96  
97      public String getOperation() {
98          return operation;
99      }
100 
101     protected String invokeOperation(Object obj) throws JspException {
102         Class clazz = obj.getClass();
103         String methodToInvoke = getOperation();
104         StringBuffer methodName = new StringBuffer();
105         methodName.append(getMethodPrefix());
106         methodName.append(methodToInvoke.substring(0, 1).toUpperCase());
107         methodName.append(methodToInvoke.substring(1));
108 
109         Method method = null;
110 
111         try {
112             method = clazz.getMethod(methodName.toString(), (Class[]) null);
113         } catch (SecurityException se) {
114             throw new JspException(se);
115         } catch (NoSuchMethodException nsme) {
116             throw new JspException(nsme);
117         }
118 
119         Object retVal = null;
120 
121         try {
122             retVal = method.invoke(obj, (Object[]) null);
123         } catch (IllegalArgumentException iae) {
124             throw new JspException(iae);
125         } catch (IllegalAccessException iae) {
126             throw new JspException(iae);
127         } catch (InvocationTargetException ite) {
128             throw new JspException(ite);
129         }
130 
131         if (retVal == null) {
132             retVal = "";
133         }
134 
135         return retVal.toString();
136     }
137 
138     public void setMethodPrefix(String methodPrefix) {
139         this.methodPrefix = methodPrefix;
140     }
141 
142     public void setOperation(String operation) {
143         this.operation = operation;
144     }
145 
146     protected void validateArguments() throws JspException {
147         if ((getMethodPrefix() != null) && !getMethodPrefix().equals("")) {
148             if (!methodPrefixValidOptions.contains(getMethodPrefix())) {
149                 throw new JspException("Authorization tag : no valid method prefix available");
150             }
151         } else {
152             throw new JspException("Authorization tag : no method prefix available");
153         }
154     }
155 
156     protected void writeMessage(String msg) throws JspException {
157         try {
158             pageContext.getOut().write(String.valueOf(msg));
159         } catch (IOException ioe) {
160             throw new JspException(ioe);
161         }
162     }
163 }