1 package org
.argeo
.security
.activemq
;
3 import java
.io
.InputStream
;
4 import java
.security
.KeyStore
;
5 import java
.security
.SecureRandom
;
7 import javax
.jms
.Connection
;
8 import javax
.jms
.ConnectionFactory
;
9 import javax
.jms
.JMSException
;
10 import javax
.net
.ssl
.KeyManagerFactory
;
11 import javax
.net
.ssl
.TrustManagerFactory
;
12 import javax
.swing
.UIManager
;
13 import javax
.swing
.UnsupportedLookAndFeelException
;
14 import javax
.swing
.plaf
.metal
.MetalLookAndFeel
;
16 import org
.apache
.activemq
.ActiveMQSslConnectionFactory
;
17 import org
.apache
.commons
.logging
.Log
;
18 import org
.apache
.commons
.logging
.LogFactory
;
19 import org
.argeo
.ArgeoException
;
20 import org
.argeo
.security
.core
.UserPasswordDialog
;
21 import org
.springframework
.beans
.factory
.DisposableBean
;
22 import org
.springframework
.beans
.factory
.InitializingBean
;
23 import org
.springframework
.core
.io
.Resource
;
24 import org
.springframework
.jms
.connection
.CachingConnectionFactory
;
25 import org
.springframework
.jms
.connection
.UserCredentialsConnectionFactoryAdapter
;
27 public class SecuredActiveMqConnectionFactory
implements ConnectionFactory
,
28 InitializingBean
, DisposableBean
{
30 public final static String AUTHMODE_UI
= "ui";
31 public final static String AUTHMODE_OS
= "os";
32 public final static String AUTHMODE_DEFAULT
= AUTHMODE_OS
;
33 // private final static String LOGIN_CONFIG_PROPERTY = "java.security.auth.login.config";
35 private final static Log log
= LogFactory
36 .getLog(SecuredActiveMqConnectionFactory
.class);
38 private String keyStorePassword
;
39 private Resource keyStore
;
40 private String keyStoreType
= "JKS";// "PKCS12"
41 private String brokerURL
;
43 private String authenticationMode
;
45 private CachingConnectionFactory cachingConnectionFactory
;
47 public Connection
createConnection() throws JMSException
{
48 return cachingConnectionFactory
.createConnection();
51 public Connection
createConnection(String userName
, String password
)
53 throw new UnsupportedOperationException();
56 public void afterPropertiesSet() throws Exception
{
57 ActiveMQSslConnectionFactory activeMQSslConnectionFactory
= new ActiveMQSslConnectionFactory();
58 prepareActiveMqSslConnectionFactory(activeMQSslConnectionFactory
);
59 activeMQSslConnectionFactory
.setBrokerURL(brokerURL
);
60 UserCredentialsConnectionFactoryAdapter uccfa
= new UserCredentialsConnectionFactoryAdapter();
61 uccfa
.setTargetConnectionFactory(activeMQSslConnectionFactory
);
62 cachingConnectionFactory
= new CachingConnectionFactory();
63 cachingConnectionFactory
.setTargetConnectionFactory(uccfa
);
65 initConnectionFactoryCredentials(uccfa
);
66 cachingConnectionFactory
.initConnection();
67 log
.info("Connected to " + brokerURL
);
68 uccfa
.setUsername(null);
69 uccfa
.setPassword(null);
73 protected void initConnectionFactoryCredentials(
74 final UserCredentialsConnectionFactoryAdapter uccfa
) {
75 if (authenticationMode
== null)
76 authenticationMode
= AUTHMODE_DEFAULT
;
78 if (AUTHMODE_OS
.equals(authenticationMode
)) {
80 // // Cache previous value of login conf location
81 // String oldLoginConfLocation = System
82 // .getProperty(LOGIN_CONFIG_PROPERTY);
84 // String osName = System.getProperty("os.name");
86 // if (osName.startsWith("Windows"))
88 // else if (osName.startsWith("SunOS")
89 // || osName.startsWith("Solaris"))
95 // // see http://old.nabble.com/osgi-and-jaas-td23485885.html
96 // ClassLoader ccl = Thread.currentThread()
97 // .getContextClassLoader();
99 // Thread.currentThread().setContextClassLoader(
100 // getClass().getClassLoader());
101 // URL url = getClass().getResource(
102 // "/org/argeo/security/activemq/osLogin.conf");
104 // System.setProperty(LOGIN_CONFIG_PROPERTY, url.toString());
105 // LoginContext lc = new LoginContext(auth);
107 // subject = lc.getSubject();
108 // } catch (LoginException le) {
109 // throw new ArgeoException("OS authentication failed", le);
111 // if (oldLoginConfLocation != null)
112 // System.setProperty(LOGIN_CONFIG_PROPERTY,
113 // oldLoginConfLocation);
114 // Thread.currentThread().setContextClassLoader(ccl);
116 // // Extract user name
117 // String osUsername = null;
118 // for (Principal principal : subject.getPrincipals()) {
119 // String className = principal.getClass().getName();
120 // if ("Unix".equals(auth)
121 // && "com.sun.security.auth.UnixPrincipal"
122 // .equals(className))
123 // osUsername = principal.getName();
124 // else if ("Windows".equals(auth)
125 // && "com.sun.security.auth.NTUserPrincipal"
126 // .equals(className))
127 // osUsername = principal.getName();
128 // else if ("Solaris".equals(auth)
129 // && "com.sun.security.auth.SolarisPrincipal"
130 // .equals(className))
131 // osUsername = principal.getName();
134 // if (osUsername == null)
135 // throw new ArgeoException("Could not find OS user name");
138 uccfa
.setUsername(System
.getProperty("user.name"));
139 uccfa
.setPassword(null);
141 } else if (AUTHMODE_UI
.equals(authenticationMode
)) {
143 UIManager
.setLookAndFeel(new MetalLookAndFeel());
144 } catch (UnsupportedLookAndFeelException e
) {
145 throw new ArgeoException("Cannot load look and feel", e
);
147 UIManager
.put("ClassLoader", getClass().getClassLoader());
148 UserPasswordDialog dialog
= new UserPasswordDialog() {
149 private static final long serialVersionUID
= -891646559691412088L;
151 protected void useCredentials(String username
, char[] password
) {
152 uccfa
.setUsername(username
);
153 uccfa
.setPassword(new String(password
));
156 dialog
.setVisible(true);
158 throw new ArgeoException("Authentication mode '"
159 + authenticationMode
+ "' is not supported");
164 protected void prepareActiveMqSslConnectionFactory(
165 ActiveMQSslConnectionFactory connectionFactory
) {
167 KeyStore keyStoreKs
= KeyStore
.getInstance(keyStoreType
);
169 InputStream keyInput
= keyStore
.getInputStream();
170 keyStoreKs
.load(keyInput
,
171 keyStorePassword
!= null ? keyStorePassword
.toCharArray()
175 TrustManagerFactory tmf
= TrustManagerFactory
176 .getInstance(TrustManagerFactory
.getDefaultAlgorithm());
177 tmf
.init(keyStoreKs
);
179 KeyManagerFactory keyManagerFactory
= KeyManagerFactory
180 .getInstance(KeyManagerFactory
.getDefaultAlgorithm());
181 keyManagerFactory
.init(keyStoreKs
, keyStorePassword
.toCharArray());
183 connectionFactory
.setKeyAndTrustManagers(keyManagerFactory
184 .getKeyManagers(), tmf
.getTrustManagers(),
186 } catch (Exception e
) {
187 throw new ArgeoException(
188 "Cannot initailize JMS conneciton factory", e
);
193 public void destroy() throws Exception
{
194 if (cachingConnectionFactory
!= null)
195 cachingConnectionFactory
.destroy();
198 public void setKeyStorePassword(String keyStorePassword
) {
199 this.keyStorePassword
= keyStorePassword
;
202 public void setKeyStore(Resource keyStore
) {
203 this.keyStore
= keyStore
;
206 public void setKeyStoreType(String keyStoreType
) {
207 this.keyStoreType
= keyStoreType
;
210 public void setBrokerURL(String brokerUrl
) {
211 this.brokerURL
= brokerUrl
;
214 public void setAuthenticationMode(String authenticationMode
) {
215 this.authenticationMode
= authenticationMode
;