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.core.Content;
37 import info.magnolia.cms.security.MgnlUser;
38 import info.magnolia.cms.security.MgnlUserManager;
39 import info.magnolia.cms.security.SecuritySupport;
40 import info.magnolia.cms.security.User;
41 import info.magnolia.cms.security.UserManager;
42 import info.magnolia.cms.security.auth.Entity;
43 import info.magnolia.jaas.principal.EntityImpl;
44 import info.magnolia.jaas.sp.AbstractLoginModule;
45 import info.magnolia.jaas.sp.UserAwareLoginModule;
46 import org.apache.commons.lang.StringUtils;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 import javax.security.auth.login.FailedLoginException;
51 import javax.security.auth.login.LoginException;
52 import javax.security.auth.login.AccountNotFoundException;
53 import javax.security.auth.login.AccountLockedException;
54
55 import java.util.Calendar;
56 import java.util.GregorianCalendar;
57 import java.util.Iterator;
58 import java.util.TimeZone;
59
60
61
62
63
64
65 public class JCRAuthenticationModule extends AbstractLoginModule implements UserAwareLoginModule {
66 private static final Logger log = LoggerFactory.getLogger(JCRAuthenticationModule.class);
67
68 protected User user;
69
70
71
72
73 public int getMaxAttempts() {
74
75 if (this.user instanceof MgnlUser) {
76 Content node = ((MgnlUser) this.user).getUserNode();
77 realm = StringUtils.substringBefore(StringUtils.substringAfter(node.getHandle(), "/"), "/");
78
79 } else {
80 return 0;
81 }
82 MgnlUserManager manager = (MgnlUserManager) SecuritySupport.Factory.getInstance().getUserManager(realm);
83 return (int)manager.getMaxFailedLoginAttempts();
84 }
85
86
87
88
89 public long getTimeLock(){
90
91 if (this.user instanceof MgnlUser) {
92 Content node = ((MgnlUser) this.user).getUserNode();
93 realm = StringUtils.substringBefore(StringUtils.substringAfter(node.getHandle(), "/"), "/");
94 } else {
95
96 return 0;
97 }
98 MgnlUserManager manager = (MgnlUserManager) SecuritySupport.Factory.getInstance().getUserManager(realm);
99 return (long)manager.getLockTimePeriod();
100 }
101
102
103
104
105 public boolean release() {
106 return true;
107 }
108
109
110
111
112
113 public void validateUser() throws LoginException {
114 initUser();
115
116 if (this.user == null) {
117 throw new AccountNotFoundException("User account " + this.name + " not found.");
118 }
119
120 if (!this.user.isEnabled()){
121 throw new AccountLockedException("User account " + this.name + " is locked.");
122 }
123
124 matchPassword();
125
126 if (!UserManager.ANONYMOUS_USER.equals(user.getName()) && user instanceof MgnlUser)
127 {
128 ((MgnlUser) user).setLastAccess();
129 }
130 }
131
132 protected void initUser() {
133 user = getUserManager().getUser(name);
134 }
135
136 protected void matchPassword() throws LoginException {
137 if(getMaxAttempts() > 0 && !UserManager.ANONYMOUS_USER.equals(user.getName()) && getTimeLock() > 0){
138
139 Calendar currentTime = new GregorianCalendar(TimeZone.getDefault());
140 Calendar lockTime = new GregorianCalendar(TimeZone.getDefault());
141 MgnlUser mgnlUser = (MgnlUser) user;
142 if(mgnlUser.getReleaseTime() != null){
143 lockTime.clear();
144 lockTime.setTime(mgnlUser.getReleaseTime().getTime());
145 }
146 if(lockTime.after(currentTime) && mgnlUser.getReleaseTime() != null){
147 throw new LoginException("User account " + this.name + " is locked until " + mgnlUser.getReleaseTime().getTime() + ".");
148 }
149 }
150
151 String serverPassword = user.getPassword();
152
153 if (StringUtils.isEmpty(serverPassword)) {
154 throw new FailedLoginException("we do not allow users with no password");
155 }
156
157 if (!StringUtils.equals(serverPassword, new String(this.pswd))) {
158
159 if (getMaxAttempts() > 0 && !UserManager.ANONYMOUS_USER.equals(user.getName())){
160
161 MgnlUser mgnlUser = (MgnlUser) user;
162 mgnlUser.setFailedLoginAttempts(mgnlUser.getFailedLoginAttempts() + 1);
163
164
165 if (mgnlUser.getFailedLoginAttempts() >= getMaxAttempts() && getTimeLock() <= 0){
166 mgnlUser.setEnabled(false);
167 mgnlUser.setFailedLoginAttempts(0);
168 log.warn("Account " + this.name + " was locked due to high number of failed login attempts.");
169
170 }else if (mgnlUser.getFailedLoginAttempts() >= getMaxAttempts() && getTimeLock() > 0){
171 mgnlUser.setFailedLoginAttempts(0);
172 Calendar calendar = new GregorianCalendar(TimeZone.getDefault());
173 calendar.add(Calendar.MINUTE, (int)getTimeLock());
174 mgnlUser.setReleaseTime(calendar);
175 String minuteString = "minutes";
176 if(getTimeLock() == 1){
177 minuteString = "minute";
178 }
179 log.warn("Account " + this.name + " was locked for " + getTimeLock() + " " + minuteString + " due to high number of failed login attempts.");
180 }
181 }
182 throw new FailedLoginException("passwords do not match");
183 }
184 if(user instanceof MgnlUser){
185 MgnlUser mgnlUser = (MgnlUser) user;
186 if (getMaxAttempts() > 0 && !UserManager.ANONYMOUS_USER.equals(mgnlUser.getName()) && mgnlUser.getFailedLoginAttempts() > 0){
187 mgnlUser.setFailedLoginAttempts(0);
188 }
189 }
190 }
191
192
193
194
195 public UserManager getUserManager() {
196 SecuritySupport securitySupport = SecuritySupport.Factory.getInstance();
197 return securitySupport.getUserManager(this.realm);
198 }
199
200
201
202
203 public void setEntity() {
204 EntityImpl entity = new EntityImpl();
205 entity.addProperty(Entity.LANGUAGE, this.user.getLanguage());
206 entity.addProperty(Entity.NAME, this.user.getName());
207
208 String fullName = this.user.getProperty("title");
209 if(fullName != null){
210 entity.addProperty(Entity.FULL_NAME, fullName);
211 }
212 entity.addProperty(Entity.PASSWORD, new String(this.pswd));
213 this.subject.getPrincipals().add(entity);
214
215 collectGroupNames();
216 collectRoleNames();
217 }
218
219
220
221
222 public void setACL() {
223 }
224
225
226
227
228 public void collectRoleNames() {
229 for (Iterator iter = this.user.getAllRoles().iterator(); iter.hasNext();) {
230 addRoleName((String)iter.next());
231 }
232 }
233
234
235
236
237 public void collectGroupNames() {
238 for (Iterator iter = this.user.getAllGroups().iterator(); iter.hasNext();) {
239 addGroupName((String) iter.next());
240 }
241 }
242
243 public User getUser() {
244 return user;
245 }
246
247 }