| /** |
| * |
| * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation |
| */ |
| package org.eclipse.osbp.authentication.shiro.extensions; |
| |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.naming.AuthenticationNotSupportedException; |
| import javax.naming.NameNotFoundException; |
| import javax.naming.NamingEnumeration; |
| import javax.naming.NamingException; |
| import javax.naming.directory.Attributes; |
| import javax.naming.directory.SearchControls; |
| import javax.naming.directory.SearchResult; |
| import javax.naming.ldap.LdapContext; |
| |
| import org.apache.shiro.authc.AuthenticationException; |
| import org.apache.shiro.authc.AuthenticationInfo; |
| import org.apache.shiro.authc.AuthenticationToken; |
| import org.apache.shiro.authc.SimpleAuthenticationInfo; |
| import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher; |
| import org.apache.shiro.authz.AuthorizationException; |
| import org.apache.shiro.authz.AuthorizationInfo; |
| import org.apache.shiro.ldap.UnsupportedAuthenticationMechanismException; |
| import org.apache.shiro.realm.ldap.JndiLdapContextFactory; |
| import org.apache.shiro.realm.ldap.LdapContextFactory; |
| import org.apache.shiro.realm.ldap.LdapUtils; |
| import org.apache.shiro.subject.PrincipalCollection; |
| import org.apache.shiro.util.StringUtils; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.eclipse.osbp.authentication.account.dtos.UserAccountDto; |
| import org.eclipse.osbp.authentication.providerimpl.AuthorizationInformation; |
| import org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm; |
| import org.eclipse.osbp.preferences.ProductConfiguration; |
| import org.eclipse.osbp.ui.api.useraccess.AbstractPosition; |
| |
| /** |
| * The Class LDAPRealm provides a layer for authentication via LDAP services. |
| */ |
| @SuppressWarnings("rawtypes") |
| public class LDAPRealm extends UserAccessAuthorizationRealm { |
| |
| /** The Constant log. */ |
| private static final Logger log = LoggerFactory.getLogger("realm"); |
| |
| /** The Constant USERDN_SUBSTITUTION_TOKEN. */ |
| //The zero index currently means nothing, but could be utilized in the future for other substitution techniques. |
| private static final String USERDN_SUBSTITUTION_TOKEN = "{0}"; |
| |
| /** The user dn prefix. */ |
| private String userDnPrefix; |
| |
| /** The user dn suffix. */ |
| private String userDnSuffix; |
| |
| /** |
| * The LdapContextFactory instance used to acquire {@link javax.naming.ldap.LdapContext LdapContext}'s at runtime |
| * to acquire connections to the LDAP directory to perform authentication attempts and authorizatino queries. |
| */ |
| private LdapContextFactory contextFactory; |
| |
| /** The authentication info. */ |
| private AuthenticationInfo authenticationInfo = null; |
| |
| /** The authorization info. */ |
| private AuthorizationInfo authorizationInfo = null; |
| |
| /** The ldap token. */ |
| private IPortalAuthenticationToken ldapToken = null; |
| |
| /** |
| * Instantiates a new LDAP realm. |
| */ |
| public LDAPRealm() { |
| //Credentials Matching is not necessary - the LDAP directory will do it automatically: |
| setCredentialsMatcher(new AllowAllCredentialsMatcher()); |
| //Any Object principal and Object credentials may be passed to the LDAP provider, so accept any token: |
| setAuthenticationTokenClass(AuthenticationToken.class); |
| setName(ProductConfiguration.SHIRO_LDAP_REALM); |
| contextFactory = new JndiLdapContextFactory(); |
| setAuthorizationCachingEnabled(true); |
| if (!org.eclipse.osbp.preferences.ProductConfigurationPrefs.SHIRO_LDAP_REALM_CLASS.equals(getClass().getCanonicalName())) { |
| throw new IllegalArgumentException("configuration key in preferences has to be modified"); |
| } |
| } |
| |
| /** |
| * Returns the User DN prefix to use when building a runtime User DN value or {@code null} if no |
| * {@link #getUserDnTemplate() userDnTemplate} has been configured. If configured, this value is the text that |
| * occurs before the {@link #USERDN_SUBSTITUTION_TOKEN} in the {@link #getUserDnTemplate() userDnTemplate} value. |
| * |
| * @return the the User DN prefix to use when building a runtime User DN value or {@code null} if no |
| * {@link #getUserDnTemplate() userDnTemplate} has been configured. |
| */ |
| protected String getUserDnPrefix() { |
| return userDnPrefix; |
| } |
| |
| /** |
| * Returns the User DN suffix to use when building a runtime User DN value. or {@code null} if no |
| * {@link #getUserDnTemplate() userDnTemplate} has been configured. If configured, this value is the text that |
| * occurs after the {@link #USERDN_SUBSTITUTION_TOKEN} in the {@link #getUserDnTemplate() userDnTemplate} value. |
| * |
| * @return the User DN suffix to use when building a runtime User DN value or {@code null} if no |
| * {@link #getUserDnTemplate() userDnTemplate} has been configured. |
| */ |
| protected String getUserDnSuffix() { |
| return userDnSuffix; |
| } |
| |
| /** |
| * Sets the User Distinguished Name (DN) template to use when creating User DNs at runtime. A User DN is an LDAP |
| * fully-qualified unique user identifier which is required to establish a connection with the LDAP |
| * directory to authenticate users and query for authorization information. |
| * <h2>Usage</h2> |
| * User DN formats are unique to the LDAP directory's schema, and each environment differs - you will need to |
| * specify the format corresponding to your directory. You do this by specifying the full User DN as normal, but |
| * but you use a <b>{@code {0}}</b> placeholder token in the string representing the location where the |
| * user's submitted principal (usually a username or uid) will be substituted at runtime. |
| * <p> |
| * For example, if your directory |
| * uses an LDAP {@code uid} attribute to represent usernames, the User DN for the {@code jsmith} user may look like |
| * this: |
| * <br> |
| * <pre>uid=jsmith,ou=users,dc=mycompany,dc=com</pre> |
| * <p> |
| * in which case you would set this property with the following template value: |
| * <br> |
| * <pre>uid=<b>{0}</b>,ou=users,dc=mycompany,dc=com</pre> |
| * <p> |
| * If no template is configured, the raw {@code AuthenticationToken} |
| * {@link AuthenticationToken#getPrincipal() principal} will be used as the LDAP principal. This is likely |
| * incorrect as most LDAP directories expect a fully-qualified User DN as opposed to the raw uid or username. So, |
| * ensure you set this property to match your environment! |
| * |
| * @param template the User Distinguished Name template to use for runtime substitution |
| * @throws IllegalArgumentException if the template is null, empty, or does not contain the |
| * {@code {0}} substitution token. |
| * @see LdapContextFactory#getLdapContext(Object,Object) |
| */ |
| public void setUserDnTemplate(String template) { |
| if (!StringUtils.hasText(template)) { |
| String msg = "User DN template cannot be null or empty."; |
| throw new IllegalArgumentException(msg); |
| } |
| int index = template.indexOf(USERDN_SUBSTITUTION_TOKEN); |
| if (index < 0) { |
| String msg = "User DN template must contain the '" + |
| USERDN_SUBSTITUTION_TOKEN + "' replacement token to understand where to " + |
| "insert the runtime authentication principal."; |
| throw new IllegalArgumentException(msg); |
| } |
| String prefix = template.substring(0, index); |
| String suffix = template.substring(prefix.length() + USERDN_SUBSTITUTION_TOKEN.length()); |
| if (log.isDebugEnabled()) { |
| log.debug("Determined user DN prefix [{}] and suffix [{}]", prefix, suffix); |
| } |
| this.userDnPrefix = prefix; |
| this.userDnSuffix = suffix; |
| } |
| |
| /** |
| * Returns the User Distinguished Name (DN) template to use when creating User DNs at runtime - see the |
| * {@link #setUserDnTemplate(String) setUserDnTemplate} JavaDoc for a full explanation. |
| * |
| * @return the User Distinguished Name (DN) template to use when creating User DNs at runtime. |
| */ |
| public String getUserDnTemplate() { |
| return getUserDn(USERDN_SUBSTITUTION_TOKEN); |
| } |
| |
| /** |
| * Returns the LDAP User Distinguished Name (DN) to use when acquiring an |
| * {@link javax.naming.ldap.LdapContext LdapContext} from the {@link LdapContextFactory}. |
| * <p> |
| * If the the {@link #getUserDnTemplate() userDnTemplate} property has been set, this implementation will construct |
| * the User DN by substituting the specified {@code principal} into the configured template. If the |
| * {@link #getUserDnTemplate() userDnTemplate} has not been set, the method argument will be returned directly |
| * (indicating that the submitted authentication token principal <em>is</em> the User DN). |
| * |
| * @param principal the principal to substitute into the configured {@link #getUserDnTemplate() userDnTemplate}. |
| * @return the constructed User DN to use at runtime when acquiring an {@link javax.naming.ldap.LdapContext}. |
| * @throws IllegalArgumentException if the method argument is null or empty |
| * @throws IllegalStateException if the {@link #getUserDnTemplate userDnTemplate} has not been set. |
| * @see LdapContextFactory#getLdapContext(Object, Object) |
| */ |
| protected String getUserDn(String principal) throws IllegalArgumentException, IllegalStateException { |
| if (!StringUtils.hasText(principal)) { |
| throw new IllegalArgumentException("User principal cannot be null or empty for User DN construction."); |
| } |
| String prefix = getUserDnPrefix(); |
| String suffix = getUserDnSuffix(); |
| if (prefix == null && suffix == null) { |
| log.debug("userDnTemplate property has not been configured, indicating the submitted " + |
| "AuthenticationToken's principal is the same as the User DN. Returning the method argument " + |
| "as is."); |
| return principal; |
| } |
| |
| int prefixLength = prefix != null ? prefix.length() : 0; |
| int suffixLength = suffix != null ? suffix.length() : 0; |
| StringBuilder sb = new StringBuilder(prefixLength + principal.length() + suffixLength); |
| if (prefixLength > 0) { |
| sb.append(prefix); |
| } |
| sb.append(principal); |
| if (suffixLength > 0) { |
| sb.append(suffix); |
| } |
| return sb.toString(); |
| } |
| |
| /** |
| * Sets the LdapContextFactory instance used to acquire connections to the LDAP directory during authentication |
| * attempts and authorization queries. Unless specified otherwise, the default is a {@link JndiLdapContextFactory} |
| * instance. |
| * |
| * @param contextFactory the LdapContextFactory instance used to acquire connections to the LDAP directory during |
| * authentication attempts and authorization queries |
| */ |
| public void setContextFactory(LdapContextFactory contextFactory) { |
| this.contextFactory = contextFactory; |
| } |
| |
| /** |
| * Returns the LdapContextFactory instance used to acquire connections to the LDAP directory during authentication |
| * attempts and authorization queries. Unless specified otherwise, the default is a {@link JndiLdapContextFactory} |
| * instance. |
| * |
| * @return the LdapContextFactory instance used to acquire connections to the LDAP directory during |
| * authentication attempts and authorization queries |
| */ |
| public LdapContextFactory getContextFactory() { |
| return this.contextFactory; |
| } |
| |
| /*-------------------------------------------- |
| | M E T H O D S | |
| ============================================*/ |
| |
| /** |
| * Delegates to {@link #queryForAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken, LdapContextFactory)}, |
| * wrapping any {@link NamingException}s in a Shiro {@link AuthenticationException} to satisfy the parent method |
| * signature. |
| * |
| * @param token the authentication token containing the user's principal and credentials. |
| * @return the {@link AuthenticationInfo} acquired after a successful authentication attempt |
| * @throws AuthenticationException if the authentication attempt fails or if a |
| * {@link NamingException} occurs. |
| */ |
| @Override |
| protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { |
| ldapToken = (IPortalAuthenticationToken)token; |
| try { |
| authenticationInfo = queryForAuthenticationInfo(token, getContextFactory()); |
| } catch (AuthenticationNotSupportedException e) { |
| String msg = "Unsupported configured authentication mechanism"; |
| log.debug(msg); |
| throw new UnsupportedAuthenticationMechanismException(msg, e); |
| } catch (javax.naming.AuthenticationException e) { |
| String msg = "LDAP authentication failed."+e.getLocalizedMessage(); |
| if (e.getExplanation()!= null) { |
| msg += e.getExplanation(); |
| } |
| log.debug(msg); |
| throw new AuthenticationException("LDAP authentication failed.", e); |
| } catch (NamingException e) { |
| String msg = "LDAP naming error while attempting to authenticate user."; |
| log.debug(msg); |
| throw new AuthenticationException(msg, e); |
| } |
| if (authenticationInfo != null) { |
| ldapToken.setAuthenticatedByRealm(this); |
| } |
| return authenticationInfo; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection) |
| */ |
| @Override |
| protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { |
| try { |
| authorizationInfo = queryForAuthorizationInfo(principals, getContextFactory()); |
| } catch (NamingException e) { |
| String msg = "LDAP naming error while attempting to retrieve authorization for user [" + principals + "]."; |
| log.debug(msg); |
| throw new AuthorizationException(msg, e); |
| } |
| |
| return authorizationInfo; |
| } |
| |
| /** |
| * Returns the principal to use when creating the LDAP connection for an authentication attempt. |
| * <p> |
| * This implementation uses a heuristic: it checks to see if the specified token's |
| * {@link AuthenticationToken#getPrincipal() principal} is a {@code String}, and if so, |
| * {@link #getUserDn(String) converts it} from what is |
| * assumed to be a raw uid or username {@code String} into a User DN {@code String}. Almost all LDAP directories |
| * expect the authentication connection to present a User DN and not an unqualified username or uid. |
| * <p> |
| * If the token's {@code principal} is not a String, it is assumed to already be in the format supported by the |
| * underlying {@link LdapContextFactory} implementation and the raw principal is returned directly. |
| * |
| * @param token the {@link AuthenticationToken} submitted during the authentication process |
| * @return the User DN or raw principal to use to acquire the LdapContext. |
| * @see LdapContextFactory#getLdapContext(Object, Object) |
| */ |
| protected Object getLdapPrincipal(AuthenticationToken token) { |
| Object principal = token.getPrincipal(); |
| if (principal instanceof String) { |
| String sPrincipal = (String) principal; |
| return getUserDn(sPrincipal); |
| } |
| return principal; |
| } |
| |
| /** |
| * This implementation opens an LDAP connection using the token's |
| * {@link #getLdapPrincipal(org.apache.shiro.authc.AuthenticationToken) discovered principal} and provided |
| * {@link AuthenticationToken#getCredentials() credentials}. If the connection opens successfully, the |
| * authentication attempt is immediately considered successful and a new |
| * {@link AuthenticationInfo} instance is |
| * {@link #createAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken, Object, Object, javax.naming.ldap.LdapContext) created} |
| * and returned. If the connection cannot be opened, either because LDAP authentication failed or some other |
| * JNDI problem, an {@link NamingException} will be thrown. |
| * |
| * @param token the submitted authentication token that triggered the authentication attempt. |
| * @param ldapContextFactory factory used to retrieve LDAP connections. |
| * @return an {@link AuthenticationInfo} instance representing the authenticated user's information. |
| * @throws NamingException if any LDAP errors occur. |
| */ |
| protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, |
| LdapContextFactory ldapContextFactory) |
| throws NamingException { |
| |
| Object principal = token.getPrincipal(); |
| Object credentials = token.getCredentials(); |
| |
| log.debug("Authenticating user '{}' through LDAP", principal); |
| |
| principal = getLdapPrincipal(token); |
| LdapContext ctx = null; |
| |
| try { |
| ctx = ldapContextFactory.getLdapContext(principal, credentials); |
| //context was opened successfully, which means their credentials were valid. Return the AuthenticationInfo: |
| return createAuthenticationInfo(token, principal, credentials, ctx); |
| } finally { |
| LdapUtils.closeContext(ctx); |
| } |
| } |
| |
| /** |
| * Returns the {@link AuthenticationInfo} resulting from a Subject's successful LDAP authentication attempt. |
| * <p> |
| * This implementation ignores the {@code ldapPrincipal}, {@code ldapCredentials}, and the opened |
| * {@code ldapContext} arguments and merely returns an {@code AuthenticationInfo} instance mirroring the |
| * submitted token's principal and credentials. This is acceptable because this method is only ever invoked after |
| * a successful authentication attempt, which means the provided principal and credentials were correct, and can |
| * be used directly to populate the (now verified) {@code AuthenticationInfo}. |
| * <p> |
| * Subclasses however are free to override this method for more advanced construction logic. |
| * |
| * @param token the submitted {@code AuthenticationToken} that resulted in a successful authentication |
| * @param ldapPrincipal the LDAP principal used when creating the LDAP connection. Unlike the token's |
| * {@link AuthenticationToken#getPrincipal() principal}, this value is usually a constructed |
| * User DN and not a simple username or uid. The exact value is depending on the |
| * configured |
| * <a href="http://download-llnw.oracle.com/javase/tutorial/jndi/ldap/auth_mechs.html"> |
| * LDAP authentication mechanism</a> in use. |
| * @param ldapCredentials the LDAP credentials used when creating the LDAP connection. |
| * @param ldapContext the LdapContext created that resulted in a successful authentication. It can be used |
| * further by subclasses for more complex operations. It does not need to be closed - |
| * it will be closed automatically after this method returns. |
| * @return the {@link AuthenticationInfo} resulting from a Subject's successful LDAP authentication attempt. |
| * @throws NamingException if there was any problem using the {@code LdapContext} |
| */ |
| protected AuthenticationInfo createAuthenticationInfo(AuthenticationToken token, Object ldapPrincipal, |
| Object ldapCredentials, LdapContext ldapContext) |
| throws NamingException { |
| return new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), ProductConfiguration.SHIRO_LDAP_REALM); |
| } |
| |
| |
| /** |
| * Method to build an |
| * {@link AuthorizationInfo} object by querying the LDAP context for the |
| * specified principal. |
| * <br> |
| * @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. |
| */ |
| protected AuthorizationInfo queryForAuthorizationInfo( |
| PrincipalCollection principals, |
| LdapContextFactory ldapContextFactory) throws NamingException { |
| // return super.queryForAuthorizationInfo(principals, ldapContextFactory); |
| String username = principals.toString(); |
| AbstractPosition position = findPositionForUser(username); |
| if (position == null) { |
| return null; |
| } |
| return new AuthorizationInformation( |
| getPortalId(), |
| principals, |
| position, |
| position.getRoles(), |
| findPermissionsForUser(username)); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.shiro.realm.AuthenticatingRealm#supports(org.apache.shiro.authc.AuthenticationToken) |
| */ |
| @Override |
| public boolean supports(AuthenticationToken token) { |
| return token != null && token instanceof IPortalAuthenticationToken && |
| getPortalId().equals(((IPortalAuthenticationToken)token).getPortalId()); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm#getAllUsers() |
| */ |
| @Override |
| public Set<String> getAllUsers() { |
| Set<String> retcode = new HashSet<>(); |
| if (authenticationInfo == null) { |
| return retcode; |
| } |
| LdapContext ctx = null; |
| NamingEnumeration results = null; |
| try { |
| ctx = getContextFactory().getLdapContext(authenticationInfo.getPrincipals(), authenticationInfo.getCredentials()); |
| SearchControls controls = new SearchControls(); |
| controls.setSearchScope(SearchControls.SUBTREE_SCOPE); |
| results = ctx.search("", "(objectclass=person)", controls); |
| while (results.hasMore()) { |
| SearchResult searchResult = (SearchResult) results.next(); |
| Attributes attributes = searchResult.getAttributes(); |
| retcode.add(""+attributes.get("cn").get()); |
| // System.out.println("dn----------> "+searchResult.getName()); |
| // System.out.println("cn----------> "+attributes.get("cn").get()); |
| // if (attributes.get("givenName")!=null) |
| // System.out.println("First Name--> "+attributes.get("givenName").get()); |
| // System.out.println("Last Name---> "+attributes.get("sn").get()); |
| // System.out.println("Mail--------> "+attributes.get("mail").get()+"\n\n"); |
| } |
| } catch (NameNotFoundException e) { |
| log.error(e.getLocalizedMessage()); |
| } catch (NamingException e) { |
| log.error(e.getExplanation()); |
| } finally { |
| if (results != null) { |
| try { |
| results.close(); |
| } catch (Exception e) { // NOSONAR |
| log.error(e.getLocalizedMessage()); |
| } |
| } |
| LdapUtils.closeContext(ctx); |
| } |
| return retcode; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm#getAllUsersPositions() |
| */ |
| @Override |
| public Map<String,String> getAllUsersPositions() { |
| Map<String,String> retcode = new HashMap<>(); |
| if (authenticationInfo == null) { |
| return retcode; |
| } |
| LdapContext ctx = null; |
| NamingEnumeration results = null; |
| try { |
| ctx = getContextFactory().getLdapContext(authenticationInfo.getPrincipals(), authenticationInfo.getCredentials()); |
| SearchControls controls = new SearchControls(); |
| controls.setSearchScope(SearchControls.SUBTREE_SCOPE); |
| results = ctx.search("", "(objectclass=person)", controls); |
| while (results.hasMore()) { |
| SearchResult searchResult = (SearchResult) results.next(); |
| Attributes attributes = searchResult.getAttributes(); |
| // the ldap database must be extended for the attribute 'position' |
| retcode.put(""+attributes.get("cn").get(),""+attributes.get("position").get()); |
| // System.out.println("dn----------> "+searchResult.getName()); |
| // System.out.println("cn----------> "+attributes.get("cn").get()); |
| // if (attributes.get("givenName")!=null) |
| // System.out.println("First Name--> "+attributes.get("givenName").get()); |
| // System.out.println("Last Name---> "+attributes.get("sn").get()); |
| // System.out.println("Mail--------> "+attributes.get("mail").get()+"\n\n"); |
| } |
| } catch (NameNotFoundException e) { // NOSONAR |
| log.error(e.getLocalizedMessage()); |
| } catch (NamingException e) { // NOSONAR |
| log.error(e.getExplanation()); |
| } finally { |
| if (results != null) { |
| try { |
| results.close(); |
| } catch (Exception e) { // NOSONAR |
| log.error(e.getLocalizedMessage()); |
| } |
| } |
| LdapUtils.closeContext(ctx); |
| } |
| return retcode; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.authentication.shiro.extensions.IUserAccess#getAllEmails() |
| */ |
| @Override |
| public Set<String> getAllEmails() { |
| Set<String> retcode = new HashSet<>(); |
| if (authenticationInfo == null) { |
| return retcode; |
| } |
| LdapContext ctx = null; |
| NamingEnumeration results = null; |
| try { |
| ctx = getContextFactory().getLdapContext(authenticationInfo.getPrincipals(), authenticationInfo.getCredentials()); |
| SearchControls controls = new SearchControls(); |
| controls.setSearchScope(SearchControls.SUBTREE_SCOPE); |
| results = ctx.search("", "(objectclass=person)", controls); |
| while (results.hasMore()) { |
| SearchResult searchResult = (SearchResult) results.next(); |
| Attributes attributes = searchResult.getAttributes(); |
| retcode.add(""+attributes.get("mail").get()); |
| } |
| } catch (NameNotFoundException e) { // NOSONAR |
| log.error(e.getLocalizedMessage()); |
| } catch (NamingException e) { // NOSONAR |
| log.error(e.getExplanation()); |
| } finally { |
| if (results != null) { |
| try { |
| results.close(); |
| } catch (Exception e) { // NOSONAR |
| log.error(e.getLocalizedMessage()); |
| } |
| } |
| LdapUtils.closeContext(ctx); |
| } |
| return retcode; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm#findUserAccount(java.lang.String) |
| */ |
| @Override |
| public UserAccountDto findUserAccount(String username) { |
| HashSet<UserAccountDto> users = new HashSet<>(); |
| if (authenticationInfo == null) { |
| return null; |
| } |
| LdapContext ctx = null; |
| NamingEnumeration results = null; |
| try { |
| ctx = getContextFactory().getLdapContext(authenticationInfo.getPrincipals(), authenticationInfo.getCredentials()); |
| SearchControls controls = new SearchControls(); |
| controls.setSearchScope(SearchControls.SUBTREE_SCOPE); |
| if (ldapToken.getUserProtocol().isFindByUserName()) { |
| // common name search |
| results = ctx.search("", "(cn="+username+")", controls); |
| } |
| else { |
| // email search |
| results = ctx.search("", "(mail="+username+")", controls); |
| } |
| while (results.hasMore()) { |
| SearchResult searchResult = (SearchResult) results.next(); |
| Attributes attributes = searchResult.getAttributes(); |
| UserAccountDto user = new UserAccountDto(); |
| user.setEnabled(true); |
| if (attributes.get("position")!=null) { |
| user.setPosition(""+attributes.get("position").get()); |
| } |
| user.setEmail(""+attributes.get("mail").get()); |
| user.setUserName(""+attributes.get("cn").get()); |
| users.add(user); |
| } |
| } catch (NameNotFoundException e) { |
| log.error(e.getLocalizedMessage()); |
| } catch (NamingException e) { // NOSONAR |
| log.error(e.getExplanation()); |
| } finally { |
| if (results != null) { |
| try { |
| results.close(); |
| } catch (Exception e) { // NOSONAR |
| log.error(e.getLocalizedMessage()); |
| } |
| } |
| LdapUtils.closeContext(ctx); |
| } |
| if (users.size() > 1) { |
| log.error("user account is not unique - first match taken"); |
| } else if (users.isEmpty()) { |
| log.debug("user account not found"); |
| return null; |
| } |
| return users.iterator().next(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm#findUsersForPosition(java.lang.String) |
| */ |
| @Override |
| public Set<String> findUsersForPosition(String orgNode) { |
| Set<String> retcode = new HashSet<>(); |
| if (authenticationInfo == null) { |
| return retcode; |
| } |
| LdapContext ctx = null; |
| NamingEnumeration results = null; |
| try { |
| ctx = getContextFactory().getLdapContext(authenticationInfo.getPrincipals(), authenticationInfo.getCredentials()); |
| SearchControls controls = new SearchControls(); |
| controls.setSearchScope(SearchControls.SUBTREE_SCOPE); |
| results = ctx.search("", "(objectclass=person)", controls); |
| while (results.hasMore()) { |
| SearchResult searchResult = (SearchResult) results.next(); |
| Attributes attributes = searchResult.getAttributes(); |
| if (attributes.get("position")!=null && |
| orgNode.equals((String)attributes.get("position").get()) ) { |
| |
| retcode.add(""+attributes.get("cn").get()); |
| } |
| } |
| } catch (NameNotFoundException e) { // NOSONAR |
| log.error(e.getLocalizedMessage()); |
| } catch (NamingException e) { // NOSONAR |
| log.error(e.getExplanation()); |
| } finally { |
| if (results != null) { |
| try { |
| results.close(); |
| } catch (Exception e) { // NOSONAR |
| log.error(e.getLocalizedMessage()); |
| } |
| } |
| LdapUtils.closeContext(ctx); |
| } |
| return retcode; |
| } |
| } |