READ 1ST: Re: Authorization layer API and low level access checks

Peter Firmstone peter.firmstone at zeus.net.au
Sat Jun 26 05:41:59 UTC 2021


Apologies for multiple earlier emails, please ignore and read this instead.

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.

Summary of Proposed Changes:

 1. 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.
 2. 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.
 3. JDK code to no longer call Permission implementations directly,
    instances obtained using GuardFactory, when enabled in the
    java.security configuration file.
 4. 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.
 5. 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.
 6. 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.
 7. 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.
 8. Deprecate for removal the CodeSource::implies method.
 9. 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.
10. Deprecate for removal AccessController::checkPermission and
    AccessControlContext::checkPermission methods.
11. Undeprecate AccessController, AccessControlContext, DomainCombiner,
    SubjectDomainCombiner and Subject::doAs methods, while deprecating
    for removal methods stated in items above.
12. Deprecate for removal ProtectionDomain::implies,
    ProtectionDomain::getPermissions and
    ProtectionDomain::staticPermissionsOnly
13. Replace PermissionCollection type argument with Object in
    ProtectionDomain constructors, ignore the permissions parameter, and
    deprecate existing constructors.   Deprecate PermissionCollection
    for removal.
14. Create a new constructor: ProtectionDomain(CodeSource cs,
    ClassLoader cl, Principal[] p).
15. 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.

To clarify what an *unprivileged* AccessControlContext is:

    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.

    So as to distinguish between what is traditionally a JDK bootstrap
    ProtectionDomain and unprivileged domain after
    ProtectionDomain::getPermissions is removed.

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.

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.

Regards,

Peter Firmstone.

On 25/06/2021 3:59 pm, Peter Firmstone wrote:
> Thanks Dalibor,
>
> Would targeting Java 18 be practical?
>
> Also it won't take long to code a prototype, just not sure of the 
> process.
>
> Cheers,
>
> Peter.
>
>
> On 24/06/2021 9:30 pm, Dalibor Topic wrote:
>> On 24.06.2021 04:24, Peter Firmstone wrote:
>>> Thanks Andrew,
>>>
>>> For the simple case, of replacing the SecurityManager stack walk, 
>>> one could use reflection.
>>>
>>> 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.
>>
>> 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.
>>
>> cheers,
>> dalibor topic
>>


More information about the discuss mailing list