Пример #1
0
  /**
   * Begin user authentication.
   *
   * <p>Acquire the user's credentials and verify them against the specified LDAP directory.
   *
   * @return true always, since this <code>LoginModule</code> should not be ignored.
   * @exception FailedLoginException if the authentication fails.
   * @exception LoginException if this <code>LoginModule</code> is unable to perform the
   *     authentication.
   */
  public boolean login() throws LoginException {

    if (userProvider == null) {
      throw new LoginException("Unable to locate the LDAP directory service");
    }

    if (debug) {
      System.out.println("\t\t[LdapLoginModule] user provider: " + userProvider);
    }

    // attempt the authentication
    if (tryFirstPass) {

      try {
        // attempt the authentication by getting the
        // username and password from shared state
        attemptAuthentication(true);

        // authentication succeeded
        succeeded = true;
        if (debug) {
          System.out.println("\t\t[LdapLoginModule] " + "tryFirstPass succeeded");
        }
        return true;

      } catch (LoginException le) {
        // authentication failed -- try again below by prompting
        cleanState();
        if (debug) {
          System.out.println("\t\t[LdapLoginModule] " + "tryFirstPass failed: " + le.toString());
        }
      }

    } else if (useFirstPass) {

      try {
        // attempt the authentication by getting the
        // username and password from shared state
        attemptAuthentication(true);

        // authentication succeeded
        succeeded = true;
        if (debug) {
          System.out.println("\t\t[LdapLoginModule] " + "useFirstPass succeeded");
        }
        return true;

      } catch (LoginException le) {
        // authentication failed
        cleanState();
        if (debug) {
          System.out.println("\t\t[LdapLoginModule] " + "useFirstPass failed");
        }
        throw le;
      }
    }

    // attempt the authentication by prompting for the username and pwd
    try {
      attemptAuthentication(false);

      // authentication succeeded
      succeeded = true;
      if (debug) {
        System.out.println("\t\t[LdapLoginModule] " + "authentication succeeded");
      }
      return true;

    } catch (LoginException le) {
      cleanState();
      if (debug) {
        System.out.println("\t\t[LdapLoginModule] " + "authentication failed");
      }
      throw le;
    }
  }
