/
UserRolesRetrieveStrategy.java
130 lines (102 loc) · 5.18 KB
/
UserRolesRetrieveStrategy.java
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.storage.ldap.mappers.membership;
import org.keycloak.models.LDAPConstants;
import org.keycloak.storage.ldap.LDAPConfig;
import org.keycloak.storage.ldap.LDAPUtils;
import org.keycloak.storage.ldap.idm.model.LDAPDn;
import org.keycloak.storage.ldap.idm.model.LDAPObject;
import org.keycloak.storage.ldap.idm.query.Condition;
import org.keycloak.storage.ldap.idm.query.internal.LDAPQuery;
import org.keycloak.storage.ldap.idm.query.internal.LDAPQueryConditionsBuilder;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* Strategy for how to retrieve LDAP roles of user
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public interface UserRolesRetrieveStrategy {
List<LDAPObject> getLDAPRoleMappings(CommonLDAPGroupMapper roleOrGroupMapper, LDAPObject ldapUser, LDAPConfig ldapConfig);
void beforeUserLDAPQuery(LDAPQuery query);
// Impl subclasses
/**
* Roles of user will be retrieved by sending LDAP query to retrieve all roles where "member" is our user
*/
class LoadRolesByMember implements UserRolesRetrieveStrategy {
@Override
public List<LDAPObject> getLDAPRoleMappings(CommonLDAPGroupMapper roleOrGroupMapper, LDAPObject ldapUser, LDAPConfig ldapConfig) {
LDAPQuery ldapQuery = roleOrGroupMapper.createLDAPGroupQuery();
String membershipAttr = roleOrGroupMapper.getConfig().getMembershipLdapAttribute();
String membershipUserAttrName = roleOrGroupMapper.getConfig().getMembershipUserLdapAttribute(ldapConfig);
String userMembership = LDAPUtils.getMemberValueOfChildObject(ldapUser, roleOrGroupMapper.getConfig().getMembershipTypeLdapAttribute(), membershipUserAttrName);
Condition membershipCondition = getMembershipCondition(membershipAttr, userMembership);
ldapQuery.addWhereCondition(membershipCondition);
return ldapQuery.getResultList();
}
@Override
public void beforeUserLDAPQuery(LDAPQuery query) {
}
protected Condition getMembershipCondition(String membershipAttr, String userMembership) {
return new LDAPQueryConditionsBuilder().equal(membershipAttr, userMembership);
}
};
/**
* Roles of user will be retrieved from "memberOf" attribute of our user
*/
class GetRolesFromUserMemberOfAttribute implements UserRolesRetrieveStrategy {
@Override
public List<LDAPObject> getLDAPRoleMappings(CommonLDAPGroupMapper roleOrGroupMapper, LDAPObject ldapUser, LDAPConfig ldapConfig) {
Set<String> memberOfValues = ldapUser.getAttributeAsSet(LDAPConstants.MEMBER_OF);
if (memberOfValues == null) {
return Collections.emptyList();
}
List<LDAPObject> roles = new LinkedList<>();
LDAPDn parentDn = LDAPDn.fromString(roleOrGroupMapper.getConfig().getLDAPGroupsDn());
for (String roleDn : memberOfValues) {
LDAPDn roleDN = LDAPDn.fromString(roleDn);
if (roleDN.isDescendantOf(parentDn)) {
LDAPObject role = new LDAPObject();
role.setDn(roleDN);
String firstDN = roleDN.getFirstRdnAttrName();
if (firstDN.equalsIgnoreCase(roleOrGroupMapper.getConfig().getLDAPGroupNameLdapAttribute())) {
role.setRdnAttributeName(firstDN);
role.setSingleAttribute(firstDN, roleDN.getFirstRdnAttrValue());
roles.add(role);
}
}
}
return roles;
}
@Override
public void beforeUserLDAPQuery(LDAPQuery query) {
query.addReturningLdapAttribute(LDAPConstants.MEMBER_OF);
query.addReturningReadOnlyLdapAttribute(LDAPConstants.MEMBER_OF);
}
};
/**
* Extension specific to Active Directory. Roles of user will be retrieved by sending LDAP query to retrieve all roles where "member" is our user.
* The query will be able to retrieve memberships recursively with usage of AD specific extension LDAP_MATCHING_RULE_IN_CHAIN, so likely doesn't work on other LDAP servers
*/
class LoadRolesByMemberRecursively extends LoadRolesByMember {
protected Condition getMembershipCondition(String membershipAttr, String userMembership) {
return new LDAPQueryConditionsBuilder().equal(membershipAttr + LDAPConstants.LDAP_MATCHING_RULE_IN_CHAIN, userMembership);
}
};
}