<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 26/06/2021 3:41 pm, Peter Firmstone
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:e0436c20-41b6-811a-8026-59da7c5e3a7e@zeus.net.au">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <p>Apologies for multiple earlier emails, please ignore and read
        this instead.</p>
      <p>This proposal is about stripping out and simplifying as much of
        the dilapidated and complex SecurityManager infrastructure as
        possible, while retaining the ability for developers to
        implement a better high scaling and performant Authorization
        layer, without prohibitively preventing it.<br>
      </p>
      <p>Summary of Proposed Changes:</p>
      <ol>
        <li>GuardFactory & GuardFactorySpi to provide hooks for
          authorization checks without SecurityManager or Policy. (Note
          GuardFactory should never return null and instead return a
          no-op Guard that hotspot can optimize out.<br>
        </li>
        <li>Existing Permission implementations to be obtained using
          GuardFactorySpi implementations, until their removal.  Note
          that when SecurityManager is stubbed out and Permission
          implementations are deprecated for removal, these should no
          longer be provided by default, but instead need to be enabled
          by entries in the java.security config file, in preparation
          for their removal.<br>
        </li>
        <li>JDK code to no longer call Permission implementations
          directly, instances obtained using GuardFactory, when enabled
          in the java.security configuration file.<br>
        </li>
        <li>Threads (system and virtual) updated to use a singleton
          *unprivileged* AccessControlContext, instead of inherited
          AccessControlContext, this is more appropriate for Executors,
          the original inherited context was designed before Executors
          were introduced.</li>
        <li>Deprecation for removal of all Permission implementations
          from the JDK platform.   The existing implementations of
          Permission introduce unnecessary complexity; they lack
          sufficient flexibility resulting in a proliferation of
          Permission grants required in policy files and some make
          blocking network calls.<br>
        </li>
        <li>Introduce a system property to change AccessController's
          default behaviour, disable the stack walk by default, but
          allow it to be re-enabled with a system property, replace the
          stack walk array result of ProtectionDomains with an
          *unprivileged* AccessControlContext, the SubjectDomainCombiner
          can replace it with a, AccessControlContext containing a
          single element array, containing one ProtectionDomain with
          Principals.  <br>
        </li>
        <li>AccessController::doPrivileged erases the DomainCombiner by
          default, deprecate these methods for removal (make private),
          retain doPrivilegedWithCombiner methods that preserve the
          SubjectDomainCombiner.   Developers should replace their
          doPrivileged methods with doPrivilegedWithCombiner.   Create a
          new method AccessController::doUnprivileged, clear intent, to
          erase the DomainCombiner, and use the *unprivileged*
          AccessControlContext.  Update
          AccessController.AccHolder.innocuousAcc to refer to an
          *unprivileged* context, as per the definition below.<br>
        </li>
        <li>Deprecate for removal the CodeSource::implies method.</li>
        <li>Give unique ProtectionDomain's with a meaninful CodeSource
          to Java modules mapped to the boot loader, rather than using a
          Shared ProtectionDomain with a null CodeSource.</li>
        <li>Deprecate for removal AccessController::checkPermission and
          AccessControlContext::checkPermission methods.</li>
      </ol>
    </blockquote>
    <p>AccessController.checkPermission calls
      AccessControlContext.optimize, which invokes the DomainCombiner,
      prior to calling AccessControlContext.checkPermission  <br>
    </p>
    <p>In my implementation of SecurityManager, I call
      AccessController.getContext from within a PrivilegedAction, to
      optimise a newly created AccessControlContext, 
      (AccessController.getContext also calls
      AcessControlConext.optimize), prior to calling
      AccessControlContext.checkPermission.<br>
    </p>
    <p>I think it would be simpler however, to create a new method in
      AccessController to replace checkPermission which also calls
      optimize.</p>
    I think something could be done here with Stream and Consumer to
    perform the function checking ProtectionDomain's.  Needs a little
    more thought, but basically we want to be able to check each
    ProtectionDomain, without being restricted to Permission or Policy
    implementations.<br>
    <p>Eg:</p>
    <p>AccessController.stream(AccessControlContext
      context).forEach(domain -> Check::domain)</p>
    <p>Or <br>
    </p>
    <p>AccessController.checkDomains(AccessControlContext context,
      Consumer<ProtectionDomain>)</p>
    <p>This method would have a relevant Guard.check "RUNTIME"
      "getProtectionDomain" prior to calling
      AccessControlContext.optimize and the developer would need to make
      the call from a PrivilegedAction, and remember pass the relevant
      guard check for it's own AccessControlContext.<br>
    </p>
    <blockquote type="cite"
      cite="mid:e0436c20-41b6-811a-8026-59da7c5e3a7e@zeus.net.au">
      <ol start="11">
        <li>Undeprecate AccessController, AccessControlContext,
          DomainCombiner, SubjectDomainCombiner and Subject::doAs
          methods, while deprecating for removal methods stated in items
          above.</li>
        <li>Deprecate for removal ProtectionDomain::implies,
          ProtectionDomain::getPermissions and
          ProtectionDomain::staticPermissionsOnly</li>
        <li>Replace PermissionCollection type argument with Object in
          ProtectionDomain constructors, ignore the permissions
          parameter, and deprecate existing constructors.   Deprecate
          PermissionCollection for removal.<br>
        </li>
        <li>Create a new constructor: ProtectionDomain(CodeSource cs,
          ClassLoader cl, Principal[] p).</li>
        <li>Create a new factory method 
          ProtectionDomain::newInstance(Principal[] p), to allow a weak
          cache of ProtectionDomain instances for each Principal[], to
          be utilised by SubjectDomainCombiner to avoid unnecessary
          duplication of objects.   This is an optimization for
          AccessControlContext::equals and ::hashCode methods.   Using a
          cache of AccessControlContext, it is possible to avoid
          rechecking authorization that has already been checked.  For
          example, when using an Executor with many tasks, all with the
          same AccessControlContext, you only need to check once and
          return the same result for subsequent checks.   This is an
          optimization I have used previously to great effect.<br>
        </li>
      </ol>
    </blockquote>
    <p>The ProtectionDomain::newInstance is just a nice to have,
      SubjectDomainCombiner already caches PD's, just seems a better
      place to cache for the following reasons:</p>
    <ul>
      <li>Cache can be utilised by other implementations.</li>
      <li>Simplification of SubjectDomainCombiner.</li>
      <li>Responsibility of ProtectionDomain.</li>
    </ul>
    <p>It's not an essential item, however, just seems like an
      opportunity for a little refactoring.<br>
    </p>
    <blockquote type="cite"
      cite="mid:e0436c20-41b6-811a-8026-59da7c5e3a7e@zeus.net.au">
      <ol start="11">
      </ol>
      <p>To clarify what an *unprivileged* AccessControlContext is:</p>
      <blockquote>
        <p>An instance of AccessControlContext, that contains a single
          element array, containing a ProtectionDomain, with a null
          ClassLoader, null Principal[] and a *non-null* CodeSource,
          containing a null URL.<br>
        </p>
        <p>So as to distinguish between what is traditionally a JDK
          bootstrap ProtectionDomain and unprivileged domain after
          ProtectionDomain::getPermissions is removed.<br>
        </p>
      </blockquote>
      <blockquote> </blockquote>
      <p>Stubbing of SecurityManager and Policy, for runtime backward
        compatibility. Update ProtectionDomain::implies method, to *not*
        consult with the Policy.  Note it's possible to get access to
        the ProtectionDomain array contained within AccessControlContext
        using a DomainCombiner.<br>
      </p>
      <p>This is backward compatible with existing usages of JAAS and
        least painful method of transition for all concerned as well as
        allowing complete flexibility of implementation.</p>
      <p>Regards,</p>
      <p>Peter Firmstone.<br>
      </p>
      <div class="moz-cite-prefix">On 25/06/2021 3:59 pm, Peter
        Firmstone wrote:<br>
      </div>
      <blockquote type="cite"
        cite="mid:2f315680-1cdb-1694-34a3-95312bf42ca7@zeus.net.au">Thanks
        Dalibor, <br>
        <br>
        Would targeting Java 18 be practical? <br>
        <br>
        Also it won't take long to code a prototype, just not sure of
        the process. <br>
        <br>
        Cheers, <br>
        <br>
        Peter. <br>
        <br>
        <br>
        On 24/06/2021 9:30 pm, Dalibor Topic wrote: <br>
        <blockquote type="cite">On 24.06.2021 04:24, Peter Firmstone
          wrote: <br>
          <blockquote type="cite">Thanks Andrew, <br>
            <br>
            For the simple case, of replacing the SecurityManager stack
            walk, one could use reflection. <br>
            <br>
            Thank you for also confirming that is not possible (or at
            least very unlikely) to add a GuardBuilder to Java 8, the
            proposal is for JDK code to use a provider mechanism, to
            intercept permission checks, so custom authentication layers
            can be implemented, this could be accepted in future
            versions of Java, but not existing. As it is said, there is
            no harm in asking. <br>
          </blockquote>
          <br>
          Generally speaking, adding any public APIs to a platform
          release after its specification has been published, is always
          going to be a very tall order involving the JCP, among other
          things. It's not really worth it, when other technical
          solutions, such as multi-release JARs, already exist, that
          alleviate the necessity. <br>
          <br>
          cheers, <br>
          dalibor topic <br>
          <br>
        </blockquote>
      </blockquote>
    </blockquote>
    <pre class="moz-signature" cols="72">-- 
Regards,
 
Peter Firmstone
</pre>
  </body>
</html>