1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.shiro.realm.activedirectory;
20
21 import org.apache.shiro.authc.AuthenticationInfo;
22 import org.apache.shiro.authc.AuthenticationToken;
23 import org.apache.shiro.authc.SimpleAuthenticationInfo;
24 import org.apache.shiro.authc.UsernamePasswordToken;
25 import org.apache.shiro.authz.AuthorizationInfo;
26 import org.apache.shiro.authz.SimpleAuthorizationInfo;
27 import org.apache.shiro.realm.Realm;
28 import org.apache.shiro.realm.ldap.AbstractLdapRealm;
29 import org.apache.shiro.realm.ldap.LdapContextFactory;
30 import org.apache.shiro.realm.ldap.LdapUtils;
31 import org.apache.shiro.subject.PrincipalCollection;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 import javax.naming.NamingEnumeration;
36 import javax.naming.NamingException;
37 import javax.naming.directory.Attribute;
38 import javax.naming.directory.Attributes;
39 import javax.naming.directory.SearchControls;
40 import javax.naming.directory.SearchResult;
41 import javax.naming.ldap.LdapContext;
42 import java.util.*;
43
44
45
46
47
48
49
50
51
52
53 public class ActiveDirectoryRealm extends AbstractLdapRealm {
54
55
56
57
58
59
60
61 private static final Logger log = LoggerFactory.getLogger(ActiveDirectoryRealm.class);
62
63 private static final String ROLE_NAMES_DELIMETER = ",";
64
65
66
67
68
69
70
71
72
73
74 private Map<String, String> groupRolesMap;
75
76
77
78
79
80 public void setGroupRolesMap(Map<String, String> groupRolesMap) {
81 this.groupRolesMap = groupRolesMap;
82 }
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException {
102
103 UsernamePasswordToken upToken = (UsernamePasswordToken) token;
104
105
106 LdapContext ctx = null;
107 try {
108 ctx = ldapContextFactory.getLdapContext(upToken.getUsername(), String.valueOf(upToken.getPassword()));
109 } finally {
110 LdapUtils.closeContext(ctx);
111 }
112
113 return buildAuthenticationInfo(upToken.getUsername(), upToken.getPassword());
114 }
115
116 protected AuthenticationInfo buildAuthenticationInfo(String username, char[] password) {
117 return new SimpleAuthenticationInfo(username, password, getName());
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException {
137
138 String username = (String) getAvailablePrincipal(principals);
139
140
141 LdapContext ldapContext = ldapContextFactory.getSystemLdapContext();
142
143 Set<String> roleNames;
144
145 try {
146 roleNames = getRoleNamesForUser(username, ldapContext);
147 } finally {
148 LdapUtils.closeContext(ldapContext);
149 }
150
151 return buildAuthorizationInfo(roleNames);
152 }
153
154 protected AuthorizationInfo buildAuthorizationInfo(Set<String> roleNames) {
155 return new SimpleAuthorizationInfo(roleNames);
156 }
157
158 protected Set<String> getRoleNamesForUser(String username, LdapContext ldapContext) throws NamingException {
159 Set<String> roleNames;
160 roleNames = new LinkedHashSet<String>();
161
162 SearchControls searchCtls = new SearchControls();
163 searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
164
165 String userPrincipalName = username;
166 if (principalSuffix != null) {
167 userPrincipalName += principalSuffix;
168 }
169
170 Object[] searchArguments = new Object[]{userPrincipalName};
171
172 NamingEnumeration answer = ldapContext.search(searchBase, searchFilter, searchArguments, searchCtls);
173
174 while (answer.hasMoreElements()) {
175 SearchResult sr = (SearchResult) answer.next();
176
177 if (log.isDebugEnabled()) {
178 log.debug("Retrieving group names for user [" + sr.getName() + "]");
179 }
180
181 Attributes attrs = sr.getAttributes();
182
183 if (attrs != null) {
184 NamingEnumeration ae = attrs.getAll();
185 while (ae.hasMore()) {
186 Attribute attr = (Attribute) ae.next();
187
188 if (attr.getID().equals("memberOf")) {
189
190 Collection<String> groupNames = LdapUtils.getAllAttributeValues(attr);
191
192 if (log.isDebugEnabled()) {
193 log.debug("Groups found for user [" + username + "]: " + groupNames);
194 }
195
196 Collection<String> rolesForGroups = getRoleNamesForGroups(groupNames);
197 roleNames.addAll(rolesForGroups);
198 }
199 }
200 }
201 }
202 return roleNames;
203 }
204
205
206
207
208
209
210
211
212 protected Collection<String> getRoleNamesForGroups(Collection<String> groupNames) {
213 Set<String> roleNames = new HashSet<String>(groupNames.size());
214
215 if (groupRolesMap != null) {
216 for (String groupName : groupNames) {
217 String strRoleNames = groupRolesMap.get(groupName);
218 if (strRoleNames != null) {
219 for (String roleName : strRoleNames.split(ROLE_NAMES_DELIMETER)) {
220
221 if (log.isDebugEnabled()) {
222 log.debug("User is member of group [" + groupName + "] so adding role [" + roleName + "]");
223 }
224
225 roleNames.add(roleName);
226
227 }
228 }
229 }
230 }
231 return roleNames;
232 }
233
234 }