/* * Copyright 2002-2016 the original author or authors. * * 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.springframework.security.core.authority.mapping; import java.util.*; import org.springframework.beans.factory.InitializingBean; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * This class implements the Attributes2GrantedAuthoritiesMapper and * MappableAttributesRetriever interfaces based on the supplied Map. It supports both * one-to-one and one-to-many mappings. The granted authorities to map to can be supplied * either as a String or as a GrantedAuthority object. * * @author Ruud Senden */ public class MapBasedAttributes2GrantedAuthoritiesMapper implements Attributes2GrantedAuthoritiesMapper, MappableAttributesRetriever, InitializingBean { private Map<String, Collection<GrantedAuthority>> attributes2grantedAuthoritiesMap = null; private String stringSeparator = ","; private Set<String> mappableAttributes = null; public void afterPropertiesSet() throws Exception { Assert.notNull(attributes2grantedAuthoritiesMap, "attributes2grantedAuthoritiesMap must be set"); } /** * Map the given array of attributes to Spring Security GrantedAuthorities. */ public List<GrantedAuthority> getGrantedAuthorities(Collection<String> attributes) { ArrayList<GrantedAuthority> gaList = new ArrayList<GrantedAuthority>(); for (String attribute : attributes) { Collection<GrantedAuthority> c = attributes2grantedAuthoritiesMap .get(attribute); if (c != null) { gaList.addAll(c); } } gaList.trimToSize(); return gaList; } /** * @return Returns the attributes2grantedAuthoritiesMap. */ public Map<String, Collection<GrantedAuthority>> getAttributes2grantedAuthoritiesMap() { return attributes2grantedAuthoritiesMap; } /** * @param attributes2grantedAuthoritiesMap The attributes2grantedAuthoritiesMap to * set. */ public void setAttributes2grantedAuthoritiesMap( final Map<?, ?> attributes2grantedAuthoritiesMap) { Assert.notEmpty(attributes2grantedAuthoritiesMap, "A non-empty attributes2grantedAuthoritiesMap must be supplied"); this.attributes2grantedAuthoritiesMap = preProcessMap(attributes2grantedAuthoritiesMap); mappableAttributes = Collections .unmodifiableSet(this.attributes2grantedAuthoritiesMap.keySet()); } /** * Preprocess the given map to convert all the values to GrantedAuthority collections * * @param orgMap The map to process * @return the processed Map */ private Map<String, Collection<GrantedAuthority>> preProcessMap(Map<?, ?> orgMap) { Map<String, Collection<GrantedAuthority>> result = new HashMap<String, Collection<GrantedAuthority>>( orgMap.size()); for (Map.Entry<?, ?> entry : orgMap.entrySet()) { Assert.isInstanceOf(String.class, entry.getKey(), "attributes2grantedAuthoritiesMap contains non-String objects as keys"); result.put((String) entry.getKey(), getGrantedAuthorityCollection(entry.getValue())); } return result; } /** * Convert the given value to a collection of Granted Authorities * * @param value The value to convert to a GrantedAuthority Collection * @return Collection containing the GrantedAuthority Collection */ private Collection<GrantedAuthority> getGrantedAuthorityCollection(Object value) { Collection<GrantedAuthority> result = new ArrayList<GrantedAuthority>(); addGrantedAuthorityCollection(result, value); return result; } /** * Convert the given value to a collection of Granted Authorities, adding the result * to the given result collection. * * @param value The value to convert to a GrantedAuthority Collection * @return Collection containing the GrantedAuthority Collection */ private void addGrantedAuthorityCollection(Collection<GrantedAuthority> result, Object value) { if (value == null) { return; } if (value instanceof Collection<?>) { addGrantedAuthorityCollection(result, (Collection<?>) value); } else if (value instanceof Object[]) { addGrantedAuthorityCollection(result, (Object[]) value); } else if (value instanceof String) { addGrantedAuthorityCollection(result, (String) value); } else if (value instanceof GrantedAuthority) { result.add((GrantedAuthority) value); } else { throw new IllegalArgumentException("Invalid object type: " + value.getClass().getName()); } } private void addGrantedAuthorityCollection(Collection<GrantedAuthority> result, Collection<?> value) { for (Object elt : value) { addGrantedAuthorityCollection(result, elt); } } private void addGrantedAuthorityCollection(Collection<GrantedAuthority> result, Object[] value) { for (Object aValue : value) { addGrantedAuthorityCollection(result, aValue); } } private void addGrantedAuthorityCollection(Collection<GrantedAuthority> result, String value) { StringTokenizer st = new StringTokenizer(value, stringSeparator, false); while (st.hasMoreTokens()) { String nextToken = st.nextToken(); if (StringUtils.hasText(nextToken)) { result.add(new SimpleGrantedAuthority(nextToken)); } } } /** * * @see org.springframework.security.core.authority.mapping.MappableAttributesRetriever#getMappableAttributes() */ public Set<String> getMappableAttributes() { return mappableAttributes; } /** * @return Returns the stringSeparator. */ public String getStringSeparator() { return stringSeparator; } /** * @param stringSeparator The stringSeparator to set. */ public void setStringSeparator(String stringSeparator) { this.stringSeparator = stringSeparator; } }