1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.jaas.sp.jcr;
35
36 import info.magnolia.cms.beans.config.ContentRepository;
37 import info.magnolia.cms.security.PrincipalUtil;
38 import info.magnolia.cms.security.User;
39 import info.magnolia.cms.security.UserManager;
40 import info.magnolia.context.Context;
41 import info.magnolia.context.MgnlContext;
42 import info.magnolia.init.MagnoliaConfigurationProperties;
43 import info.magnolia.objectfactory.Components;
44
45 import java.io.IOException;
46 import java.io.Serializable;
47 import java.util.Arrays;
48 import java.util.Map;
49
50 import javax.security.auth.Subject;
51 import javax.security.auth.callback.Callback;
52 import javax.security.auth.callback.CallbackHandler;
53 import javax.security.auth.callback.NameCallback;
54 import javax.security.auth.callback.PasswordCallback;
55 import javax.security.auth.callback.UnsupportedCallbackException;
56 import javax.security.auth.login.FailedLoginException;
57 import javax.security.auth.login.LoginException;
58 import javax.security.auth.spi.LoginModule;
59
60 import org.apache.jackrabbit.core.security.UserPrincipal;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64
65
66
67
68
69
70
71
72 public class JackrabbitAuthenticationModule implements LoginModule, Serializable {
73
74 private static final Logger log = LoggerFactory.getLogger(JackrabbitAuthenticationModule.class);
75
76 private Subject subject;
77 private CallbackHandler callbackHandler;
78 private String name;
79
80 @Override
81 public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
82 this.subject = subject;
83 this.callbackHandler = callbackHandler;
84 }
85
86 @Override
87 public boolean login() throws LoginException {
88
89 if (this.callbackHandler == null) {
90 throw new LoginException("Error: no CallbackHandler available");
91 }
92
93 Callback[] callbacks = new Callback[2];
94 callbacks[0] = new NameCallback("name");
95 callbacks[1] = new PasswordCallback("pswd", false);
96
97 char[] password;
98 try {
99 this.callbackHandler.handle(callbacks);
100 this.name = ((NameCallback) callbacks[0]).getName();
101 password = ((PasswordCallback) callbacks[1]).getPassword();
102 } catch (IOException ioe) {
103 throw new LoginException(ioe.toString());
104 } catch (UnsupportedCallbackException ce) {
105 throw new LoginException(ce.getCallback().toString() + " not available");
106 }
107
108
109
110
111
112
113 if (getAdminUser().equals(this.name)) {
114 if (!Arrays.equals(password, getAdminPassword().toCharArray())) {
115 throw new FailedLoginException();
116 }
117 compileAdminPrincipals();
118 return true;
119 }
120
121 Context context = MgnlContext.hasInstance() ? MgnlContext.getInstance() : null;
122 if (context == null) {
123 throw new FailedLoginException("Cannot login, magnolia context is not set");
124 }
125
126 Subject magnoliaSubject = context.getSubject();
127 if (magnoliaSubject == null) {
128 throw new FailedLoginException("Cannot login, invalid setup or deserialization error");
129 }
130
131 if (isSuperuser(magnoliaSubject)) {
132 compileAdminPrincipals();
133 return true;
134 }
135
136 compileUserPrincipals(magnoliaSubject);
137 return true;
138 }
139
140 @Override
141 public boolean commit() throws LoginException {
142 return true;
143 }
144
145 @Override
146 public boolean abort() throws LoginException {
147 return false;
148 }
149
150 @Override
151 public boolean logout() throws LoginException {
152 callbackHandler = null;
153 name = null;
154 return true;
155 }
156
157 private void compileUserPrincipals(Subject magnoliaSubject) {
158 subject.getPrincipals().addAll(magnoliaSubject.getPrincipals());
159 subject.getPrincipals().add(new UserPrincipal(name));
160 }
161
162 private void compileAdminPrincipals() {
163 this.subject.getPrincipals().add(new MagnoliaJRAdminPrincipal(getAdminUser()));
164 }
165
166 protected String getAdminUser() {
167 String user = ContentRepository.REPOSITORY_USER;
168 if (user == null) {
169 MagnoliaConfigurationProperties mcp = Components.getSingleton(MagnoliaConfigurationProperties.class);
170 user = mcp.getProperty("magnolia.connection.jcr.userId");
171 }
172 if (user == null) {
173 user = System.getProperty("magnolia.connection.jcr.userId");
174 }
175 return user;
176 }
177
178 protected String getAdminPassword() {
179 String user = ContentRepository.REPOSITORY_PSWD;
180 if (user == null) {
181 MagnoliaConfigurationProperties mcp = Components.getSingleton(MagnoliaConfigurationProperties.class);
182 user = mcp.getProperty("magnolia.connection.jcr.password");
183 }
184 if (user == null) {
185 user = System.getProperty("magnolia.connection.jcr.password");
186 }
187 return user;
188 }
189
190
191
192
193 private boolean isSuperuser(Subject magnoliaSubject) {
194 User user = PrincipalUtil.findPrincipal(magnoliaSubject, User.class);
195 return user != null && UserManager.SYSTEM_USER.equals(user.getName());
196 }
197 }