KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > net > axis > server > JBossAuthorizationHandler


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7
8 // $Id: JBossAuthorizationHandler.java,v 1.4.6.1 2005/03/02 14:19:51 tdiesler Exp $
9

10 package org.jboss.net.axis.server;
11
12 import org.jboss.axis.AxisFault;
13 import org.jboss.axis.MessageContext;
14 import org.jboss.axis.handlers.BasicHandler;
15 import org.jboss.security.AnybodyPrincipal;
16 import org.jboss.security.NobodyPrincipal;
17 import org.jboss.security.RealmMapping;
18 import org.jboss.security.SimplePrincipal;
19
20 import javax.naming.InitialContext JavaDoc;
21 import javax.naming.NamingException JavaDoc;
22 import javax.security.auth.Subject JavaDoc;
23 import java.security.Principal JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Set JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29
30 /**
31  * AuthorizationHandler that checks allowed and denied roles against the active
32  * subject using a given realmMapping. Is somehow redundant to what, e.g., the JBoss EJB invocation handler
33  * does, but maybe we need this to shield access to other container resources
34  * such as MBeans for which we will expose security-agnostic providers.
35  * <br>
36  * <h3>Change History</h3>
37  * <ul>
38  * <li> jung, 15.03.2002: Added security domain option. </li>
39  * </ul>
40  * <br>
41  * <h3>To Do</h3>
42  * <ul>
43  * <li> jung, 14.03.2002: Cache simple principals. Principal factory for
44  * interacting with various security domains.
45  * </ul>
46  * @author <a HREF="mailto:Christoph.Jung@infor.de">Christoph G. Jung</a>
47  * @created 14.03.2002
48  * @version $Revision: 1.4.6.1 $
49  */

50
51 public class JBossAuthorizationHandler extends BasicHandler
52 {
53
54    //
55
// Attributes
56
//
57

58    /** the security domain against which we call */
59    protected RealmMapping realmMapping;
60    /** the roles that we want to let through */
61    final protected Set JavaDoc rolesAllowed = new java.util.HashSet JavaDoc();
62    /** the roles that we want to deny access */
63    final protected Set JavaDoc rolesDenied = new java.util.HashSet JavaDoc();
64    /** whether this handler has been initialized */
65    protected boolean isInitialised;
66
67    //
68
// Constructors
69
//
70

71    public JBossAuthorizationHandler()
72    {
73    }
74
75    //
76
// Protected helpers
77
//
78

79    /** initializes the roles checked by this handler */
80    protected void initialise() throws AxisFault
81    {
82       // bind against the jboss security subsystem
83
isInitialised = true;
84       realmMapping = null;
85       String JavaDoc securityDomain = (String JavaDoc)getOption(Constants.SECURITY_DOMAIN_OPTION);
86       if (securityDomain != null)
87       {
88          try
89          {
90             realmMapping =
91                     (RealmMapping)new InitialContext JavaDoc().lookup(securityDomain);
92          }
93          catch (NamingException JavaDoc e)
94          {
95             throw new AxisFault("Could not lookup security domain " + securityDomain, e);
96          }
97       }
98
99       // parse role options
100
String JavaDoc allowedRoles = (String JavaDoc)getOption(Constants.ALLOWED_ROLES_OPTION);
101
102       // default:let all through
103
if (allowedRoles == null)
104       {
105          allowedRoles = "*";
106       }
107
108       StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(allowedRoles, ",");
109       while (tokenizer.hasMoreTokens())
110       {
111          rolesAllowed.add(getPrincipal(tokenizer.nextToken()));
112       }
113
114       String JavaDoc deniedRoles = (String JavaDoc)getOption(Constants.DENIED_ROLES_OPTION);
115       if (deniedRoles != null)
116       {
117          tokenizer = new StringTokenizer JavaDoc(deniedRoles, ",");
118          while (tokenizer.hasMoreTokens())
119          {
120             rolesDenied.add(getPrincipal(tokenizer.nextToken()));
121          }
122       }
123    }
124
125    /**
126     * creates a new principal belonging to the given username,
127     * override to adapt to specific security domains.
128     */

129    protected Principal getPrincipal(String JavaDoc userName)
130    {
131       if (userName.equals("*"))
132       {
133          return AnybodyPrincipal.ANYBODY_PRINCIPAL;
134       }
135       else
136       {
137          return new SimplePrincipal(userName);
138       }
139    }
140
141    /** returns a collection of principals that the context subject
142     * is associated with
143     */

144    protected Collection JavaDoc getAssociatedPrincipals(MessageContext msgContext)
145    {
146       // get the active subject
147
Subject JavaDoc activeSubject =
148               (Subject JavaDoc)msgContext.getProperty(MessageContext.AUTHUSER);
149       if (activeSubject == null)
150       {
151          return Collections.singleton(NobodyPrincipal.NOBODY_PRINCIPAL);
152       }
153       else
154       {
155          return activeSubject.getPrincipals();
156       }
157    }
158
159    /** return whether the given Principal has the given roles */
160    protected boolean doesUserHaveRole(Principal principal, Set JavaDoc roles)
161    {
162       return realmMapping.doesUserHaveRole(principal, roles);
163    }
164
165    //
166
// API
167
//
168

169    /**
170     * Authenticate the user and password from the msgContext. Note that
171     * we do not disassociate the subject here, since that would have
172     * to be done by a separate handler in the response chain and we
173     * currently expect Jetty or the WebContainer to do that for us
174     */

175
176    public void invoke(MessageContext msgContext) throws AxisFault
177    {
178
179       // initialize the handler
180
if (!isInitialised)
181       {
182          synchronized (this)
183          {
184             if (!isInitialised)
185             {
186                initialise();
187             }
188          }
189       }
190
191       // check association
192
if (realmMapping == null)
193       {
194          throw new AxisFault("No security domain associated.");
195       }
196
197       Iterator JavaDoc allPrincipals = getAssociatedPrincipals(msgContext).iterator();
198       boolean accessAllowed = false;
199       while (allPrincipals.hasNext())
200       {
201          Principal nextPrincipal = (Principal)allPrincipals.next();
202          // a single denied is enough to exclude the access
203
if (doesUserHaveRole(nextPrincipal, rolesDenied))
204          {
205             accessAllowed = false;
206             break;
207             // allowed
208
}
209          else if (!accessAllowed && doesUserHaveRole(nextPrincipal, rolesAllowed))
210          {
211             accessAllowed = true;
212          }
213       }
214
215       if (!accessAllowed)
216       {
217          throw new AxisFault("Access denied.");
218       }
219    }
220 }
Popular Tags