001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.jetty6;
017:
018: import java.security.AccessControlContext;
019: import java.security.AccessControlException;
020: import java.security.Principal;
021: import java.security.cert.X509Certificate;
022: import java.util.HashMap;
023:
024: import javax.security.auth.Subject;
025: import javax.security.auth.login.LoginContext;
026: import javax.security.auth.login.LoginException;
027: import javax.security.jacc.WebRoleRefPermission;
028:
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031: import org.apache.geronimo.security.ContextManager;
032: import org.apache.geronimo.security.realm.providers.CertificateCallbackHandler;
033: import org.apache.geronimo.security.realm.providers.ClearableCallbackHandler;
034: import org.apache.geronimo.security.realm.providers.PasswordCallbackHandler;
035: import org.mortbay.jetty.Request;
036:
037: /**
038: * @version $Rev: 565989 $ $Date: 2007-08-14 17:47:35 -0700 (Tue, 14 Aug 2007) $
039: */
040: public class InternalJAASJettyRealm {
041: private static Log log = LogFactory
042: .getLog(InternalJAASJettyRealm.class);
043:
044: private final String securityRealmName;
045: private final HashMap<String, Principal> userMap = new HashMap<String, Principal>();
046: private int count = 1;
047:
048: public InternalJAASJettyRealm(String geronimoRealmName) {
049: this .securityRealmName = geronimoRealmName;
050: }
051:
052: public String getSecurityRealmName() {
053: return securityRealmName;
054: }
055:
056: public Principal getPrincipal(String username) {
057: return userMap.get(username);
058: }
059:
060: public Principal authenticate(String username, Object credentials,
061: Request request) {
062: try {
063: if ((username != null) && (!username.equals(""))) {
064:
065: JAASJettyPrincipal userPrincipal = (JAASJettyPrincipal) userMap
066: .get(username);
067:
068: //user has been previously authenticated, but
069: //re-authentication has been requested, so remove them
070: if (userPrincipal != null) {
071: userMap.remove(username);
072: }
073:
074: ClearableCallbackHandler callbackHandler;
075: if (credentials instanceof char[]) {
076: char[] password = (char[]) credentials;
077: callbackHandler = new PasswordCallbackHandler(
078: username, password);
079: } else if (credentials instanceof String) {
080: char[] password = ((String) credentials)
081: .toCharArray();
082: callbackHandler = new PasswordCallbackHandler(
083: username, password);
084: } else if (credentials instanceof X509Certificate[]) {
085: X509Certificate[] certs = (X509Certificate[]) credentials;
086: if (certs.length < 1) {
087: throw new LoginException(
088: "no certificates supplied");
089: }
090: callbackHandler = new CertificateCallbackHandler(
091: certs[0]);
092: } else {
093: throw new LoginException(
094: "Cannot extract credentials from class: "
095: + credentials.getClass().getName());
096: }
097:
098: //set up the login context
099: LoginContext loginContext = ContextManager.login(
100: securityRealmName, callbackHandler);
101: callbackHandler.clear();
102:
103: Subject subject = loginContext.getSubject();
104: ContextManager.setCallers(subject, subject);
105:
106: //login success
107: userPrincipal = new JAASJettyPrincipal(username);
108: userPrincipal.setSubject(subject);
109:
110: userMap.put(username, userPrincipal);
111:
112: return userPrincipal;
113: } else {
114: log.debug("Login Failed - null userID");
115: return null;
116: }
117:
118: } catch (LoginException e) {
119: log.debug("Login Failed", e);
120: return null;
121: }
122: }
123:
124: public void logout(Principal user) {
125: JAASJettyPrincipal principal = (JAASJettyPrincipal) user;
126:
127: userMap.remove(principal.getName());
128: ContextManager.unregisterSubject(principal.getSubject());
129: }
130:
131: public boolean reauthenticate(Principal user) {
132: // TODO This is not correct if auth can expire! We need to
133:
134: Subject subject = ((JAASJettyPrincipal) user).getSubject();
135: ContextManager.setCallers(subject, subject);
136:
137: // get the user out of the cache
138: return (userMap.get(user.getName()) != null);
139: }
140:
141: public void disassociate(Principal user) {
142: // do nothing
143: }
144:
145: public boolean isUserInRole(Principal user, String role) {
146: if (user == null || role == null) {
147: return false;
148: }
149:
150: AccessControlContext acc = ContextManager.getCurrentContext();
151: try {
152: // JACC v1.0 secion B.19
153: String servletName = InternalJettyServletHolder
154: .getCurrentServletName();
155: if (servletName == null || servletName.equals("jsp")) {
156: servletName = "";
157: }
158: acc.checkPermission(new WebRoleRefPermission(servletName,
159: role));
160: } catch (AccessControlException e) {
161: return false;
162: }
163: return true;
164: }
165:
166: public Principal pushRole(Principal user, String role) {
167: //handled by JettyServletHolder and its runAsSubject
168: return user;
169: }
170:
171: public Principal popRole(Principal user) {
172: return user;
173: }
174:
175: public void addUse() {
176: count++;
177: }
178:
179: public int removeUse() {
180: return count--;
181: }
182:
183: }
|