Пример #2
0
  private void invoke(String methodName) throws LoginException {

    // start at moduleIndex
    // - this can only be non-zero if methodName is LOGIN_METHOD

    for (int i = moduleIndex; i < moduleStack.length; i++, moduleIndex++) {
      try {

        int mIndex = 0;
        Method[] methods = null;

        if (moduleStack[i].module != null) {
          methods = moduleStack[i].module.getClass().getMethods();
        } else {

          // instantiate the LoginModule
          //
          // Allow any object to be a LoginModule as long as it
          // conforms to the interface.
          Class<?> c =
              Class.forName(moduleStack[i].entry.getLoginModuleName(), true, contextClassLoader);

          Constructor<?> constructor = c.getConstructor(PARAMS);
          Object[] args = {};
          moduleStack[i].module = constructor.newInstance(args);

          // call the LoginModule's initialize method
          methods = moduleStack[i].module.getClass().getMethods();
          for (mIndex = 0; mIndex < methods.length; mIndex++) {
            if (methods[mIndex].getName().equals(INIT_METHOD)) {
              break;
            }
          }

          Object[] initArgs = {subject, callbackHandler, state, moduleStack[i].entry.getOptions()};
          // invoke the LoginModule initialize method
          //
          // Throws ArrayIndexOutOfBoundsException if no such
          // method defined.  May improve to use LoginException in
          // the future.
          methods[mIndex].invoke(moduleStack[i].module, initArgs);
        }

        // find the requested method in the LoginModule
        for (mIndex = 0; mIndex < methods.length; mIndex++) {
          if (methods[mIndex].getName().equals(methodName)) {
            break;
          }
        }

        // set up the arguments to be passed to the LoginModule method
        Object[] args = {};

        // invoke the LoginModule method
        //
        // Throws ArrayIndexOutOfBoundsException if no such
        // method defined.  May improve to use LoginException in
        // the future.
        boolean status =
            ((Boolean) methods[mIndex].invoke(moduleStack[i].module, args)).booleanValue();

        if (status == true) {

          // if SUFFICIENT, return if no prior REQUIRED errors
          if (!methodName.equals(ABORT_METHOD)
              && !methodName.equals(LOGOUT_METHOD)
              && moduleStack[i].entry.getControlFlag()
                  == AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT
              && firstRequiredError == null) {

            // clear state
            clearState();

            if (debug != null) debug.println(methodName + " SUFFICIENT success");
            return;
          }

          if (debug != null) debug.println(methodName + " success");
          success = true;
        } else {
          if (debug != null) debug.println(methodName + " ignored");
        }

      } catch (NoSuchMethodException nsme) {
        MessageFormat form =
            new MessageFormat(
                ResourcesMgr.getString(
                    "unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor"));
        Object[] source = {moduleStack[i].entry.getLoginModuleName()};
        throwException(null, new LoginException(form.format(source)));
      } catch (InstantiationException ie) {
        throwException(
            null,
            new LoginException(
                ResourcesMgr.getString("unable.to.instantiate.LoginModule.") + ie.getMessage()));
      } catch (ClassNotFoundException cnfe) {
        throwException(
            null,
            new LoginException(
                ResourcesMgr.getString("unable.to.find.LoginModule.class.") + cnfe.getMessage()));
      } catch (IllegalAccessException iae) {
        throwException(
            null,
            new LoginException(
                ResourcesMgr.getString("unable.to.access.LoginModule.") + iae.getMessage()));
      } catch (InvocationTargetException ite) {

        // failure cases

        LoginException le;

        if (ite.getCause() instanceof PendingException && methodName.equals(LOGIN_METHOD)) {

          // XXX
          //
          // if a module's LOGIN_METHOD threw a PendingException
          // then immediately throw it.
          //
          // when LoginContext is called again,
          // the module that threw the exception is invoked first
          // (the module list is not invoked from the start).
          // previously thrown exception state is still present.
          //
          // it is assumed that the module which threw
          // the exception can have its
          // LOGIN_METHOD invoked twice in a row
          // without any commit/abort in between.
          //
          // in all cases when LoginContext returns
          // (either via natural return or by throwing an exception)
          // we need to call clearState before returning.
          // the only time that is not true is in this case -
          // do not call throwException here.

          throw (PendingException) ite.getCause();

        } else if (ite.getCause() instanceof LoginException) {

          le = (LoginException) ite.getCause();

        } else if (ite.getCause() instanceof SecurityException) {

          // do not want privacy leak
          // (e.g., sensitive file path in exception msg)

          le = new LoginException("Security Exception");
          le.initCause(new SecurityException());
          if (debug != null) {
            debug.println(
                "original security exception with detail msg "
                    + "replaced by new exception with empty detail msg");
            debug.println("original security exception: " + ite.getCause().toString());
          }
        } else {

          // capture an unexpected LoginModule exception
          java.io.StringWriter sw = new java.io.StringWriter();
          ite.getCause().printStackTrace(new java.io.PrintWriter(sw));
          sw.flush();
          le = new LoginException(sw.toString());
        }

        if (moduleStack[i].entry.getControlFlag()
            == AppConfigurationEntry.LoginModuleControlFlag.REQUISITE) {

          if (debug != null) debug.println(methodName + " REQUISITE failure");

          // if REQUISITE, then immediately throw an exception
          if (methodName.equals(ABORT_METHOD) || methodName.equals(LOGOUT_METHOD)) {
            if (firstRequiredError == null) firstRequiredError = le;
          } else {
            throwException(firstRequiredError, le);
          }

        } else if (moduleStack[i].entry.getControlFlag()
            == AppConfigurationEntry.LoginModuleControlFlag.REQUIRED) {

          if (debug != null) debug.println(methodName + " REQUIRED failure");

          // mark down that a REQUIRED module failed
          if (firstRequiredError == null) firstRequiredError = le;

        } else {

          if (debug != null) debug.println(methodName + " OPTIONAL failure");

          // mark down that an OPTIONAL module failed
          if (firstError == null) firstError = le;
        }
      }
    }

    // we went thru all the LoginModules.
    if (firstRequiredError != null) {
      // a REQUIRED module failed -- return the error
      throwException(firstRequiredError, null);
    } else if (success == false && firstError != null) {
      // no module succeeded -- return the first error
      throwException(firstError, null);
    } else if (success == false) {
      // no module succeeded -- all modules were IGNORED
      throwException(
          new LoginException(ResourcesMgr.getString("Login.Failure.all.modules.ignored")), null);
    } else {
      // success

      clearState();
      return;
    }
  }