001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.shiro.realm.ldap; 020 021import java.util.Collection; 022import java.util.HashSet; 023import java.util.Set; 024import javax.naming.NamingEnumeration; 025import javax.naming.NamingException; 026import javax.naming.directory.Attribute; 027import javax.naming.ldap.LdapContext; 028 029import org.slf4j.Logger; 030import org.slf4j.LoggerFactory; 031 032/** 033 * Utility class providing static methods to make working with LDAP 034 * easier. 035 * 036 * @since 0.2 037 */ 038public final class LdapUtils { 039 040 /** 041 * Private internal log instance. 042 */ 043 private static final Logger LOGGER = LoggerFactory.getLogger(LdapUtils.class); 044 045 private LdapUtils() { 046 } 047 048 /** 049 * Closes an LDAP context, logging any errors, but not throwing 050 * an exception if there is a failure. 051 * 052 * @param ctx the LDAP context to close. 053 */ 054 public static void closeContext(LdapContext ctx) { 055 try { 056 if (ctx != null) { 057 ctx.close(); 058 } 059 } catch (NamingException e) { 060 LOGGER.error("Exception while closing LDAP context. ", e); 061 } 062 } 063 064 /** 065 * Helper method used to retrieve all attribute values from a particular context attribute. 066 * 067 * @param attr the LDAP attribute. 068 * @return the values of the attribute. 069 * @throws javax.naming.NamingException if there is an LDAP error while reading the values. 070 */ 071 public static Collection<String> getAllAttributeValues(Attribute attr) throws NamingException { 072 Set<String> values = new HashSet<String>(); 073 NamingEnumeration ne = null; 074 try { 075 ne = attr.getAll(); 076 while (ne.hasMore()) { 077 String value = (String) ne.next(); 078 values.add(value); 079 } 080 } finally { 081 closeEnumeration(ne); 082 } 083 084 return values; 085 } 086 087 /** 088 * added based on SHIRO-127, per Emmanuel's comment [1] 089 * [1] <a href="https://issues.apache.org/jira/browse/SHIRO-127?focusedCommentId=12891380&" 090 * + "page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12891380" /> 091 */ 092 public static void closeEnumeration(NamingEnumeration ne) { 093 try { 094 if (ne != null) { 095 ne.close(); 096 } 097 } catch (NamingException e) { 098 LOGGER.error("Exception while closing NamingEnumeration: ", e); 099 } 100 } 101 102}