Coverage Report - org.apache.shiro.realm.ldap.AbstractLdapRealm
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractLdapRealm
45%
22/48
50%
2/4
1.667
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.shiro.realm.ldap;
 20  
 
 21  
 import org.apache.shiro.authc.AuthenticationException;
 22  
 import org.apache.shiro.authc.AuthenticationInfo;
 23  
 import org.apache.shiro.authc.AuthenticationToken;
 24  
 import org.apache.shiro.authz.AuthorizationException;
 25  
 import org.apache.shiro.authz.AuthorizationInfo;
 26  
 import org.apache.shiro.realm.AuthorizingRealm;
 27  
 import org.apache.shiro.subject.PrincipalCollection;
 28  
 import org.slf4j.Logger;
 29  
 import org.slf4j.LoggerFactory;
 30  
 
 31  
 import javax.naming.NamingException;
 32  
 
 33  
 /**
 34  
  * <p>A {@link org.apache.shiro.realm.Realm} that authenticates with an LDAP
 35  
  * server to build the Subject for a user.  This implementation only returns roles for a
 36  
  * particular user, and not permissions - but it can be subclassed to build a permission
 37  
  * list as well.</p>
 38  
  *
 39  
  * <p>Implementations would need to implement the
 40  
  * {@link #queryForAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken ,LdapContextFactory)} and
 41  
  * {@link #queryForAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection ,LdapContextFactory)} abstract methods.</p>
 42  
  *
 43  
  * <p>By default, this implementation will create an instance of {@link DefaultLdapContextFactory} to use for
 44  
  * creating LDAP connections using the principalSuffix, searchBase, url, systemUsername, and systemPassword properties
 45  
  * specified on the realm.  The remaining settings use the defaults of {@link DefaultLdapContextFactory}, which are usually
 46  
  * sufficient.  If more customized connections are needed, you should inject a custom {@link LdapContextFactory}, which
 47  
  * will cause these properties specified on the realm to be ignored.</p>
 48  
  *
 49  
  * @see #queryForAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken , LdapContextFactory)
 50  
  * @see #queryForAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection , LdapContextFactory)
 51  
  * @since 0.1
 52  
  */
 53  1
 public abstract class AbstractLdapRealm extends AuthorizingRealm {
 54  
 
 55  
     //TODO - complete JavaDoc
 56  
 
 57  
     /*--------------------------------------------
 58  
     |             C O N S T A N T S             |
 59  
     ============================================*/
 60  
 
 61  1
     private static final Logger log = LoggerFactory.getLogger(AbstractLdapRealm.class);
 62  
 
 63  
     /*--------------------------------------------
 64  
     |    I N S T A N C E   V A R I A B L E S    |
 65  
     ============================================*/
 66  1
     protected String principalSuffix = null;
 67  
 
 68  1
     protected String searchBase = null;
 69  
 
 70  1
     protected String url = null;
 71  
 
 72  1
     protected String systemUsername = null;
 73  
 
 74  1
     protected String systemPassword = null;
 75  
 
 76  1
     private LdapContextFactory ldapContextFactory = null;
 77  
 
 78  
     /*--------------------------------------------
 79  
     |         C O N S T R U C T O R S           |
 80  
     ============================================*/
 81  
 
 82  
     /*--------------------------------------------
 83  
     |  A C C E S S O R S / M O D I F I E R S    |
 84  
     ============================================*/
 85  
 
 86  
     /*--------------------------------------------
 87  
     |               M E T H O D S               |
 88  
     ============================================*/
 89  
 
 90  
 
 91  
     /**
 92  
      * Used when initializing the default {@link LdapContextFactory}.  This property is ignored if a custom
 93  
      * <tt>LdapContextFactory</tt> is specified.
 94  
      *
 95  
      * @param principalSuffix the suffix.
 96  
      * @see DefaultLdapContextFactory#setPrincipalSuffix(String)
 97  
      */
 98  
     public void setPrincipalSuffix(String principalSuffix) {
 99  0
         this.principalSuffix = principalSuffix;
 100  0
     }
 101  
 
 102  
     /**
 103  
      * Used when initializing the default {@link LdapContextFactory}.  This property is ignored if a custom
 104  
      * <tt>LdapContextFactory</tt> is specified.
 105  
      *
 106  
      * @param searchBase the search base.
 107  
      * @see DefaultLdapContextFactory#setSearchBase(String)
 108  
      */
 109  
     public void setSearchBase(String searchBase) {
 110  0
         this.searchBase = searchBase;
 111  0
     }
 112  
 
 113  
     /**
 114  
      * Used when initializing the default {@link LdapContextFactory}.  This property is ignored if a custom
 115  
      * <tt>LdapContextFactory</tt> is specified.
 116  
      *
 117  
      * @param url the LDAP url.
 118  
      * @see DefaultLdapContextFactory#setUrl(String)
 119  
      */
 120  
     public void setUrl(String url) {
 121  0
         this.url = url;
 122  0
     }
 123  
 
 124  
     /**
 125  
      * Used when initializing the default {@link LdapContextFactory}.  This property is ignored if a custom
 126  
      * <tt>LdapContextFactory</tt> is specified.
 127  
      *
 128  
      * @param systemUsername the username to use when logging into the LDAP server for authorization.
 129  
      * @see DefaultLdapContextFactory#setSystemUsername(String)
 130  
      */
 131  
     public void setSystemUsername(String systemUsername) {
 132  0
         this.systemUsername = systemUsername;
 133  0
     }
 134  
 
 135  
 
 136  
     /**
 137  
      * Used when initializing the default {@link LdapContextFactory}.  This property is ignored if a custom
 138  
      * <tt>LdapContextFactory</tt> is specified.
 139  
      *
 140  
      * @param systemPassword the password to use when logging into the LDAP server for authorization.
 141  
      * @see DefaultLdapContextFactory#setSystemPassword(String)
 142  
      */
 143  
     public void setSystemPassword(String systemPassword) {
 144  0
         this.systemPassword = systemPassword;
 145  0
     }
 146  
 
 147  
 
 148  
     /**
 149  
      * Configures the {@link LdapContextFactory} implementation that is used to create LDAP connections for
 150  
      * authentication and authorization.  If this is set, the {@link LdapContextFactory} provided will be used.
 151  
      * Otherwise, a {@link DefaultLdapContextFactory} instance will be created based on the properties specified
 152  
      * in this realm.
 153  
      *
 154  
      * @param ldapContextFactory the factory to use - if not specified, a default factory will be created automatically.
 155  
      */
 156  
     public void setLdapContextFactory(LdapContextFactory ldapContextFactory) {
 157  0
         this.ldapContextFactory = ldapContextFactory;
 158  0
     }
 159  
 
 160  
     /*--------------------------------------------
 161  
     |               M E T H O D S                |
 162  
     ============================================*/
 163  
 
 164  
     protected void onInit() {
 165  0
         super.onInit();
 166  0
         ensureContextFactory();
 167  0
     }
 168  
 
 169  
     private LdapContextFactory ensureContextFactory() {
 170  1
         if (this.ldapContextFactory == null) {
 171  
 
 172  1
             if (log.isDebugEnabled()) {
 173  1
                 log.debug("No LdapContextFactory specified - creating a default instance.");
 174  
             }
 175  
 
 176  1
             DefaultLdapContextFactory defaultFactory = new DefaultLdapContextFactory();
 177  1
             defaultFactory.setPrincipalSuffix(this.principalSuffix);
 178  1
             defaultFactory.setSearchBase(this.searchBase);
 179  1
             defaultFactory.setUrl(this.url);
 180  1
             defaultFactory.setSystemUsername(this.systemUsername);
 181  1
             defaultFactory.setSystemPassword(this.systemPassword);
 182  
 
 183  1
             this.ldapContextFactory = defaultFactory;
 184  
         }
 185  1
         return this.ldapContextFactory;
 186  
     }
 187  
 
 188  
 
 189  
     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
 190  
         AuthenticationInfo info;
 191  
         try {
 192  1
             info = queryForAuthenticationInfo(token, ensureContextFactory());
 193  0
         } catch (javax.naming.AuthenticationException e) {
 194  0
             throw new AuthenticationException("LDAP authentication failed.", e);
 195  0
         } catch (NamingException e) {
 196  0
             String msg = "LDAP naming error while attempting to authenticate user.";
 197  0
             throw new AuthenticationException(msg, e);
 198  1
         }
 199  
 
 200  1
         return info;
 201  
     }
 202  
 
 203  
 
 204  
     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
 205  
         AuthorizationInfo info;
 206  
         try {
 207  0
             info = queryForAuthorizationInfo(principals, ensureContextFactory());
 208  0
         } catch (NamingException e) {
 209  0
             String msg = "LDAP naming error while attempting to retrieve authorization for user [" + principals + "].";
 210  0
             throw new AuthorizationException(msg, e);
 211  0
         }
 212  
 
 213  0
         return info;
 214  
     }
 215  
 
 216  
 
 217  
     /**
 218  
      * <p>Abstract method that should be implemented by subclasses to builds an
 219  
      * {@link AuthenticationInfo} object by querying the LDAP context for the
 220  
      * specified username.</p>
 221  
      *
 222  
      * @param token              the authentication token given during authentication.
 223  
      * @param ldapContextFactory factory used to retrieve LDAP connections.
 224  
      * @return an {@link AuthenticationInfo} instance containing information retrieved from the LDAP server.
 225  
      * @throws NamingException if any LDAP errors occur during the search.
 226  
      */
 227  
     protected abstract AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException;
 228  
 
 229  
 
 230  
     /**
 231  
      * <p>Abstract method that should be implemented by subclasses to builds an
 232  
      * {@link AuthorizationInfo} object by querying the LDAP context for the
 233  
      * specified principal.</p>
 234  
      *
 235  
      * @param principal          the principal of the Subject whose AuthenticationInfo should be queried from the LDAP server.
 236  
      * @param ldapContextFactory factory used to retrieve LDAP connections.
 237  
      * @return an {@link AuthorizationInfo} instance containing information retrieved from the LDAP server.
 238  
      * @throws NamingException if any LDAP errors occur during the search.
 239  
      */
 240  
     protected abstract AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principal, LdapContextFactory ldapContextFactory) throws NamingException;
 241  
 
 242  
 }