Пример #1
0
  private void throwException(LoginException originalError, LoginException le)
      throws LoginException {

    // first clear state
    clearState();

    // throw the exception
    LoginException error = (originalError != null) ? originalError : le;
    throw error;
  }
Пример #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;
    }
  }