Skip to main content
added 15 characters in body
Source Link
Uux
  • 1.2k
  • 1
  • 10
  • 22

Subject#doAsPrivileged, when given a null AccessControlContext, on the other hand, does the trick, because it "trims" the effective context's stack to its top-most frame, i.e., the one from which doAsPrivileged gets invoked. What actually happens is that the null (blank) context gets treated by the AccessController as if it were a context whose permission evaluation yields AllPermissionsAllPermission; in other words:

AllPermissionsAllPermissionpermissionsframe2 = { CustomPermission("someMethod"), default ones } ,

which is (save for the minimal set of seemingly extraneous statically-assigned Permnissions) the desired outcome.

Why is the Principal implementation mustforced to override equals(Object) and hashCode?

Subject#doAsPrivileged, when given a null AccessControlContext, on the other hand, does the trick, because it "trims" the effective context's stack to its top-most frame, i.e., the one from which doAsPrivileged gets invoked. What actually happens is that the null (blank) context gets treated by the AccessController as if it were a context whose permission evaluation yields AllPermissions; in other words:

AllPermissionspermissionsframe2 = { CustomPermission("someMethod"), default ones } ,

which is (save for the minimal set of seemingly extraneous statically-assigned Permnissions) the desired outcome

Why the Principal implementation must override equals(Object)

Subject#doAsPrivileged, when given a null AccessControlContext, on the other hand, does the trick, because it "trims" the effective context's stack to its top-most frame, i.e., the one from which doAsPrivileged gets invoked. What actually happens is that the null (blank) context gets treated by the AccessController as if it were a context whose permission evaluation yields AllPermission; in other words:

AllPermissionpermissionsframe2 = { CustomPermission("someMethod"), default ones } ,

which is (save for the minimal set of seemingly extraneous statically-assigned Permnissions) the desired outcome.

Why is the Principal implementation forced to override equals and hashCode?

Source Link
Uux
  • 1.2k
  • 1
  • 10
  • 22

Subject#doAs vs Subject#doAsPrivileged

The default authorization algorithm employed by the AccessController is based on Permission intersection: If all of an AccessControlContext's ProtectionDomains, potentially combined with a Subject's Principals, have, statically and/or as per the Policy in effect, the Permission being checked, the evaluation succeeds; otherwise it fails.

Subject#doAs does not work in your case because your Permission is granted to the combination of your ProtectionDomain and your Principal, but not to the domain itself. Specifically, at the time of the AccessController#checkPermission(customPermission) invocation, the effective AccessControlContext included following relevant (as far as Permission evaluation is concerned) frames:

Frame # | ProtectionDomain          | Permissions
--------+---------------------------+---------------------------------------------
 2      | "file:./bin/"             | { CustomPermission("someMethod"),
        | + CustomPrincipal("user") |   permissions statically assigned by default
        |                           |   by the ClassLoader }
--------+---------------------------+---------------------------------------------
 1      | "file:./bin/"             | { AuthPermission(
        |                           |   "createLoginContext.MyLoginModule"),
        |                           |   AuthPermission("doAs"), default as above }
--------+---------------------------+---------------------------------------------

The intersection of those frames' permissions does of course not include the desired CustomPermission.

Subject#doAsPrivileged, when given a null AccessControlContext, on the other hand, does the trick, because it "trims" the effective context's stack to its top-most frame, i.e., the one from which doAsPrivileged gets invoked. What actually happens is that the null (blank) context gets treated by the AccessController as if it were a context whose permission evaluation yields AllPermissions; in other words:

AllPermissionspermissionsframe2 = { CustomPermission("someMethod"), default ones } ,

which is (save for the minimal set of seemingly extraneous statically-assigned Permnissions) the desired outcome

Of course, in cases where such potentially arbitrary privilege escalation is undesired, a custom context, whose encapsulated domains' permissions express the maximum set of privileges you are willing to grant (to e.g. some Subject), can be passed to doAsPrivileged instead of the null one.

Why the Principal implementation must override equals(Object)

The following stack trace snippet illustrates why:

at java.lang.Thread.dumpStack(Thread.java:1329)
at com.foo.bar.PrincipalImpl.equals(PrincipalImpl.java:53)
at javax.security.auth.Subject$SecureSet.contains(Subject.java:1201)
at java.util.Collections$SynchronizedCollection.contains(Collections.java:2021)
at java.security.Principal.implies(Principal.java:92)
at sun.security.provider.PolicyFile.addPermissions(PolicyFile.java:1374)
at sun.security.provider.PolicyFile.getPermissions(PolicyFile.java:1228)
at sun.security.provider.PolicyFile.getPermissions(PolicyFile.java:1191)
at sun.security.provider.PolicyFile.getPermissions(PolicyFile.java:1132)
at sun.security.provider.PolicyFile.implies(PolicyFile.java:1086)
at java.security.ProtectionDomain.implies(ProtectionDomain.java:281)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:450)
at java.security.AccessController.checkPermission(AccessController.java:884)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
...

Further reading: