View Javadoc

1   /* Copyright 2004 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.adapters.jetty;
17  
18  import org.acegisecurity.Authentication;
19  import org.acegisecurity.AuthenticationException;
20  import org.acegisecurity.AuthenticationManager;
21  import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  
26  import org.mortbay.http.HttpRequest;
27  import org.mortbay.http.UserPrincipal;
28  import org.mortbay.http.UserRealm;
29  
30  import org.springframework.context.support.ClassPathXmlApplicationContext;
31  
32  import java.util.Map;
33  
34  
35  /***
36   * Adapter to enable Jetty to authenticate via the Acegi Security System for
37   * Spring.
38   * 
39   * <p>
40   * Returns a {@link JettyAcegiUserToken} to Jetty's authentication system,
41   * which is subsequently available via
42   * <code>HttpServletRequest.getUserPrincipal()</code>.
43   * </p>
44   *
45   * @author Ben Alex
46   * @version $Id: JettyAcegiUserRealm.java,v 1.4 2005/11/17 00:56:28 benalex Exp $
47   */
48  public final class JettyAcegiUserRealm implements UserRealm {
49      //~ Static fields/initializers =============================================
50  
51      private static final Log logger = LogFactory.getLog(JettyAcegiUserRealm.class);
52  
53      //~ Instance fields ========================================================
54  
55      private AuthenticationManager authenticationManager;
56      private String key;
57      private String realm;
58  
59      //~ Constructors ===========================================================
60  
61      /***
62       * Construct a <code>SpringUserRealm</code>.
63       *
64       * @param realm the name of the authentication realm (within Jetty)
65       * @param providerKey a password to sign all authentication objects
66       * @param appContextLocation the classpath location of the bean context XML
67       *        file
68       *
69       * @throws IllegalArgumentException DOCUMENT ME!
70       */
71      public JettyAcegiUserRealm(String realm, String providerKey,
72          String appContextLocation) {
73          this.realm = realm;
74          this.key = providerKey;
75  
76          if ((realm == null) || "".equals(realm)) {
77              throw new IllegalArgumentException("realm must be specified");
78          }
79  
80          if ((key == null) || "".equals(key)) {
81              throw new IllegalArgumentException("key must be specified");
82          }
83  
84          if ((appContextLocation == null) || "".equals(appContextLocation)) {
85              throw new IllegalArgumentException(
86                  "appContextLocation must be specified");
87          }
88  
89          if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) {
90              throw new IllegalArgumentException("Cannot locate "
91                  + appContextLocation);
92          }
93  
94          ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(appContextLocation);
95          Map beans = ctx.getBeansOfType(AuthenticationManager.class, true, true);
96  
97          if (beans.size() == 0) {
98              throw new IllegalArgumentException(
99                  "Bean context must contain at least one bean of type AuthenticationManager");
100         }
101 
102         String beanName = (String) beans.keySet().iterator().next();
103         authenticationManager = (AuthenticationManager) beans.get(beanName);
104     }
105 
106     protected JettyAcegiUserRealm() {
107         throw new IllegalArgumentException("Cannot use default constructor");
108     }
109 
110     //~ Methods ================================================================
111 
112     public AuthenticationManager getAuthenticationManager() {
113         return authenticationManager;
114     }
115 
116     /***
117      * Accesses the realm name.
118      *
119      * @return the name of the realm as defined when
120      *         <code>SpringUserRealm</code> was created
121      */
122     public String getName() {
123         return this.realm;
124     }
125 
126     public UserPrincipal authenticate(String username, Object password,
127         HttpRequest httpRequest) {
128         if (username == null) {
129             return null;
130         }
131 
132         if (password == null) {
133             password = "";
134         }
135 
136         Authentication request = new UsernamePasswordAuthenticationToken(username
137                 .toString(), password.toString());
138         Authentication response = null;
139 
140         try {
141             response = authenticationManager.authenticate(request);
142         } catch (AuthenticationException failed) {
143             if (logger.isDebugEnabled()) {
144                 logger.debug("Authentication request for user: " + username
145                     + " failed: " + failed.toString());
146             }
147 
148             return null;
149         }
150 
151         return new JettyAcegiUserToken(this.key,
152             response.getPrincipal().toString(),
153             response.getCredentials().toString(), response.getAuthorities());
154     }
155 
156     public void disassociate(UserPrincipal userPrincipal) {
157         // No action required
158     }
159 
160     public void logout(UserPrincipal arg0) {
161         // Not supported
162     }
163 
164     public UserPrincipal popRole(UserPrincipal userPrincipal) {
165         // Not supported
166         return userPrincipal;
167     }
168 
169     public UserPrincipal pushRole(UserPrincipal userPrincipal, String role) {
170         // Not supported
171         return userPrincipal;
172     }
173 }