001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015:
016: package org.acegisecurity.adapters.jetty;
017:
018: import org.acegisecurity.Authentication;
019: import org.acegisecurity.AuthenticationException;
020: import org.acegisecurity.AuthenticationManager;
021:
022: import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026:
027: import org.mortbay.http.HttpRequest;
028: import org.mortbay.http.UserPrincipal;
029: import org.mortbay.http.UserRealm;
030:
031: import org.springframework.context.support.ClassPathXmlApplicationContext;
032:
033: import java.util.Map;
034:
035: /**
036: * Adapter to enable Jetty to authenticate via the Acegi Security System for Spring.<p>Returns a {@link
037: * JettyAcegiUserToken} to Jetty's authentication system, which is subsequently available via
038: * <code>HttpServletRequest.getUserPrincipal()</code>.</p>
039: *
040: * @author Ben Alex
041: * @version $Id: JettyAcegiUserRealm.java 1496 2006-05-23 13:38:33Z benalex $
042: */
043: public final class JettyAcegiUserRealm implements UserRealm {
044: //~ Static fields/initializers =====================================================================================
045:
046: private static final Log logger = LogFactory
047: .getLog(JettyAcegiUserRealm.class);
048:
049: //~ Instance fields ================================================================================================
050:
051: private AuthenticationManager authenticationManager;
052: private String key;
053: private String realm;
054:
055: //~ Constructors ===================================================================================================
056:
057: /**
058: * Construct a <code>SpringUserRealm</code>.
059: *
060: * @param realm the name of the authentication realm (within Jetty)
061: * @param providerKey a password to sign all authentication objects
062: * @param appContextLocation the classpath location of the bean context XML
063: * file
064: *
065: * @throws IllegalArgumentException DOCUMENT ME!
066: */
067: public JettyAcegiUserRealm(String realm, String providerKey,
068: String appContextLocation) {
069: this .realm = realm;
070: this .key = providerKey;
071:
072: if ((realm == null) || "".equals(realm)) {
073: throw new IllegalArgumentException(
074: "realm must be specified");
075: }
076:
077: if ((key == null) || "".equals(key)) {
078: throw new IllegalArgumentException("key must be specified");
079: }
080:
081: if ((appContextLocation == null)
082: || "".equals(appContextLocation)) {
083: throw new IllegalArgumentException(
084: "appContextLocation must be specified");
085: }
086:
087: if (Thread.currentThread().getContextClassLoader().getResource(
088: appContextLocation) == null) {
089: throw new IllegalArgumentException("Cannot locate "
090: + appContextLocation);
091: }
092:
093: ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
094: appContextLocation);
095: Map beans = ctx.getBeansOfType(AuthenticationManager.class,
096: true, true);
097:
098: if (beans.size() == 0) {
099: throw new IllegalArgumentException(
100: "Bean context must contain at least one bean of type AuthenticationManager");
101: }
102:
103: String beanName = (String) beans.keySet().iterator().next();
104: authenticationManager = (AuthenticationManager) beans
105: .get(beanName);
106: }
107:
108: protected JettyAcegiUserRealm() {
109: throw new IllegalArgumentException(
110: "Cannot use default constructor");
111: }
112:
113: //~ Methods ========================================================================================================
114:
115: public UserPrincipal authenticate(String username, Object password,
116: HttpRequest httpRequest) {
117: if (username == null) {
118: return null;
119: }
120:
121: if (password == null) {
122: password = "";
123: }
124:
125: Authentication request = new UsernamePasswordAuthenticationToken(
126: username.toString(), password.toString());
127: Authentication response = null;
128:
129: try {
130: response = authenticationManager.authenticate(request);
131: } catch (AuthenticationException failed) {
132: if (logger.isDebugEnabled()) {
133: logger.debug("Authentication request for user: "
134: + username + " failed: " + failed.toString());
135: }
136:
137: return null;
138: }
139:
140: return new JettyAcegiUserToken(this .key, response
141: .getPrincipal().toString(), response.getCredentials()
142: .toString(), response.getAuthorities());
143: }
144:
145: public void disassociate(UserPrincipal userPrincipal) {
146: // No action required
147: }
148:
149: public AuthenticationManager getAuthenticationManager() {
150: return authenticationManager;
151: }
152:
153: /**
154: * Accesses the realm name.
155: *
156: * @return the name of the realm as defined when <code>SpringUserRealm</code> was created
157: */
158: public String getName() {
159: return this .realm;
160: }
161:
162: public void logout(UserPrincipal arg0) {
163: // Not supported
164: }
165:
166: public UserPrincipal popRole(UserPrincipal userPrincipal) {
167: // Not supported
168: return userPrincipal;
169: }
170:
171: public UserPrincipal pushRole(UserPrincipal userPrincipal,
172: String role) {
173: // Not supported
174: return userPrincipal;
175: }
176: }
|