001: /*
002: * DefaultRealmAuthenticationProvider.java
003: *
004: * Created on November 12, 2006, 10:22 AM
005: *
006: * To change this template, choose Tools | Template Manager
007: * and open the template in the editor.
008: */
009:
010: package com.sun.xml.wss.impl.misc;
011:
012: import com.sun.xml.wss.RealmAuthenticationAdapter;
013: import com.sun.xml.wss.XWSSecurityException;
014: import com.sun.xml.wss.impl.MessageConstants;
015: import java.io.File;
016: import java.io.IOException;
017: import java.security.AccessController;
018: import java.security.Principal;
019: import java.security.PrivilegedAction;
020: import java.util.HashMap;
021: import javax.security.auth.Subject;
022: import javax.security.auth.callback.Callback;
023: import javax.security.auth.callback.CallbackHandler;
024: import javax.security.auth.message.callback.CallerPrincipalCallback;
025: import javax.security.auth.message.callback.PasswordValidationCallback;
026: import javax.security.auth.x500.X500Principal;
027: import javax.xml.parsers.DocumentBuilder;
028: import javax.xml.parsers.DocumentBuilderFactory;
029: import javax.xml.parsers.ParserConfigurationException;
030: import org.w3c.dom.Document;
031: import org.w3c.dom.NamedNodeMap;
032: import org.w3c.dom.Node;
033: import org.w3c.dom.NodeList;
034: import org.xml.sax.SAXException;
035:
036: /**
037: *
038: * @author kumar jayanti
039: */
040: public class DefaultRealmAuthenticationAdapter extends
041: RealmAuthenticationAdapter {
042:
043: private CallbackHandler gfCallbackHandler = null;
044: private HashMap tomcatUsersXML = null;
045:
046: private static DocumentBuilderFactory dbf = DocumentBuilderFactory
047: .newInstance();
048:
049: private static String classname = "com.sun.enterprise.security.jmac.callback.ContainerCallbackHandler";
050:
051: /*
052: static {
053: dbf.setNamespaceAware(true);
054: }*/
055:
056: /** Creates a new instance of DefaultRealmAuthenticationProvider */
057: public DefaultRealmAuthenticationAdapter() {
058: if (isGlassfish()) {
059: gfCallbackHandler = this .loadGFHandler();
060: } else if (isTomcat()) {
061: populateTomcatUsersXML();
062: }
063: }
064:
065: private boolean isGlassfish() {
066: String val = System.getProperty("com.sun.aas.installRoot");
067: if (val != null) {
068: return true;
069: }
070: return false;
071: }
072:
073: private boolean isTomcat() {
074: String val = System.getProperty("catalina.home");
075: String val1 = System.getProperty("com.sun.aas.installRoot");
076: if ((val1 == null) && (val != null)) {
077: return true;
078: }
079: return false;
080: }
081:
082: private boolean authenticateFromTomcatUsersXML(
083: final Subject callerSubject, final String username,
084: final String password) throws XWSSecurityException {
085: if (tomcatUsersXML != null) {
086: String pass = (String) tomcatUsersXML.get(username);
087: if (pass == null) {
088: return false;
089: }
090: if (pass.equals(password)) {
091: //populate the subject
092: AccessController.doPrivileged(new PrivilegedAction() {
093:
094: public Object run() {
095: String x500Name = "CN=" + username;
096: Principal principal = new X500Principal(
097: x500Name);
098: callerSubject.getPrincipals().add(principal);
099: if (password != null) {
100: callerSubject.getPrivateCredentials().add(
101: password);
102: }
103: return null; // nothing to return
104: }
105: });
106: return true;
107: } else {
108: return false;
109: }
110:
111: } else {
112: throw new XWSSecurityException(
113: "Internal Error: Username Authentication Failed: Could not Load/Locate tomcat-users.xml, Possible Cause is Application is Not Running on TOMCAT ?");
114: }
115: }
116:
117: private boolean authenticateWithGFCBH(Subject callerSubject,
118: String username, String password)
119: throws XWSSecurityException {
120: if (gfCallbackHandler != null) {
121: char[] pwd = (password == null) ? null : password
122: .toCharArray();
123: PasswordValidationCallback pvCallback = new PasswordValidationCallback(
124: callerSubject, username, pwd);
125: Callback[] callbacks = new Callback[] { pvCallback };
126: try {
127: gfCallbackHandler.handle(callbacks);
128: } catch (Exception e) {
129: throw new XWSSecurityException(e);
130: }
131:
132: // zero the password
133: if (pwd != null)
134: pvCallback.clearPassword();
135:
136: boolean result = pvCallback.getResult();
137: if (result) {
138: //invoke the CallerPrincipalCallback
139: CallerPrincipalCallback pCallback = new CallerPrincipalCallback(
140: callerSubject, username);
141: callbacks = new Callback[] { pCallback };
142: try {
143: gfCallbackHandler.handle(callbacks);
144: } catch (Exception e) {
145: throw new XWSSecurityException(e);
146: }
147: return result;
148: } else {
149: return result;
150: }
151: } else {
152: throw new XWSSecurityException(
153: "Internal Error: Username Authentication Failed: Could not Locate/Load CallbackHandler: "
154: + classname);
155: }
156: }
157:
158: public boolean authenticate(Subject callerSubject, String username,
159: String password) throws XWSSecurityException {
160: if (isGlassfish()) {
161: return authenticateWithGFCBH(callerSubject, username,
162: password);
163:
164: } else if (isTomcat()) {
165: return authenticateFromTomcatUsersXML(callerSubject,
166: username, password);
167: } else {
168: throw new XWSSecurityException(
169: "Error: Could not locate default username validator for the container");
170: }
171: }
172:
173: protected CallbackHandler loadGFHandler() {
174:
175: Class ret = null;
176: try {
177:
178: ClassLoader loader = Thread.currentThread()
179: .getContextClassLoader();
180: try {
181: if (loader != null) {
182: ret = loader.loadClass(classname);
183: }
184: } catch (ClassNotFoundException e) {
185: // throw new RuntimeException(e);
186: }
187:
188: if (ret == null) {
189: // if context classloader didnt work, try this
190: loader = this .getClass().getClassLoader();
191: ret = loader.loadClass(classname);
192: }
193:
194: if (ret != null) {
195: CallbackHandler handler = (CallbackHandler) ret
196: .newInstance();
197: return handler;
198: }
199: } catch (ClassNotFoundException e) {
200: // ignore
201: //throw new RuntimeException(e);
202:
203: } catch (InstantiationException e) {
204: //throw new RuntimeException(e);
205: } catch (IllegalAccessException ex) {
206: //throw new RuntimeException(ex);
207: }
208: //throw new RuntimeException("Internal Error: Could Not Load CallbackHandler Class: " + classname);
209: return null;
210: }
211:
212: private void populateTomcatUsersXML() {
213: String catalinaHome = System.getProperty("catalina.home");
214:
215: String tomcat_user_xml = catalinaHome + File.separator + "conf"
216: + File.separator + "tomcat-users.xml";
217:
218: try {
219: File tomcatUserXML = new File(tomcat_user_xml);
220: if (!tomcatUserXML.exists()) {
221: // this may not be a TOMCAT system although catalina.home is set.
222: //TODO Issue a FINE LOG here
223: return;
224: }
225: DocumentBuilder builder = dbf.newDocumentBuilder();
226: Document doc = builder.parse(tomcatUserXML);
227: NodeList nl = doc.getElementsByTagName("user");
228: tomcatUsersXML = new HashMap();
229:
230: for (int i = 0; i < nl.getLength(); i++) {
231: Node n = nl.item(i);
232: NamedNodeMap nmap = n.getAttributes();
233: Node un = nmap.getNamedItem("username");
234: Node pn = nmap.getNamedItem("password");
235: tomcatUsersXML
236: .put(un.getNodeValue(), pn.getNodeValue());
237: if (MessageConstants.debug) {
238: System.out.println("Entered : U="
239: + un.getNodeValue() + ": P="
240: + pn.getNodeValue());
241: }
242: }
243: } catch (ParserConfigurationException ex) {
244: throw new RuntimeException(ex);
245: } catch (SAXException e) {
246: throw new RuntimeException(e);
247: } catch (IOException ie) {
248: throw new RuntimeException(ie);
249: }
250: }
251: }
|