Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8275529

Alternate Subject.getSubject and doAs APIs that do not depend on Security Manager APIs

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 18
    • security-libs
    • None
    • source
    • minimal
    • Hide
      We need to preserve compatibility with applications that may still be using the old APIs. Thus, the old APIs are deprecated, but the implementation works the same and has not been changed. In order to preserve compatibility with applications using the old APIs, the implementation of the new APIs by default uses the same mechanisms as the old APIs. However, users can try out a newer mechanism (which uses ThreadLocals) by setting the system property "jdk.security.auth.subject.useTL" to "true". At some point in a future version of the JDK, when the compatibility risk has declined, we will migrate the new APIs to use this implementation by default (or some other implementation that does not use the deprecated Security Manager APIs).
      Show
      We need to preserve compatibility with applications that may still be using the old APIs. Thus, the old APIs are deprecated, but the implementation works the same and has not been changed. In order to preserve compatibility with applications using the old APIs, the implementation of the new APIs by default uses the same mechanisms as the old APIs. However, users can try out a newer mechanism (which uses ThreadLocals) by setting the system property "jdk.security.auth.subject.useTL" to "true". At some point in a future version of the JDK, when the compatibility risk has declined, we will migrate the new APIs to use this implementation by default (or some other implementation that does not use the deprecated Security Manager APIs).
    • Java API, System or security property
    • SE

      Summary

      Create new JAAS APIs to be replacements of deprecated getSubject and doAs.

      Problem

      With JEP 411, we have deprecated most APIs related to the security manager. In JDK 17, we already deprecated Subject::getSubject because its argument is a deprecated class AccessControlContext. In JDK 18, we will deprecate the Subject::doAs methods because they are closely related to getSubject() (one setter one getter) and their specifications heavily depend on deprecated classes AccessController and SubjectDomainCombiner. However, these APIs are useful independent of the Security Manager as they provide a mechanism to transport a Subject's credentials across API boundaries. Thus, we need to create new APIs that do not depend on the Security Manager APIs -- this plan was already documented in JEP 411.

      Solution

      Deprecate Subject::doAs for removal and add new methods Subject::current and Subject::callAs. The new APIs do not have API dependencies on the deprecated Security Manager APIs and are designed to offer the same capabilities as the deprecated APIs.

      Specification

       package javax.security.auth;
      
      
       public final class Subject implements java.io.Serializable {
      
           /**
            * Get the {@code Subject} associated with the provided
            * {@code AccessControlContext}.
            ....
            * @deprecated This method depends on {@link AccessControlContext}
            *       which, in conjunction with
            *       {@linkplain SecurityManager the Security Manager}, is deprecated
      -     *       and subject to removal in a future release. However, obtaining a
      -     *       Subject is useful independent of the Security Manager, so a
      -     *       replacement for this method may be added in a future release.
      +     *       and subject to removal in a future release. However,
      +     *       obtaining a Subject is useful independent of the Security Manager.
      +     *       Thus, a replacement API named {@link #current()} has been added
      +     *       which can be used to obtain the current subject.
      
            */
           @Deprecated(since="17", forRemoval=true)
           public static Subject getSubject(final AccessControlContext acc);
      +
      +    /**
      +     * Returns the current subject.
      +     * <p>
      +     * The current subject is installed by the {@link #callAs} method.
      +     * When {@code callAs(subject, action)} is called, {@code action} is
      +     * executed with {@code subject} as its current subject which can be
      +     * retrieved by this method. After {@code action} is finished, the current
      +     * subject is reset to its previous value. The current
      +     * subject is {@code null} before the first call of {@code callAs()}.
      +     * <p>
      +     * When a new thread is created, its current subject is the same as
      +     * the one of its parent thread, and will not change even if
      +     * its parent thread's current subject is changed to another value.
      +     *
      +     * @implNote
      +     * By default, this method returns the same value as
      +     * {@code Subject.getSubject(AccessController.getContext())}. This
      +     * preserves compatibility with code that may still be calling {@code doAs}
      +     * which installs the subject in an {@code AccessControlContext}. However,
      +     * if the system property {@systemProperty jdk.security.auth.subject.useTL}
      +     * is set to {@code true}, the subject is retrieved from an inheritable
      +     * {@code ThreadLocal} object. This behavior is subject to
      +     * change in a future version.
      +     *
      +     * @return the current subject, or {@code null} if a current subject is
      +     *      not installed or the current subject is set to {@code null}.
      +     * @see #callAs(Subject, Callable)
      +     * @since 18
      +     */
      +    public static Subject current();
      
      +    /**
      +     * Executes a {@code Callable} with {@code subject} as the
      +     * current subject.
      +     *
      +     * @implNote
      +     * By default, this method calls {@link #doAs(Subject, PrivilegedExceptionAction)
      +     * Subject.doAs(subject, altAction)} which stores the subject in
      +     * a new {@code AccessControlContext}, where {@code altAction.run()}
      +     * is equivalent to {@code action.call()} and the exception thrown is
      +     * modified to match the specification of this method. This preserves
      +     * compatibility with code that may still be calling
      +     * {@code getSubject(AccessControlContext)} which retrieves the subject
      +     * from an {@code AccessControlContext}. However,
      +     * if the system property {@code jdk.security.auth.subject.useTL}
      +     * is set to {@code true}, the current subject will be stored in an inheritable
      +     * {@code ThreadLocal} object. This behavior is subject to change in a
      +     * future version.
      +     *
      +     * @param subject the {@code Subject} that the specified {@code action}
      +     *               will run as.  This parameter may be {@code null}.
      +     * @param action the code to be run with {@code subject} as its current
      +     *               subject. Must not be {@code null}.
      +     * @param <T> the type of value returned by the {@code call} method
      +     *            of {@code action}
      +     * @return the value returned by the {@code call} method of {@code action}
      +     * @throws NullPointerException if {@code action} is {@code null}
      +     * @throws CompletionException if {@code action.call()} throws an exception.
      +     *      The cause of the {@code CompletionException} is set to the exception
      +     *      thrown by {@code action.call()}.
      +     * @see #current()
      +     * @since 18
      +     */
      +    public static <T> T callAs(final Subject subject,
      +            final Callable<T> action) throws CompletionException;
      
           /**
            * Perform work as a particular {@code Subject}.
            ....
      +     *
      +     * @deprecated This method depends on {@link AccessControlContext}
      +     *       which, in conjunction with
      +     *       {@linkplain SecurityManager the Security Manager}, is deprecated
      +     *       and subject to removal in a future release. However, performing
      +     *       work as a Subject is useful independent of the Security Manager.
      +     *       Thus, a replacement API named {@link #callAs} has been added
      +     *       which can be used to perform the same work.
            */
           @SuppressWarnings("removal")
      +    @Deprecated(since="18", forRemoval=true)
           public static <T> T doAs(final Subject subject,
                               final java.security.PrivilegedAction<T> action);
      
      
           /**
            * Perform work as a particular {@code Subject}.
            ....
      +     *
      +     * @deprecated This method depends on {@link AccessControlContext}
      +     *       which, in conjunction with
      +     *       {@linkplain SecurityManager the Security Manager}, is deprecated
      +     *       and subject to removal in a future release. However, performing
      +     *       work as a Subject is useful independent of the Security Manager.
      +     *       Thus, a replacement API named {@link #callAs} has been added
      +     *       which can be used to perform the same work.
            */
           @SuppressWarnings("removal")
      +    @Deprecated(since="18", forRemoval=true)
           public static <T> T doAs(final Subject subject,
                               final java.security.PrivilegedExceptionAction<T> action)
                               throws java.security.PrivilegedActionException;
       }

            weijun Weijun Wang
            weijun Weijun Wang
            Sean Mullan
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: