1 package org
.argeo
.cms
.internal
.kernel
;
4 import java
.io
.IOException
;
6 import java
.nio
.file
.ProviderNotFoundException
;
7 import java
.security
.KeyStore
;
8 import java
.security
.Provider
;
9 import java
.security
.Security
;
10 import java
.util
.Arrays
;
12 import javax
.security
.auth
.Subject
;
13 import javax
.security
.auth
.callback
.Callback
;
14 import javax
.security
.auth
.callback
.CallbackHandler
;
15 import javax
.security
.auth
.callback
.NameCallback
;
16 import javax
.security
.auth
.callback
.PasswordCallback
;
17 import javax
.security
.auth
.callback
.UnsupportedCallbackException
;
18 import javax
.security
.auth
.login
.LoginContext
;
19 import javax
.security
.auth
.login
.LoginException
;
20 import javax
.security
.auth
.x500
.X500Principal
;
22 import org
.apache
.commons
.io
.FileUtils
;
23 import org
.apache
.commons
.logging
.Log
;
24 import org
.apache
.commons
.logging
.LogFactory
;
25 import org
.argeo
.cms
.CmsException
;
26 import org
.argeo
.cms
.KernelHeader
;
27 import org
.argeo
.osgi
.useradmin
.AbstractUserDirectory
;
28 import org
.argeo
.osgi
.useradmin
.LdapUserAdmin
;
29 import org
.argeo
.osgi
.useradmin
.LdifUserAdmin
;
30 import org
.argeo
.security
.crypto
.PkiUtils
;
31 import org
.bouncycastle
.jce
.provider
.BouncyCastleProvider
;
32 import org
.osgi
.framework
.BundleContext
;
33 import org
.osgi
.framework
.ServiceRegistration
;
34 import org
.osgi
.service
.useradmin
.UserAdmin
;
35 import org
.springframework
.security
.authentication
.AuthenticationManager
;
36 import org
.springframework
.security
.core
.Authentication
;
37 import org
.springframework
.security
.core
.AuthenticationException
;
39 /** Authentication and user management. */
40 class NodeSecurity
implements AuthenticationManager
{
41 private final static Log log
;
43 log
= LogFactory
.getLog(NodeSecurity
.class);
44 // Make Bouncy Castle the default provider
45 Provider provider
= new BouncyCastleProvider();
46 int position
= Security
.insertProviderAt(provider
, 1);
48 log
.error("Provider " + provider
.getName()
49 + " already installed and could not be set as default");
50 Provider defaultProvider
= Security
.getProviders()[0];
51 if (!defaultProvider
.getName().equals(KernelHeader
.SECURITY_PROVIDER
))
52 log
.error("Provider name is " + defaultProvider
.getName()
53 + " but it should be " + KernelHeader
.SECURITY_PROVIDER
);
56 private final BundleContext bundleContext
;
57 private final NodeUserAdmin userAdmin
;
58 private final Subject kernelSubject
;
60 // private final OsAuthenticationProvider osAuth;
61 // private final InternalAuthenticationProvider internalAuth;
62 // private final AnonymousAuthenticationProvider anonymousAuth;
63 // private final JackrabbitUserAdminService userAdminService;
65 private ServiceRegistration
<AuthenticationManager
> authenticationManagerReg
;
66 // private ServiceRegistration<UserAdminService> userAdminServiceReg;
67 // private ServiceRegistration<UserDetailsManager> userDetailsManagerReg;
69 private ServiceRegistration
<UserAdmin
> userAdminReg
;
71 public NodeSecurity(BundleContext bundleContext
) {
72 // Configure JAAS first
73 URL url
= getClass().getClassLoader().getResource(
74 KernelConstants
.JAAS_CONFIG
);
75 System
.setProperty("java.security.auth.login.config",
76 url
.toExternalForm());
78 this.bundleContext
= bundleContext
;
79 this.kernelSubject
= logKernel();
81 // osAuth = new OsAuthenticationProvider();
82 // internalAuth = new InternalAuthenticationProvider(
83 // Activator.getSystemKey());
84 // anonymousAuth = new AnonymousAuthenticationProvider(
85 // Activator.getSystemKey());
88 // userAdminService = new JackrabbitUserAdminService();
89 // userAdminService.setRepository(node);
90 // userAdminService.setSecurityModel(new SimpleJcrSecurityModel());
91 // userAdminService.init();
93 userAdmin
= new NodeUserAdmin();
95 File osgiInstanceDir
= KernelUtils
.getOsgiInstanceDir();
96 File homeDir
= new File(osgiInstanceDir
, "node");
99 String userAdminUri
= KernelUtils
100 .getFrameworkProp(KernelConstants
.USERADMIN_URI
);
101 String baseDn
= "dc=example,dc=com";
102 if (userAdminUri
== null) {
103 File businessRolesFile
= new File(homeDir
, baseDn
+ ".ldif");
104 // userAdminUri = getClass().getResource(baseDn +
105 // ".ldif").toString();
106 if (!businessRolesFile
.exists())
108 FileUtils
.copyInputStreamToFile(getClass()
109 .getResourceAsStream(baseDn
+ ".ldif"),
111 } catch (IOException e
) {
112 throw new CmsException("Cannot copy demo resource", e
);
114 userAdminUri
= businessRolesFile
.toURI().toString();
117 AbstractUserDirectory businessRoles
;
118 if (userAdminUri
.startsWith("ldap"))
119 businessRoles
= new LdapUserAdmin(userAdminUri
);
121 businessRoles
= new LdifUserAdmin(userAdminUri
);
123 businessRoles
.init();
124 userAdmin
.addUserAdmin(baseDn
, businessRoles
);
126 String baseNodeRoleDn
= KernelHeader
.ROLES_BASEDN
;
127 File nodeRolesFile
= new File(homeDir
, baseNodeRoleDn
+ ".ldif");
128 if (!nodeRolesFile
.exists())
130 FileUtils
.copyInputStreamToFile(
131 getClass().getResourceAsStream("demo.ldif"),
133 } catch (IOException e
) {
134 throw new CmsException("Cannot copy demo resource", e
);
136 LdifUserAdmin nodeRoles
= new LdifUserAdmin(nodeRolesFile
.toURI()
138 nodeRoles
.setExternalRoles(userAdmin
);
140 // nodeRoles.createRole(KernelHeader.ROLE_ADMIN, Role.GROUP);
141 userAdmin
.addUserAdmin(baseNodeRoleDn
, nodeRoles
);
145 private Subject
logKernel() {
146 final Subject kernelSubject
= new Subject();
147 createKeyStoreIfNeeded();
149 CallbackHandler cbHandler
= new CallbackHandler() {
152 public void handle(Callback
[] callbacks
) throws IOException
,
153 UnsupportedCallbackException
{
155 ((NameCallback
) callbacks
[1]).setName(KernelHeader
.ROLE_KERNEL
);
157 ((PasswordCallback
) callbacks
[2]).setPassword("changeit"
160 ((PasswordCallback
) callbacks
[3]).setPassword("changeit"
165 LoginContext kernelLc
= new LoginContext(
166 KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
,
169 } catch (LoginException e
) {
170 throw new CmsException("Cannot log in kernel", e
);
172 return kernelSubject
;
175 public void publish() {
176 authenticationManagerReg
= bundleContext
.registerService(
177 AuthenticationManager
.class, this, null);
178 // userAdminServiceReg = bundleContext.registerService(
179 // UserAdminService.class, userAdminService, null);
180 // userDetailsManagerReg = bundleContext.registerService(
181 // UserDetailsManager.class, userAdminService, null);
182 userAdminReg
= bundleContext
.registerService(UserAdmin
.class,
188 // userAdminService.destroy();
189 // } catch (RepositoryException e) {
190 // log.error("Error while destroying Jackrabbit useradmin");
192 // userDetailsManagerReg.unregister();
193 // userAdminServiceReg.unregister();
194 authenticationManagerReg
.unregister();
196 // userAdmin.destroy();
197 userAdminReg
.unregister();
201 LoginContext kernelLc
= new LoginContext(
202 KernelConstants
.LOGIN_CONTEXT_KERNEL
, kernelSubject
);
204 } catch (LoginException e
) {
205 throw new CmsException("Cannot log in kernel", e
);
208 Security
.removeProvider(KernelHeader
.SECURITY_PROVIDER
);
211 public NodeUserAdmin
getUserAdmin() {
215 public Subject
getKernelSubject() {
216 return kernelSubject
;
220 public Authentication
authenticate(Authentication authentication
)
221 throws AuthenticationException
{
222 log
.error("Authentication manager is deprectaed and should not be used.");
223 // Authentication auth = null;
224 // if (authentication instanceof InternalAuthentication)
225 // auth = internalAuth.authenticate(authentication);
226 // else if (authentication instanceof AnonymousAuthenticationToken)
227 // auth = anonymousAuth.authenticate(authentication);
228 // else if (authentication instanceof
229 // UsernamePasswordAuthenticationToken)
230 // auth = userAdminService.authenticate(authentication);
231 // else if (authentication instanceof OsAuthenticationToken)
232 // auth = osAuth.authenticate(authentication);
234 // throw new CmsException("Could not authenticate " + authentication);
235 throw new ProviderNotFoundException(
236 "Authentication manager is deprectaed and should not be used.");
239 private void createKeyStoreIfNeeded() {
240 char[] ksPwd
= "changeit".toCharArray();
241 char[] keyPwd
= Arrays
.copyOf(ksPwd
, ksPwd
.length
);
242 File keyStoreFile
= new File(KernelUtils
.getOsgiInstanceDir(),
244 if (!keyStoreFile
.exists()) {
246 keyStoreFile
.getParentFile().mkdirs();
247 KeyStore keyStore
= PkiUtils
.getKeyStore(keyStoreFile
, ksPwd
);
248 PkiUtils
.generateSelfSignedCertificate(keyStore
,
249 new X500Principal(KernelHeader
.ROLE_KERNEL
), keyPwd
);
250 PkiUtils
.saveKeyStore(keyStoreFile
, ksPwd
, keyStore
);
252 } catch (Exception e
) {
253 throw new CmsException("Cannot create key store "