]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.security.core/src/org/argeo/security/login/AbstractSpringLoginModule.java
Use GrantedAuthority implementing Principal in order to optimise Jackrabbit login
[lgpl/argeo-commons.git] / org.argeo.security.core / src / org / argeo / security / login / AbstractSpringLoginModule.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.security.login;
17
18 import java.io.IOException;
19 import java.util.Map;
20
21 import javax.security.auth.Subject;
22 import javax.security.auth.callback.CallbackHandler;
23 import javax.security.auth.callback.UnsupportedCallbackException;
24 import javax.security.auth.login.LoginException;
25 import javax.security.auth.spi.LoginModule;
26
27 import org.osgi.framework.BundleContext;
28 import org.osgi.service.useradmin.UserAdmin;
29 import org.springframework.security.authentication.AuthenticationManager;
30 import org.springframework.security.core.Authentication;
31 import org.springframework.security.core.context.SecurityContextHolder;
32
33 /** Login module which caches one subject per thread. */
34 abstract class AbstractSpringLoginModule implements LoginModule {
35 // private final static Log log = LogFactory
36 // .getLog(AbstractSpringLoginModule.class);
37 private CallbackHandler callbackHandler;
38 private Subject subject;
39
40 private Authentication authentication;
41
42 protected abstract Authentication processLogin(
43 CallbackHandler callbackHandler) throws LoginException,
44 UnsupportedCallbackException, IOException, InterruptedException;
45
46 @SuppressWarnings("rawtypes")
47 @Override
48 public void initialize(Subject subject, CallbackHandler callbackHandler,
49 Map sharedState, Map options) {
50 this.callbackHandler = callbackHandler;
51 this.subject = subject;
52 }
53
54 @Override
55 public boolean login() throws LoginException {
56 try {
57 // thread already logged in
58 Authentication currentAuth = SecurityContextHolder.getContext()
59 .getAuthentication();
60 if (currentAuth != null) {
61 if (subject.getPrincipals(Authentication.class).size() == 0) {
62 throw new LoginException(
63 "Security context set but not Authentication principal");
64 } else {
65 Authentication principal = subject
66 .getPrincipals(Authentication.class).iterator()
67 .next();
68 if (principal != currentAuth)
69 throw new LoginException(
70 "Already authenticated with a different auth");
71 }
72 return true;
73 }
74
75 if (callbackHandler == null)
76 throw new LoginException("No callback handler available");
77
78 authentication = processLogin(callbackHandler);
79 if (authentication != null) {
80 SecurityContextHolder.getContext().setAuthentication(
81 authentication);
82 return true;
83 } else {
84 throw new LoginException("No authentication returned");
85 }
86 } catch (LoginException e) {
87 throw e;
88 } catch (ThreadDeath e) {
89 LoginException le = new LoginException(
90 "Spring Security login thread died");
91 le.initCause(e);
92 throw le;
93 } catch (Exception e) {
94 LoginException le = new LoginException(
95 "Spring Security login failed");
96 le.initCause(e);
97 throw le;
98 }
99 }
100
101 @Override
102 public boolean logout() throws LoginException {
103 SecurityContextHolder.getContext().setAuthentication(null);
104 return true;
105 }
106
107 @Override
108 public boolean commit() throws LoginException {
109 return true;
110 }
111
112 @Override
113 public boolean abort() throws LoginException {
114 SecurityContextHolder.getContext().setAuthentication(null);
115 return true;
116 }
117
118 protected AuthenticationManager getAuthenticationManager(
119 BundleContextCallback bundleContextCallback) {
120 BundleContext bc = bundleContextCallback.getBundleContext();
121 return bc.getService(bc
122 .getServiceReference(AuthenticationManager.class));
123
124 }
125
126 protected UserAdmin getUserAdmin(BundleContextCallback bundleContextCallback) {
127 BundleContext bc = bundleContextCallback.getBundleContext();
128 return bc.getService(bc.getServiceReference(UserAdmin.class));
129 }
130
131 protected Subject getSubject() {
132 return subject;
133 }
134 }