<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>