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 java.io.IOException;
37 import java.io.Serializable;
38 import java.util.Arrays;
39 import java.util.Map;
40 import javax.security.auth.Subject;
41 import javax.security.auth.callback.Callback;
42 import javax.security.auth.callback.CallbackHandler;
43 import javax.security.auth.callback.NameCallback;
44 import javax.security.auth.callback.PasswordCallback;
45 import javax.security.auth.callback.UnsupportedCallbackException;
46 import javax.security.auth.login.FailedLoginException;
47 import javax.security.auth.login.LoginException;
48 import javax.security.auth.spi.LoginModule;
49
50 import org.apache.jackrabbit.core.security.UserPrincipal;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 import info.magnolia.cms.beans.config.ContentRepository;
55 import info.magnolia.cms.security.PrincipalUtil;
56 import info.magnolia.cms.security.User;
57 import info.magnolia.cms.security.UserManager;
58 import info.magnolia.context.Context;
59 import info.magnolia.context.MgnlContext;
60
61
62
63
64
65
66
67
68
69 public class JackrabbitAuthenticationModule implements LoginModule, Serializable {
70
71 private static final Logger log = LoggerFactory.getLogger(JackrabbitAuthenticationModule.class);
72
73 private Subject subject;
74 private CallbackHandler callbackHandler;
75 private String name;
76
77 @Override
78 public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
79 this.subject = subject;
80 this.callbackHandler = callbackHandler;
81 }
82
83 @Override
84 public boolean login() throws LoginException {
85
86 if (this.callbackHandler == null) {
87 throw new LoginException("Error: no CallbackHandler available");
88 }
89
90 Callback[] callbacks = new Callback[2];
91 callbacks[0] = new NameCallback("name");
92 callbacks[1] = new PasswordCallback("pswd", false);
93
94 char[] password;
95 try {
96 this.callbackHandler.handle(callbacks);
97 this.name = ((NameCallback) callbacks[0]).getName();
98 password = ((PasswordCallback) callbacks[1]).getPassword();
99 } catch (IOException ioe) {
100 throw new LoginException(ioe.toString());
101 } catch (UnsupportedCallbackException ce) {
102 throw new LoginException(ce.getCallback().toString() + " not available");
103 }
104
105
106
107
108
109 if (ContentRepository.REPOSITORY_USER.equals(this.name)) {
110 if (!Arrays.equals(password, ContentRepository.REPOSITORY_PSWD.toCharArray())) {
111 throw new FailedLoginException();
112 }
113 compileAdminPrincipals();
114 return true;
115 }
116
117 Context context = MgnlContext.hasInstance() ? MgnlContext.getInstance() : null;
118 if (context == null) {
119 throw new FailedLoginException("Cannot login, magnolia context is not set");
120 }
121
122 Subject magnoliaSubject = context.getSubject();
123 if (magnoliaSubject == null) {
124 throw new FailedLoginException("Cannot login, invalid setup or deserialization error");
125 }
126
127 if (isSuperuser(magnoliaSubject)) {
128 compileAdminPrincipals();
129 return true;
130 }
131
132 compileUserPrincipals(magnoliaSubject);
133 return true;
134 }
135
136 @Override
137 public boolean commit() throws LoginException {
138 return true;
139 }
140
141 @Override
142 public boolean abort() throws LoginException {
143 return false;
144 }
145
146 @Override
147 public boolean logout() throws LoginException {
148 callbackHandler = null;
149 name = null;
150 return true;
151 }
152
153 private void compileUserPrincipals(Subject magnoliaSubject) {
154 subject.getPrincipals().addAll(magnoliaSubject.getPrincipals());
155 subject.getPrincipals().add(new UserPrincipal(name));
156 }
157
158 private void compileAdminPrincipals() {
159 this.subject.getPrincipals().add(new MagnoliaJRAdminPrincipal(ContentRepository.REPOSITORY_USER));
160 }
161
162
163
164
165 private boolean isSuperuser(Subject magnoliaSubject) {
166 User user = PrincipalUtil.findPrincipal(magnoliaSubject, User.class);
167 return user != null && UserManager.SYSTEM_USER.equals(user.getName());
168 }
169 }