下面列出了javax.naming.SizeLimitExceededException#org.apache.shiro.realm.ldap.LdapContextFactory 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken authenticationToken,
LdapContextFactory ldapContextFactory) throws NamingException {
String token = (String) authenticationToken.getCredentials();
// 解密获得username,用于和数据库进行对比
String username = JwtUtil.getUsername(token);
if (null==username || !JwtUtil.verify(token, username)) {
throw new AuthenticationException("token认证失败!");
}
UserModel userModel= userService.getUserByUserName(username);
if(null==userModel){
return null;
}
return new SimpleAuthenticationInfo(token, token, "MyRealm");
}
@Override
protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals,
LdapContextFactory ldapContextFactory) throws NamingException {
System.out.println("————权限认证————");
String username = JwtUtil.getUsername(principals.toString());
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获得该用户角色
//String role = userMapper.getRole(username);
//每个角色拥有默认的权限
//String rolePermission = userMapper.getRolePermission(username);
//每个用户可以设置新的权限
//String permission = userMapper.getPermission(username);
Set<String> roleSet = new HashSet<>();
Set<String> permissionSet = new HashSet<>();
//需要将 role, permission 封装到 Set 作为 info.setRoles(), info.setStringPermissions() 的参数
// roleSet.add(role);
// permissionSet.add(rolePermission);
//permissionSet.add(permission);
//设置该用户拥有的角色和权限
info.setRoles(roleSet);
info.setStringPermissions(permissionSet);
return info;
}
@Override
protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken authenticationToken,
LdapContextFactory ldapContextFactory) throws NamingException {
String token = (String) authenticationToken.getCredentials();
// 解密获得username,用于和数据库进行对比
String username = JwtUtil.getUsername(token);
if (null==username || !JwtUtil.verify(token, username)) {
throw new AuthenticationException("token认证失败!");
}
LdapContext ctx = null;
try {
ctx = ldapContextFactory.getLdapContext(username, null);
} catch (Throwable e) {
LOGGER.error(e.getMessage(), e);
return null;
} finally {
LdapUtils.closeContext(ctx);
}
return new SimpleAuthenticationInfo(token, token, "MyRealm");
}
@Override
protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals,
LdapContextFactory ldapContextFactory) throws NamingException {
System.out.println("————权限认证————");
String username = JwtUtil.getUsername(principals.toString());
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获得该用户角色
//String role = userMapper.getRole(username);
//每个角色拥有默认的权限
//String rolePermission = userMapper.getRolePermission(username);
//每个用户可以设置新的权限
//String permission = userMapper.getPermission(username);
Set<String> roleSet = new HashSet<>();
Set<String> permissionSet = new HashSet<>();
//需要将 role, permission 封装到 Set 作为 info.setRoles(), info.setStringPermissions() 的参数
// roleSet.add(role);
// permissionSet.add(rolePermission);
//permissionSet.add(permission);
//设置该用户拥有的角色和权限
info.setRoles(roleSet);
info.setStringPermissions(permissionSet);
return info;
}
@Nullable
private AuthenticationInfo queryForAuthenticationInfo0(
AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException {
final UsernamePasswordToken upToken = ensureUsernamePasswordToken(token);
final String userDn = findUserDn(ldapContextFactory, upToken.getUsername());
if (userDn == null) {
return null;
}
LdapContext ctx = null;
try {
// Binds using the username and password provided by the user.
ctx = ldapContextFactory.getLdapContext(userDn, upToken.getPassword());
} catch (AuthenticationException e) {
// According to this page, LDAP error code 49 (invalid credentials) is the only case where
// AuthenticationException is raised:
// - https://docs.oracle.com/javase/tutorial/jndi/ldap/exceptions.html
// - com.sun.jndi.ldap.LdapCtx.mapErrorCode()
return null;
} finally {
LdapUtils.closeContext(ctx);
}
return buildAuthenticationInfo(upToken.getUsername(), upToken.getPassword());
}
public LdapContextFactory getLdapContextFactory() {
if (this.ldapContextFactory == null) {
if (log.isDebugEnabled()) {
log.debug("No LdapContextFactory specified - creating a default instance.");
}
DefaultLdapContextFactory defaultFactory = new DefaultLdapContextFactory();
defaultFactory.setPrincipalSuffix(this.principalSuffix);
defaultFactory.setSearchBase(this.searchBase);
defaultFactory.setUrl(this.url);
defaultFactory.setSystemUsername(this.systemUsername);
defaultFactory.setSystemPassword(getSystemPassword());
this.ldapContextFactory = defaultFactory;
}
return this.ldapContextFactory;
}
/**
* Builds an {@link AuthenticationInfo} object by querying the active directory LDAP context for
* the specified username. This method binds to the LDAP server using the provided username
* and password - which if successful, indicates that the password is correct.
* <p/>
* This method can be overridden by subclasses to query the LDAP server in a more complex way.
*
* @param token the authentication token provided by the user.
* @param ldapContextFactory the factory used to build connections to the LDAP server.
* @return an {@link AuthenticationInfo} instance containing information retrieved from LDAP.
* @throws NamingException if any LDAP errors occur during the search.
*/
protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token,
LdapContextFactory ldapContextFactory) throws NamingException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
// Binds using the username and password provided by the user.
LdapContext ctx = null;
try {
String userPrincipalName = upToken.getUsername();
if (!isValidPrincipalName(userPrincipalName)) {
return null;
}
if (this.principalSuffix != null && userPrincipalName.indexOf('@') < 0) {
userPrincipalName = upToken.getUsername() + this.principalSuffix;
}
ctx = ldapContextFactory.getLdapContext(
userPrincipalName, upToken.getPassword());
} finally {
LdapUtils.closeContext(ctx);
}
return buildAuthenticationInfo(upToken.getUsername(), upToken.getPassword());
}
/**
* Builds an {@link org.apache.shiro.authz.AuthorizationInfo} object by querying the active
* directory LDAP context for the groups that a user is a member of. The groups are then
* translated to role names by using the configured {@link #groupRolesMap}.
* <p/>
* This implementation expects the <tt>principal</tt> argument to be a String username.
* <p/>
* Subclasses can override this method to determine authorization data (roles, permissions, etc)
* in a more complex way. Note that this default implementation does not support permissions,
* only roles.
*
* @param principals the principal of the Subject whose account is being retrieved.
* @param ldapContextFactory the factory used to create LDAP connections.
* @return the AuthorizationInfo for the given Subject principal.
* @throws NamingException if an error occurs when searching the LDAP server.
*/
protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals,
LdapContextFactory ldapContextFactory) throws NamingException {
String username = (String) getAvailablePrincipal(principals);
// Perform context search
LdapContext ldapContext = ldapContextFactory.getSystemLdapContext();
Set<String> roleNames;
try {
roleNames = getRoleNamesForUser(username, ldapContext);
} finally {
LdapUtils.closeContext(ldapContext);
}
return buildAuthorizationInfo(roleNames);
}
/**
* Get groups from LDAP.
*
* @param principals
* the principals of the Subject whose AuthenticationInfo should
* be queried from the LDAP server.
* @param ldapContextFactory
* factory used to retrieve LDAP connections.
* @return an {@link AuthorizationInfo} instance containing information
* retrieved from the LDAP server.
* @throws NamingException
* if any LDAP errors occur during the search.
*/
@Override
public AuthorizationInfo queryForAuthorizationInfo(final PrincipalCollection principals,
final LdapContextFactory ldapContextFactory) throws NamingException {
if (!isAuthorizationEnabled()) {
return null;
}
final Set<String> roleNames = getRoles(principals, ldapContextFactory);
if (log.isDebugEnabled()) {
log.debug("RolesNames Authorization: " + roleNames);
}
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(roleNames);
Set<String> stringPermissions = permsFor(roleNames);
simpleAuthorizationInfo.setStringPermissions(stringPermissions);
return simpleAuthorizationInfo;
}
private Set<String> getRoles(PrincipalCollection principals,
final LdapContextFactory ldapContextFactory) throws NamingException {
final String username = (String) getAvailablePrincipal(principals);
LdapContext systemLdapCtx = null;
try {
systemLdapCtx = ldapContextFactory.getSystemLdapContext();
return rolesFor(principals, username, systemLdapCtx,
ldapContextFactory, SecurityUtils.getSubject().getSession());
} catch (Throwable t) {
log.warn("Failed to get roles in current context for " + username, t);
return Collections.emptySet();
} finally {
LdapUtils.closeContext(systemLdapCtx);
}
}
/**
* Builds an {@link AuthenticationInfo} object by querying the active directory LDAP context for the
* specified username.
*/
@Nullable
@Override
protected AuthenticationInfo queryForAuthenticationInfo(
AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException {
try {
return queryForAuthenticationInfo0(token, ldapContextFactory);
} catch (ServiceUnavailableException e) {
// It might be a temporary failure, so try again.
return queryForAuthenticationInfo0(token, ldapContextFactory);
}
}
/**
* Finds a distinguished name(DN) of a user by querying the active directory LDAP context for the
* specified username.
*
* @return the DN of the user, or {@code null} if there's no such user
*/
@Nullable
protected String findUserDn(LdapContextFactory ldapContextFactory, String username) throws NamingException {
LdapContext ctx = null;
try {
// Binds using the system username and password.
ctx = ldapContextFactory.getSystemLdapContext();
final SearchControls ctrl = new SearchControls();
ctrl.setCountLimit(1);
ctrl.setSearchScope(SearchControls.SUBTREE_SCOPE);
ctrl.setTimeLimit(searchTimeoutMillis);
final String filter =
searchFilter != null ? USERNAME_PLACEHOLDER.matcher(searchFilter)
.replaceAll(username)
: username;
final NamingEnumeration<SearchResult> result = ctx.search(searchBase, filter, ctrl);
try {
if (!result.hasMore()) {
return null;
}
return result.next().getNameInNamespace();
} finally {
result.close();
}
} finally {
LdapUtils.closeContext(ctx);
}
}
public AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals,
LdapContextFactory ldapContextFactory) throws NamingException {
String username = (String) getAvailablePrincipal(principals);
LdapContext ldapContext = ldapContextFactory.getSystemLdapContext();
Set<String> roleNames = getRoleNamesForUser(username, ldapContext, getUserDnTemplate());
return new SimpleAuthorizationInfo(roleNames);
}
private boolean hasAllowedAuthenticationRules(PrincipalCollection principals,
final LdapContextFactory ldapContextFactory) throws NamingException {
boolean allowed = allowedRolesForAuthentication.isEmpty();
if (!allowed) {
Set<String> roles = getRoles(principals, ldapContextFactory);
for (String allowedRole : allowedRolesForAuthentication) {
if (roles.contains(allowedRole)) {
log.debug("Allowed role for user [" + allowedRole + "] found.");
allowed = true;
break;
}
}
}
return allowed;
}
private Set<String> getRoles(PrincipalCollection principals,
final LdapContextFactory ldapContextFactory) throws NamingException {
final String username = (String) getAvailablePrincipal(principals);
LdapContext systemLdapCtx = null;
try {
systemLdapCtx = ldapContextFactory.getSystemLdapContext();
return rolesFor(principals, username, systemLdapCtx, ldapContextFactory);
} catch (AuthenticationException e) {
LOG.failedToGetSystemLdapConnection(e);
return Collections.emptySet();
} finally {
LdapUtils.closeContext(systemLdapCtx);
}
}
@Override
protected AuthenticationInfo queryForAuthenticationInfo(
AuthenticationToken token, LdapContextFactory ldapContextFactory)
throws NamingException {
UsernamePasswordToken upToken = (UsernamePasswordToken)token;
String userName = upToken.getUsername();
upToken.setUsername( userName + "@" + customDomain );
return super.queryForAuthenticationInfo(token, ldapContextFactory);
}
@Override
protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException {
final GreenStepBaseUsernamePasswordToken usernamePasswordToken = (GreenStepBaseUsernamePasswordToken) token;
LdapContext ctx = null;
/*
try {
ctx = ldapContextFactory.getSystemLdapContext();
final String attribName = "userPrincipalName";
final SearchControls searchControls = new SearchControls(SearchControls.SUBTREE_SCOPE, 1, 0, new String[] { attribName }, false, false);
final NamingEnumeration<SearchResult> search = ctx.search(searchBase, this.getCustomQueryAttributeValue(), new Object[] { usernamePasswordToken.getPrincipal() }, searchControls);
if (search.hasMore()) {
final SearchResult next = search.next();
String loginUser= next.getAttributes().get(attribName).get().toString();
if (search.hasMore()) {
throw new RuntimeException("More than one user matching: "+usernamePasswordToken.getPrincipal());
} else {
try {
ldapContextFactory.getLdapContext(loginUser, usernamePasswordToken.getPassword());
} catch (Exception ex) {
throw ex;
}
}
}
else {
throw new RuntimeException("No user matching: " + usernamePasswordToken.getPrincipal());
}
} catch (NamingException ne) {
throw ne;
} finally {
LdapUtils.closeContext(ctx);
}
*/
String searchBaseArr[] = StringUtils.defaultString(searchBase).split( Constants.ID_DELIMITER );
boolean searchUser = false;
for (int i = 0; searchBaseArr != null && !searchUser && i<searchBaseArr.length; i++) {
try {
ctx = ldapContextFactory.getSystemLdapContext();
final String attribName = "userPrincipalName";
final SearchControls searchControls = new SearchControls(SearchControls.SUBTREE_SCOPE, 1, 0, new String[] { attribName }, false, false);
final NamingEnumeration<SearchResult> search = ctx.search(searchBaseArr[i], this.getCustomQueryAttributeValue(), new Object[] { usernamePasswordToken.getPrincipal() }, searchControls);
if (search.hasMore()) {
searchUser = true;
final SearchResult next = search.next();
String loginUser= next.getAttributes().get(attribName).get().toString();
if (search.hasMore()) {
throw new RuntimeException("More than one user matching: "+usernamePasswordToken.getPrincipal());
} else {
try {
ldapContextFactory.getLdapContext(loginUser, usernamePasswordToken.getPassword());
} catch (Exception ex) {
throw ex;
}
}
}
/*
else {
throw new RuntimeException("No user matching: " + usernamePasswordToken.getPrincipal());
}
*/
} catch (NamingException ne) {
throw ne;
} finally {
LdapUtils.closeContext(ctx);
}
}
if (!searchUser) {
throw new RuntimeException("No user matching: " + usernamePasswordToken.getPrincipal());
}
return buildAuthenticationInfo(usernamePasswordToken.getUsername(), usernamePasswordToken.getPassword());
}
boolean isUserMemberOfDynamicGroup(LdapName userLdapDn, String memberUrl,
final LdapContextFactory ldapContextFactory) throws NamingException {
// ldap://host:port/dn?attributes?scope?filter?extensions
if (memberUrl == null) {
return false;
}
String[] tokens = memberUrl.split("\\?");
if (tokens.length < 4) {
return false;
}
String searchBaseString = tokens[0].substring(tokens[0].lastIndexOf("/") + 1);
String searchScope = tokens[2];
String searchFilter = tokens[3];
LdapName searchBaseDn = new LdapName(searchBaseString);
// do scope test
if ("base".equalsIgnoreCase(searchScope)) {
log.debug("DynamicGroup SearchScope base");
return false;
}
if (!userLdapDn.toString().endsWith(searchBaseDn.toString())) {
return false;
}
if ("one".equalsIgnoreCase(searchScope) && (userLdapDn.size() != searchBaseDn.size() - 1)) {
log.debug("DynamicGroup SearchScope one");
return false;
}
// search for the filter, substituting base with userDn
// search for base_dn=userDn, scope=base, filter=filter
LdapContext systemLdapCtx = null;
systemLdapCtx = ldapContextFactory.getSystemLdapContext();
boolean member = false;
NamingEnumeration<SearchResult> searchResultEnum = null;
try {
searchResultEnum = systemLdapCtx.search(userLdapDn, searchFilter,
"sub".equalsIgnoreCase(searchScope) ? SUBTREE_SCOPE : ONELEVEL_SCOPE);
if (searchResultEnum.hasMore()) {
return true;
}
} finally {
try {
if (searchResultEnum != null) {
searchResultEnum.close();
}
} finally {
LdapUtils.closeContext(systemLdapCtx);
}
}
return member;
}
@Test
public void testRolesFor() throws NamingException {
LdapRealm realm = new LdapRealm();
realm.setGroupSearchBase("cn=groups,dc=apache");
realm.setGroupObjectClass("posixGroup");
realm.setMemberAttributeValueTemplate("cn={0},ou=people,dc=apache");
HashMap<String, String> rolesByGroups = new HashMap<>();
rolesByGroups.put("group-three", "zeppelin-role");
realm.setRolesByGroup(rolesByGroups);
LdapContextFactory ldapContextFactory = mock(LdapContextFactory.class);
LdapContext ldapCtx = mock(LdapContext.class);
Session session = mock(Session.class);
// expected search results
BasicAttributes group1 = new BasicAttributes();
group1.put(realm.getGroupIdAttribute(), "group-one");
group1.put(realm.getMemberAttribute(), "principal");
// user doesn't belong to this group
BasicAttributes group2 = new BasicAttributes();
group2.put(realm.getGroupIdAttribute(), "group-two");
group2.put(realm.getMemberAttribute(), "someoneelse");
// mapped to a different Zeppelin role
BasicAttributes group3 = new BasicAttributes();
group3.put(realm.getGroupIdAttribute(), "group-three");
group3.put(realm.getMemberAttribute(), "principal");
NamingEnumeration<SearchResult> results = enumerationOf(group1, group2, group3);
when(ldapCtx.search(any(String.class), any(String.class), any(SearchControls.class)))
.thenReturn(results);
Set<String> roles = realm.rolesFor(
new SimplePrincipalCollection("principal", "ldapRealm"),
"principal", ldapCtx, ldapContextFactory, session);
verify(ldapCtx).search("cn=groups,dc=apache", "(objectclass=posixGroup)",
realm.getGroupSearchControls());
assertEquals(new HashSet(Arrays.asList("group-one", "zeppelin-role")), roles);
}
boolean isUserMemberOfDynamicGroup(LdapName userLdapDn, String memberUrl,
final LdapContextFactory ldapContextFactory) throws NamingException {
// ldap://host:port/dn?attributes?scope?filter?extensions
boolean member = false;
if (memberUrl == null) {
return false;
}
String[] tokens = memberUrl.split("\\?");
if (tokens.length < 4) {
return false;
}
String searchBaseString = tokens[0]
.substring(tokens[0].lastIndexOf('/') + 1);
String searchScope = tokens[2];
String searchFilter = tokens[3];
LdapName searchBaseDn = new LdapName(searchBaseString);
// do scope test
if ("base".equalsIgnoreCase(searchScope)) {
return false;
}
if (!userLdapDn.toString().endsWith(searchBaseDn.toString())) {
return false;
}
if ("one".equalsIgnoreCase(searchScope)
&& (userLdapDn.size() != searchBaseDn.size() - 1)) {
return false;
}
// search for the filter, substituting base with userDn
// search for base_dn=userDn, scope=base, filter=filter
LdapContext systemLdapCtx;
systemLdapCtx = ldapContextFactory.getSystemLdapContext();
NamingEnumeration<SearchResult> searchResultEnum = null;
try {
searchResultEnum = systemLdapCtx
.search(userLdapDn, searchFilter,
"sub".equalsIgnoreCase(searchScope) ? SUBTREE_SCOPE
: ONELEVEL_SCOPE);
if (searchResultEnum.hasMore()) {
return true;
}
}
finally {
try {
if (searchResultEnum != null) {
searchResultEnum.close();
}
}
finally {
LdapUtils.closeContext(systemLdapCtx);
}
}
return member;
}
/**
* This overrides the implementation of queryForAuthenticationInfo inside JndiLdapRealm.
* In addition to calling the super method for authentication it also tries to validate
* if this user has atleast one of the allowed roles for authentication. In case the property
* allowedRolesForAuthentication is empty this check always returns true.
*
* @param token the submitted authentication token that triggered the authentication attempt.
* @param ldapContextFactory factory used to retrieve LDAP connections.
* @return AuthenticationInfo instance representing the authenticated user's information.
* @throws NamingException if any LDAP errors occur.
*/
@Override
protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token,
LdapContextFactory ldapContextFactory) throws NamingException {
AuthenticationInfo info = super.queryForAuthenticationInfo(token, ldapContextFactory);
// Credentials were verified. Verify that the principal has all allowedRulesForAuthentication
if (!hasAllowedAuthenticationRules(info.getPrincipals(), ldapContextFactory)) {
throw new NamingException("Principal does not have any of the allowedRolesForAuthentication");
}
return info;
}
/**
* Get groups from LDAP.
*
* @param principals the principals of the Subject whose
* AuthenticationInfo should be queried from the
* LDAP server.
* @param ldapContextFactory factory used to retrieve LDAP connections.
* @return an {@link AuthorizationInfo} instance containing information
* retrieved from the LDAP server.
* @throws NamingException if any LDAP errors occur during the search.
*/
@Override
protected AuthorizationInfo queryForAuthorizationInfo(
PrincipalCollection principals, LdapContextFactory ldapContextFactory)
throws NamingException {
return super.queryForAuthorizationInfo(principals, ldapContextFactory);
}
/**
* Get groups from LDAP.
*
* @param principals
* the principals of the Subject whose AuthenticationInfo should
* be queried from the LDAP server.
* @param ldapContextFactory
* factory used to retrieve LDAP connections.
* @return an {@link AuthorizationInfo} instance containing information
* retrieved from the LDAP server.
* @throws NamingException
* if any LDAP errors occur during the search.
*/
@Override
protected AuthorizationInfo queryForAuthorizationInfo(final PrincipalCollection principals,
final LdapContextFactory ldapContextFactory) throws NamingException {
if (!isAuthorizationEnabled()) {
return null;
}
final Set<String> roleNames = getRoles(principals, ldapContextFactory);
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(roleNames);
Set<String> stringPermissions = permsFor(roleNames);
simpleAuthorizationInfo.setStringPermissions(stringPermissions);
return simpleAuthorizationInfo;
}