KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > resource > security > SecureIdentityLoginModule


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.resource.security;
23
24 import java.security.acl.Group JavaDoc;
25 import java.security.Principal JavaDoc;
26 import java.security.NoSuchAlgorithmException JavaDoc;
27 import java.security.InvalidKeyException JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.math.BigInteger JavaDoc;
30 import javax.resource.spi.security.PasswordCredential JavaDoc;
31 import javax.security.auth.Subject JavaDoc;
32 import javax.security.auth.callback.CallbackHandler JavaDoc;
33 import javax.security.auth.login.LoginException JavaDoc;
34 import javax.crypto.NoSuchPaddingException;
35 import javax.crypto.BadPaddingException;
36 import javax.crypto.IllegalBlockSizeException;
37 import javax.crypto.Cipher;
38 import javax.crypto.spec.SecretKeySpec;
39
40 import org.jboss.security.SimplePrincipal;
41 import org.jboss.logging.Logger;
42
43 /** An example of how one could encrypt the database password for a jca
44   connection factory. The corresponding
45  
46 <application-policy name = "HsqlDbRealm">
47    <authentication>
48       <login-module code = "org.jboss.resource.security.SecureIdentityLoginMdule"
49          flag = "required">
50          <module-option name = "userName">sa</module-option>
51          <module-option name = "password">-207a6df87216de44</module-option>
52          <module-option name = "managedConnectionFactoryName">jboss.jca:servce=LocalTxCM,name=DefaultDS</module-option>
53       </login-module>
54    </authentication>
55 </application-policy>
56
57  This uses a hard-coded cipher algo of Blowfish, and key derived from the
58  phrase 'jaas is the way'. Adjust to your requirements.
59
60  * @author Scott.Stark@jboss.org
61  * @author <a HREF="mailto:noel.rocher@jboss.org">Noel Rocher</a> 29, june 2004 username & userName issue
62  * @version $Revision: 37459 $
63  */

64 public class SecureIdentityLoginModule
65    extends AbstractPasswordCredentialLoginModule
66 {
67    /**
68     * Class logger
69     */

70    private static final Logger log = Logger.getLogger(SecureIdentityLoginModule.class);
71
72    private String JavaDoc username;
73    private String JavaDoc password;
74
75    public void initialize(Subject JavaDoc subject, CallbackHandler JavaDoc handler, Map JavaDoc sharedState, Map JavaDoc options)
76    {
77       super.initialize(subject, handler, sharedState, options);
78       // NR : we keep this username for compatibility
79
username = (String JavaDoc) options.get("username");
80       if( username == null )
81       {
82         // NR : try with userName
83
username = (String JavaDoc) options.get("userName");
84         if( username == null )
85         {
86          throw new IllegalArgumentException JavaDoc("The user name is a required option");
87         }
88      }
89       password = (String JavaDoc) options.get("password");
90       if( password == null )
91       {
92          throw new IllegalArgumentException JavaDoc("The password is a required option");
93       }
94    }
95
96    public boolean login() throws LoginException JavaDoc
97    {
98       log.trace("login called");
99       if( super.login() == true )
100          return true;
101
102       super.loginOk = true;
103       return true;
104    }
105
106    public boolean commit() throws LoginException JavaDoc
107    {
108       Principal JavaDoc principal = new SimplePrincipal(username);
109       SubjectActions.addPrincipals(subject, principal);
110       sharedState.put("javax.security.auth.login.name", username);
111       // Decode the encrypted password
112
try
113       {
114          char[] decodedPassword = decode(password);
115          PasswordCredential JavaDoc cred = new PasswordCredential JavaDoc(username, decodedPassword);
116          cred.setManagedConnectionFactory(getMcf());
117          SubjectActions.addCredentials(subject, cred);
118       }
119       catch(Exception JavaDoc e)
120       {
121          log.debug("Failed to decode password", e);
122          throw new LoginException JavaDoc("Failed to decode password: "+e.getMessage());
123       }
124       return true;
125    }
126
127    public boolean abort()
128    {
129       username = null;
130       password = null;
131       return true;
132    }
133
134    protected Principal JavaDoc getIdentity()
135    {
136       log.trace("getIdentity called, username="+username);
137       Principal JavaDoc principal = new SimplePrincipal(username);
138       return principal;
139    }
140
141    protected Group JavaDoc[] getRoleSets() throws LoginException JavaDoc
142    {
143       Group JavaDoc[] empty = new Group JavaDoc[0];
144       return empty;
145    }
146
147    private static String JavaDoc encode(String JavaDoc secret)
148       throws NoSuchPaddingException, NoSuchAlgorithmException JavaDoc,
149       InvalidKeyException JavaDoc, BadPaddingException, IllegalBlockSizeException
150    {
151       byte[] kbytes = "jaas is the way".getBytes();
152       SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");
153
154       Cipher cipher = Cipher.getInstance("Blowfish");
155       cipher.init(Cipher.ENCRYPT_MODE, key);
156       byte[] encoding = cipher.doFinal(secret.getBytes());
157       BigInteger JavaDoc n = new BigInteger JavaDoc(encoding);
158       return n.toString(16);
159    }
160
161    private static char[] decode(String JavaDoc secret)
162       throws NoSuchPaddingException, NoSuchAlgorithmException JavaDoc,
163       InvalidKeyException JavaDoc, BadPaddingException, IllegalBlockSizeException
164    {
165       byte[] kbytes = "jaas is the way".getBytes();
166       SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");
167
168       BigInteger JavaDoc n = new BigInteger JavaDoc(secret, 16);
169       byte[] encoding = n.toByteArray();
170       
171       Cipher cipher = Cipher.getInstance("Blowfish");
172       cipher.init(Cipher.DECRYPT_MODE, key);
173       byte[] decode = cipher.doFinal(encoding);
174       return new String JavaDoc(decode).toCharArray();
175    }
176
177    /** Main entry point to encrypt a password using the hard-coded pass phrase
178     *
179     * @param args - [0] = the password to encode
180     * @throws Exception
181     */

182    public static void main(String JavaDoc[] args) throws Exception JavaDoc
183    {
184       String JavaDoc encode = encode(args[0]);
185       System.out.println("Encoded password: "+encode);
186    }
187 }
188
Popular Tags