Topics

Discussion: SecurityContext - downcasting getCallerPrincipal()


Will Hopkins
 

Hi Arjan,

I removed that to trigger this discussion. I also added some new language about principals requirements in chapter 2, which is now called, "Concepts and General Requirements".

This is another case where I wasn't part of the original discussions, so I'm not completely clear on the what the specific requirement was for this, or what was motivating it.

It's possible I'm wrong -- I'm pretty familiar with WebLogic, but not so much other app servers -- but I would expect most implementations of HttpServletRequest.getUserPrincipal(), and similar calls in other containers, to return the user principal that's in the Subject for the currently authenticated user (i.e., the "caller principal"). If so, then this requirement isn't really about the behavior of SecurityContext.getCallerPrincipal(), it's really about what Principal is used to populate the Subject at authentication time.

If the problem really is that app servers are doing something like, "return new XyzPrincipal(request.getRemoteUser())", then, yes, I agree that the method should return the actual caller principal from the actual authenticated Subject instead. It might be good to understand how much of a burden that would impose on existing implementations, in terms of code or backward compatibility, but it seems like a reasonable requirement.

If, on the other hand, this is really a back-door way of specifying what principals the container must put in the Subject, then we need to think that through. JASPIC actually allows containers some flexibility on this. A ServerAuthModule is supposed to use the CallerPrincipalCallback to set "the containers representation of" the caller principal, and explicitly says the container's callback handler "may perform principal mapping of non-null argument Principal values".

The ability to map to the container's representation of the caller principal is critical for a container like WebLogic, where the authorization subsystem relies on users being represented by instances of WLSUser and groups being represented by instances of WLSGroup. In my understanding, this has rarely been a problem for customers, except in cases where they want to use JACC, in which case the principal types specified in the corresponding policy file may be an issue. (As a side note, I'm baffled by what the JASPIC spec means by a "JSR 115 compatible runtime".) It's necessary for WebLogic to support configurations such that JASPIC and JACC work together, but the vast majority of our customers do not use JACC, and therefore rely on the principal mapping our default callback handler does.

Interestingly, the GroupPrincipalCallback does not have a constructor that takes principal objects -- it takes only an array of names, essentially forcing the container's own representation of groups.

It doesn't appear that our HAM interface provides access to the CallerPrincipalCallback (or GroupPrincipalCallback).

So, assuming I've characterized the issue correctly, I'd like to propose an alternative, that allows containers to rely on proprietary representations of caller principal while still supporting use cases (like JACC) where principal type matters. As described in chapter 2 of the PRD, if containers use CallerPrincipal as a base class for container-specific caller principals, then we have the best of both worlds -- a standard base principal type, CallerPrincipal, that can safely be used in JACC policy files, and for other purposes, while still allowing the container to map to the "local" representation of a caller principal when necessary.

Thoughts? Have I correctly characterized the problem? Does my proposal meet the requirements, or am I missing something?

Will

On 05/23/2017 07:49 PM, Arjan Tijms wrote:
Hi,

I noticed that in the spec text a few essentials were removed in the security context.

For instance the part here: 

https://github.com/javaee-security-spec/security-spec/commit/db51cc841e5cb3d8feedbf52e15f31a8f2420105#diff-0164c7c2792d791d98efabe67dc90021L169

Before it said:
The _getCallerPrincipal()_ method is provided to retrieve the _Principal_ that represents the caller's name. It MUST be possible for the application to downcast this _Principal_ to the exact _Principal_ type that was set by the _HttpAuthenticationMechanism_ (possibly via an _IdentityStore_) or a JASPIC _ServerAuthModule_.
But it now it just says:
The _getCallerPrincipal()_ method retrieves the _Principal_ representing the caller.
Why was the downcast part removed?

This is really important and quite an amount of people (Java EE experts even like Mark Struberg and Romain) asked for this on Twitter and elsewhere. This aspect also comes at no cost for us since JASPIC already requires it.

It would be great if this could be put back.

Thanks!

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Arjan Tijms
 

Hi Will,

On Thu, May 25, 2017 at 11:50 PM, Will Hopkins <will.hopkins@...> wrote:

It's possible I'm wrong -- I'm pretty familiar with WebLogic, but not so much other app servers -- but I would expect most implementations of HttpServletRequest.getUserPrincipal(), and similar calls in other containers, to return the user principal that's in the Subject for the currently authenticated user (i.e., the "caller principal"). If so, then this requirement isn't really about the behavior of SecurityContext.getCallerPrincipal(), it's really about what Principal is used to populate the Subject at authentication time.

This is indeed not entirely correct. The free mapping is for the internal representation of the caller principal. GlassFish for instance maps and wraps the Principal a couple of times. This is by itself problematic for other reasons, but not the concern of this requirement here.

The requirement here is about the return value of SecurityContext.getCallerPrincipal(), which must return exactly that what was set by the HAM. If the container internally wraps the Principal, it's supposed to unwrap it right before returning it here.

Nearly all containers do this correctly when JASPIC is used, despite them internally wrapping the custom Principal.

 
If, on the other hand, this is really a back-door way of specifying what principals the container must put in the Subject, then we need to think that through.

No, the SecurityContext.getCallerPrincipal() requirement is very explicitly *not* such a back-door and is not about what the container must put in the Subject. 

We have to address the Subject at some point in a next spec revision as this is one of those things that makes it really hard to work with JACC in a portable way, but this is absolutely not what the requirement for SecurityContext.getCallerPrincipal() is about. If you want, please feel free to clarify that the SecurityContext.getCallerPrincipal() contract does not put any constraint on what the server internally puts in the Subject.

To give an overview of a typical "flow":

1. HAM sets "CustomFooPrincipal" 
2. BridgeSAM puts "CustomFooPrincipal" in CallerPrincipalCallback 
3. Handler implementation and/or runtime take "CustomFooPrincipal" from CallerPrincipalCallback and put *some representation* of "CustomFooPrincipal" in Subject
4. Subject exists in some server specific way in some kind of server specific context 
5. SecurityContextImpl gets Subject in some server specific way
6. SecurityContextImpl extracts the server specific representation of the caller principal for the Subject 
7. SecurityContextImpl transforms in some the server specific representation of the caller principal  to "CustomFooPrincipal"
8. SecurityContextImpl.getCallerPrincipal() returns  "CustomFooPrincipal"

This version of the spec says nothing about 3. to 7.

 
JASPIC actually allows containers some flexibility on this. A ServerAuthModule is supposed to use the CallerPrincipalCallback to set "the containers representation of" the caller principal, and explicitly says the container's callback handler "may perform principal mapping of non-null argument Principal values".

The ability to map to the container's representation of the caller principal is critical for a container like WebLogic, where the authorization subsystem relies on users being represented by instances of WLSUser and groups being represented by instances of WLSGroup. In my understanding, this has rarely been a problem for customers

Well, the fact that HttpServletRequest.getUserPrincipal returns the principal type they set in their custom login module or authentication mechanism has been a big concern with users over the years. I've encountered this many times and there are many forum threads and questions about this.

Just the example I mentioned earlier of a Java EE expert saying this is important:


Just a few example of users actually struggling with this:


For JASPIC I have a test that checks for this here:


 
, except in cases where they want to use JACC, in which case the principal types specified in the corresponding policy file may be an issue. (As a side note, I'm baffled by what the JASPIC spec means by a "JSR 115 compatible runtime".) It's necessary for WebLogic to support configurations such that JASPIC and JACC work together, but the vast majority of our customers do not use JACC, and therefore rely on the principal mapping our default callback handler does.

If users use JACC and work with the Subject they indeed have a somewhat related issue. We had earlier discussed a couple of ways to make this easier, like a kind of "reverse callback" where you can extract the caller principal and groups from the Subject again. I.e. Principal getCallerPrincipalFromSubject(subject);

This was also discussed in the context of the standardised group to role mapper, but we unfortunately never came to specifying that one for this spec release.

Another option was to do a "reverse wrapping" by having a getContainerPrincipal() method in CallerPrincipal, so that one can always easily find the CallerPrincipal in the Subject, but containers can always have their own version directly tied to that as well.
 

Interestingly, the GroupPrincipalCallback does not have a constructor that takes principal objects -- it takes only an array of names, essentially forcing the container's own representation of groups.

Indeed, this is maybe because there are no APIs in Java EE that actually return group principals or allow group principals for input. I.e. the existing HttpServletRequest.isUserInRole takes a string,

 

It doesn't appear that our HAM interface provides access to the CallerPrincipalCallback (or GroupPrincipalCallback).

So, assuming I've characterized the issue correctly, I'd like to propose an alternative, that allows containers to rely on proprietary representations of caller principal while still supporting use cases (like JACC) where principal type matters. As described in chapter 2 of the PRD, if containers use CallerPrincipal as a base class for container-specific caller principals, then we have the best of both worlds -- a standard base principal type, CallerPrincipal, that can safely be used in JACC policy files, and for other purposes, while still allowing the container to map to the "local" representation of a caller principal when necessary.

Thoughts? Have I correctly characterized the problem? Does my proposal meet the requirements, or am I missing something?

I think the problem is correctly characterized indeed, but for this version of the spec JACC and the Subject can be left as they are ;) The only requirement at this point as explained above is that SecurityContextImpl.getCallerPrincipal() returns the correct type. How a container accomplishes that is its own internal concern.

Hope this clarifies the intention and requirement sufficiently.

Kind regards,
Arjan Tijms


 

Will

On 05/23/2017 07:49 PM, Arjan Tijms wrote:
Hi,

I noticed that in the spec text a few essentials were removed in the security context.

For instance the part here: 

https://github.com/javaee-security-spec/security-spec/commit/db51cc841e5cb3d8feedbf52e15f31a8f2420105#diff-0164c7c2792d791d98efabe67dc90021L169

Before it said:
The _getCallerPrincipal()_ method is provided to retrieve the _Principal_ that represents the caller's name. It MUST be possible for the application to downcast this _Principal_ to the exact _Principal_ type that was set by the _HttpAuthenticationMechanism_ (possibly via an _IdentityStore_) or a JASPIC _ServerAuthModule_.
But it now it just says:
The _getCallerPrincipal()_ method retrieves the _Principal_ representing the caller.
Why was the downcast part removed?

This is really important and quite an amount of people (Java EE experts even like Mark Struberg and Romain) asked for this on Twitter and elsewhere. This aspect also comes at no cost for us since JASPIC already requires it.

It would be great if this could be put back.

Thanks!

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803



Will Hopkins
 

Arjan,

On 05/25/2017 06:57 PM, Arjan Tijms wrote:
Hi Will,

On Thu, May 25, 2017 at 11:50 PM, Will Hopkins <will.hopkins@...> wrote:

It's possible I'm wrong -- I'm pretty familiar with WebLogic, but not so much other app servers -- but I would expect most implementations of HttpServletRequest.getUserPrincipal(), and similar calls in other containers, to return the user principal that's in the Subject for the currently authenticated user (i.e., the "caller principal"). If so, then this requirement isn't really about the behavior of SecurityContext.getCallerPrincipal(), it's really about what Principal is used to populate the Subject at authentication time.

This is indeed not entirely correct. The free mapping is for the internal representation of the caller principal. GlassFish for instance maps and wraps the Principal a couple of times. This is by itself problematic for other reasons, but not the concern of this requirement here.

The requirement here is about the return value of SecurityContext.getCallerPrincipal(), which must return exactly that what was set by the HAM. If the container internally wraps the Principal, it's supposed to unwrap it right before returning it here.
In WebLogic's case, it doesn't wrap the principal, so it's not possible to get back any "original" principal by unwrapping it. Implementing a wrapping scheme would be difficult, perhaps impossible, due to the way WebLogic principals are signed (to prevent spoofing) and must be Serializable (so that they can be sent across the wire in RMI calls).

WebLogic's proprietary SPI contract for "Authentication Providers" (which wraps/extends LoginModule) allows providers to populate a Subject with any Principal types it wants, with two caveats:
  • It must provide a PrincipalValidator implementation that can "sign()" and "validate()" any non-WebLogic principal types.
  • It must include an instance of WLSUserImpl to represent the user, and use WLSGroupImpl principals to represent groups. This may not be an absolute requirement (I'd have to check), but the behavior of methods like getUserPrincipal() will be unpredicable otherwise (it would probably just return the first principal it found if it couldn't find a WLSUser), and WLS authorization mechanisms would be useless, since authorization policy can only reference WLSUser and WLSGroup principals.
Nearly all containers do this correctly when JASPIC is used, despite them internally wrapping the custom Principal.

If, on the other hand, this is really a back-door way of specifying what principals the container must put in the Subject, then we need to think that through.

No, the SecurityContext.getCallerPrincipal() requirement is very explicitly *not* such a back-door and is not about what the container must put in the Subject.

It seems like it is. If it were just a requirement to return the principal that's currently in the subject, there would be no issue. This requirement is tying what's in the subject to what the HAM (or any other auth mechanism) put there, so it's effectively a constraint on what the container can do with the principals that any authentication mechanism, not just HAM, puts in a subject.

We have to address the Subject at some point in a next spec revision as this is one of those things that makes it really hard to work with JACC in a portable way, but this is absolutely not what the requirement for SecurityContext.getCallerPrincipal() is about. If you want, please feel free to clarify that the SecurityContext.getCallerPrincipal() contract does not put any constraint on what the server internally puts in the Subject.

If it must be able to return what a HAM put in the Subject, then there is a constraint -- i.e., you must be able to get back the original principal if you substitute a different one for the caller. JASPIC is less restrictive, as I read it; it allows you to "map" the caller principal, and has no other explicit constraint, except that it must be possible to "configure" the handler to return the original principal. (That's possible in WebLogic, but doing so would break a lot of things, for the reasons listed above.)


To give an overview of a typical "flow":

1. HAM sets "CustomFooPrincipal" 
2. BridgeSAM puts "CustomFooPrincipal" in CallerPrincipalCallback 
3. Handler implementation and/or runtime take "CustomFooPrincipal" from CallerPrincipalCallback and put *some representation* of "CustomFooPrincipal" in Subject
4. Subject exists in some server specific way in some kind of server specific context 
5. SecurityContextImpl gets Subject in some server specific way
6. SecurityContextImpl extracts the server specific representation of the caller principal for the Subject 
7. SecurityContextImpl transforms in some the server specific representation of the caller principal  to "CustomFooPrincipal"
8. SecurityContextImpl.getCallerPrincipal() returns  "CustomFooPrincipal"

This version of the spec says nothing about 3. to 7.

But it says that 3. through 7. must be possible, which implies a constraint.
 
JASPIC actually allows containers some flexibility on this. A ServerAuthModule is supposed to use the CallerPrincipalCallback to set "the containers representation of" the caller principal, and explicitly says the container's callback handler "may perform principal mapping of non-null argument Principal values".

The ability to map to the container's representation of the caller principal is critical for a container like WebLogic, where the authorization subsystem relies on users being represented by instances of WLSUser and groups being represented by instances of WLSGroup. In my understanding, this has rarely been a problem for customers

Well, the fact that HttpServletRequest.getUserPrincipal returns the principal type they set in their custom login module or authentication mechanism has been a big concern with users over the years. I've encountered this many times and there are many forum threads and questions about this.

I agree that it's important to have a standard way to deal with principals that's functional both for developers and apps server vendors, and I've also seen anecdotal reports of issues people have had. But the vast majority of WebLogic customers, at least, can achieve what they need to achieve using proprietary principals. This includes a lot of layered middleware, applications, and security layers.

In my experience, there are generally a couple reasons why someone would want to use a custom principal. One is for portability across platforms, and that's a legitimate requirement. The other is to represent some specific aspect or attribute of a user other than the caller identity or groups. I've seen principals used to represent roles, or carry other attributes of a user (e.g., "employee id"). Or someone might want to use, e.g., a KerberosPrincipal to represent the kerberos principal name of a user, as distinct from the "caller identity". Sometimes people want to keep a credential in a principal, but that should really be kept as an actual Credential object in the Subject.

What I'm getting at is that I've never seen a case where, portability aside, it really mattered what principal type was used to represent caller and groups. There's no functional difference between MyUserPrincipal, CallerPrincipal, and WLSUser -- they all just contain the name of the currently authenticated user -- and no reason to prefer one over the other, except, again, for portability, or to integrate with a specific platform. The real issue is the impedance mismatch between what app developers (or custom auth mechanism developers) expect, and what the app server expects.

So perhaps we can standardize the representation of callers and groups, so that everyone has the same expectation, instead of expecting platforms to have to adapt to whatever principal a developer decides to throw in a Subject ...

One way to do that is through abstraction -- similar to the way CallerPrincipalCallback and GroupPrincipalCallback work, an authentication mechanism would tell the container what names to use, but let the container select the principal type to represent them. This would also have to work both ways -- an app (or auth mech) would need to be able to find out what the platform's principal types were.

Or, a simpler, easier approach -- standardize the actual types, at least in terms of an interface or base type. For example, if we standardized on CallerPrincipal (and we might want to make it an interface, not a concrete type), then everybody would know what type represented a user. If a container needed a special implementation (like WebLogic, to handle signing and serialization) it could substitute its own impl, but preserve the interface. Application code would then get back a type that it understood.

Either approach would make it hard for applications to add their own specific behavior to caller/group principals, but how often is that necessary? If there's really a use case for that, there might still be ways to address that, but is that a real concern? Could auxiliary principal types be used where custom behavior is needed? (I.e., types other than user/group)?

Will
 
, except in cases where they want to use JACC, in which case the principal types specified in the corresponding policy file may be an issue. (As a side note, I'm baffled by what the JASPIC spec means by a "JSR 115 compatible runtime".) It's necessary for WebLogic to support configurations such that JASPIC and JACC work together, but the vast majority of our customers do not use JACC, and therefore rely on the principal mapping our default callback handler does.

If users use JACC and work with the Subject they indeed have a somewhat related issue. We had earlier discussed a couple of ways to make this easier, like a kind of "reverse callback" where you can extract the caller principal and groups from the Subject again. I.e. Principal getCallerPrincipalFromSubject(subject);

This was also discussed in the context of the standardised group to role mapper, but we unfortunately never came to specifying that one for this spec release.

Another option was to do a "reverse wrapping" by having a getContainerPrincipal() method in CallerPrincipal, so that one can always easily find the CallerPrincipal in the Subject, but containers can always have their own version directly tied to that as well.
 

Interestingly, the GroupPrincipalCallback does not have a constructor that takes principal objects -- it takes only an array of names, essentially forcing the container's own representation of groups.

Indeed, this is maybe because there are no APIs in Java EE that actually return group principals or allow group principals for input. I.e. the existing HttpServletRequest.isUserInRole takes a string,

 

It doesn't appear that our HAM interface provides access to the CallerPrincipalCallback (or GroupPrincipalCallback).

So, assuming I've characterized the issue correctly, I'd like to propose an alternative, that allows containers to rely on proprietary representations of caller principal while still supporting use cases (like JACC) where principal type matters. As described in chapter 2 of the PRD, if containers use CallerPrincipal as a base class for container-specific caller principals, then we have the best of both worlds -- a standard base principal type, CallerPrincipal, that can safely be used in JACC policy files, and for other purposes, while still allowing the container to map to the "local" representation of a caller principal when necessary.

Thoughts? Have I correctly characterized the problem? Does my proposal meet the requirements, or am I missing something?

I think the problem is correctly characterized indeed, but for this version of the spec JACC and the Subject can be left as they are ;) The only requirement at this point as explained above is that SecurityContextImpl.getCallerPrincipal() returns the correct type. How a container accomplishes that is its own internal concern.

Hope this clarifies the intention and requirement sufficiently.

Kind regards,
Arjan Tijms


 

Will

On 05/23/2017 07:49 PM, Arjan Tijms wrote:
Hi,

I noticed that in the spec text a few essentials were removed in the security context.

For instance the part here: 

https://github.com/javaee-security-spec/security-spec/commit/db51cc841e5cb3d8feedbf52e15f31a8f2420105#diff-0164c7c2792d791d98efabe67dc90021L169

Before it said:
The _getCallerPrincipal()_ method is provided to retrieve the _Principal_ that represents the caller's name. It MUST be possible for the application to downcast this _Principal_ to the exact _Principal_ type that was set by the _HttpAuthenticationMechanism_ (possibly via an _IdentityStore_) or a JASPIC _ServerAuthModule_.
But it now it just says:
The _getCallerPrincipal()_ method retrieves the _Principal_ representing the caller.
Why was the downcast part removed?

This is really important and quite an amount of people (Java EE experts even like Mark Struberg and Romain) asked for this on Twitter and elsewhere. This aspect also comes at no cost for us since JASPIC already requires it.

It would be great if this could be put back.

Thanks!

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Arjan Tijms
 

Hi,

On Fri, May 26, 2017 at 2:31 AM, Will Hopkins <will.hopkins@...> wrote:

In WebLogic's case, it doesn't wrap the principal, so it's not possible to get back any "original" principal by unwrapping it. Implementing a wrapping scheme would be difficult, perhaps impossible, due to the way WebLogic principals are signed (to prevent spoofing) and must be Serializable (so that they can be sent across the wire in RMI calls).

I wonder then, how does WebLogic fulfil the JSR 196 requirement that it must be possible to return the exact principal?

 

It seems like it is. If it were just a requirement to return the principal that's currently in the subject, there would be no issue. This requirement is tying what's in the subject to what the HAM (or any other auth mechanism) put there, so it's effectively a constraint on what the container can do with the principals that any authentication mechanism, not just HAM, puts in a subject.

Very indirectly, perhaps, but the requirement is not new as JSR 196 already mandates it. The path where the Principal travels from the HAM to the callback handler and then back again from e.g. HttpServletRequest.getUserPrincipal should already be covered. The requirement in JSR 375 is to make sure the Principal doesn't get lost between there and when it's ultimately returned from SecurityContext.getCallerPrincipal.

 
If it must be able to return what a HAM put in the Subject, then there is a constraint -- i.e., you must be able to get back the original principal if you substitute a different one for the caller. JASPIC is less restrictive, as I read it; it allows you to "map" the caller principal, and has no other explicit constraint, except that it must be possible to "configure" the handler to return the original principal. (That's possible in WebLogic, but doing so would break a lot of things, for the reasons listed above.)

JASPIC indeed demands that it must be possible, and I double checked with the involved spec leads back then that this was indeed the case, and this was confirmed. 

As I mentioned, in practice all servers appear to be capable of returning the principal as-is. It's perhaps not easy for GlassFish, JBoss, WebSphere, Liberty, TomEE, etc either, but somehow they do manage to fulfil this requirement.


 
In my experience, there are generally a couple reasons why someone would want to use a custom principal. One is for portability across platforms, and that's a legitimate requirement. The other is to represent some specific aspect or attribute of a user other than the caller identity or groups. I've seen principals used to represent roles, or carry other attributes of a user (e.g., "employee id"). Or someone might want to use, e.g., a KerberosPrincipal to represent the kerberos principal name of a user, as distinct from the "caller identity". Sometimes people want to keep a credential in a principal, but that should really be kept as an actual Credential object in the Subject.

People indeed have all sorts of reasons, the links referenced show a few. People don't put in a custom principal type for nothing, they have a reason for doing that, and the existing specs as well as various proprietary frameworks recognised and acknowledged this a long time ago by offering APIs that allow authentication mechanisms to set a custom principal. 

The bottomline IHMO is that the spec should be portable and consistent here. Returning container specific types by default is neither, and violates the principle of least surprising (you put in an A, you get back a B).


 
Or, a simpler, easier approach -- standardize the actual types, at least in terms of an interface or base type. For example, if we standardized on CallerPrincipal (and we might want to make it an interface, not a concrete type), then everybody would know what type represented a user.

We could take a look at how to represent the principal so that's its easier for WebLogic to fulfil the requirement.

CallerPrincipal being an interface or not has in fact been discussed in the EG, but it's important to also have a concrete type so user's aren't required to perform the mundane implementation of that interface for every project out there. Easy of use is one of the prime drivers behind JSR 375 after al.
 

If a container needed a special implementation (like WebLogic, to handle signing and serialization) it could substitute its own impl, but preserve the interface. Application code would then get back a type that it understood.

An interface would be very helpful to distinguish the caller principal when browsing the bag of principals in the Subject. Still, at the end of the day, it must be possible for the exact type to be returned from SecurityContect#getCallerPrincipal.

If a user puts an A in the HAM, the expectation is simply that this A is returned later. Why otherwise would the user ever put A in, if A can't be retrieved and is just lost?

 

Either approach would make it hard for applications to add their own specific behavior to caller/group principals, but how often is that necessary? If there's really a use case for that, there might still be ways to address that, but is that a real concern?

Its apparently a real concern. See the tweet from Mark Strugberg (there were some from other EE experts as well) and the many questions about this over the last decade or so. Clearly people have their reasons.

 
Could auxiliary principal types be used where custom behavior is needed? (I.e., types other than user/group)?

WebLogic could perhaps threat the principal that was set by the HAM as a second (auxiliary) principal in the Subject, and use its own principal for whatever it needs to use this. That would be fine and not unprecedented, as containers not rarely put additional principals into the Subject for internal purposes.

The only requirement here is that SecurityContect#getCallerPrincipal returns the original one.

Perhaps it's an idea to additionally have a SecurityContect#getContainerCallerPrincipal that returns the WebLogic principal, should any code ever need that? Would that help the WebLogic case?

Kind regards,
Arjan Tijms






 

Will

 
, except in cases where they want to use JACC, in which case the principal types specified in the corresponding policy file may be an issue. (As a side note, I'm baffled by what the JASPIC spec means by a "JSR 115 compatible runtime".) It's necessary for WebLogic to support configurations such that JASPIC and JACC work together, but the vast majority of our customers do not use JACC, and therefore rely on the principal mapping our default callback handler does.

If users use JACC and work with the Subject they indeed have a somewhat related issue. We had earlier discussed a couple of ways to make this easier, like a kind of "reverse callback" where you can extract the caller principal and groups from the Subject again. I.e. Principal getCallerPrincipalFromSubject(subject);

This was also discussed in the context of the standardised group to role mapper, but we unfortunately never came to specifying that one for this spec release.

Another option was to do a "reverse wrapping" by having a getContainerPrincipal() method in CallerPrincipal, so that one can always easily find the CallerPrincipal in the Subject, but containers can always have their own version directly tied to that as well.
 

Interestingly, the GroupPrincipalCallback does not have a constructor that takes principal objects -- it takes only an array of names, essentially forcing the container's own representation of groups.

Indeed, this is maybe because there are no APIs in Java EE that actually return group principals or allow group principals for input. I.e. the existing HttpServletRequest.isUserInRole takes a string,

 

It doesn't appear that our HAM interface provides access to the CallerPrincipalCallback (or GroupPrincipalCallback).

So, assuming I've characterized the issue correctly, I'd like to propose an alternative, that allows containers to rely on proprietary representations of caller principal while still supporting use cases (like JACC) where principal type matters. As described in chapter 2 of the PRD, if containers use CallerPrincipal as a base class for container-specific caller principals, then we have the best of both worlds -- a standard base principal type, CallerPrincipal, that can safely be used in JACC policy files, and for other purposes, while still allowing the container to map to the "local" representation of a caller principal when necessary.

Thoughts? Have I correctly characterized the problem? Does my proposal meet the requirements, or am I missing something?

I think the problem is correctly characterized indeed, but for this version of the spec JACC and the Subject can be left as they are ;) The only requirement at this point as explained above is that SecurityContextImpl.getCallerPrincipal() returns the correct type. How a container accomplishes that is its own internal concern.

Hope this clarifies the intention and requirement sufficiently.

Kind regards,
Arjan Tijms


 

Will

On 05/23/2017 07:49 PM, Arjan Tijms wrote:
Hi,

I noticed that in the spec text a few essentials were removed in the security context.

For instance the part here: 

https://github.com/javaee-security-spec/security-spec/commit/db51cc841e5cb3d8feedbf52e15f31a8f2420105#diff-0164c7c2792d791d98efabe67dc90021L169

Before it said:
The _getCallerPrincipal()_ method is provided to retrieve the _Principal_ that represents the caller's name. It MUST be possible for the application to downcast this _Principal_ to the exact _Principal_ type that was set by the _HttpAuthenticationMechanism_ (possibly via an _IdentityStore_) or a JASPIC _ServerAuthModule_.
But it now it just says:
The _getCallerPrincipal()_ method retrieves the _Principal_ representing the caller.
Why was the downcast part removed?

This is really important and quite an amount of people (Java EE experts even like Mark Struberg and Romain) asked for this on Twitter and elsewhere. This aspect also comes at no cost for us since JASPIC already requires it.

It would be great if this could be put back.

Thanks!

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803



Will Hopkins
 



On 05/26/2017 03:24 AM, Arjan Tijms wrote:
Hi,

On Fri, May 26, 2017 at 2:31 AM, Will Hopkins <will.hopkins@...> wrote:

In WebLogic's case, it doesn't wrap the principal, so it's not possible to get back any "original" principal by unwrapping it. Implementing a wrapping scheme would be difficult, perhaps impossible, due to the way WebLogic principals are signed (to prevent spoofing) and must be Serializable (so that they can be sent across the wire in RMI calls).

I wonder then, how does WebLogic fulfil the JSR 196 requirement that it must be possible to return the exact principal?

I haven't exhaustively searched the spec, but AFAICT, this is what JASPIC 1.1, Maintenance Release B, says about this:
  • Section 3.8.4 of Servlet Container Profile:  "In both cases, the HttpServletRequest must be modified as necessary to ensure that the Principal returned by getUserPrincipal and the String returned by getRemoteUser correspond, respectively, to the Principal established by validateRequest (via the CallerPrincipalCallback) and to the String obtained by calling getName on the established Principal."
  • Section B.1 of Issues:  "Resolution– Defined the CallerPrincipalCallback and GroupPrincipalCallback. The container provided CallbackHandler will handle these callbacks by distinguishing (in some container specific way) the Principals identified in the corresponding Callback within a Subject passed in the Callback."
  • Javadoc for CallerPrincipalCallback:  "The handler may perform principal mapping of non-null argument Principal values, but it must be possible to configure the handler such that it establishes the non-null argument Principal as the caller principal."
The first quote tells you that it's the result of handling CallerPrincipalCallback that should be returned, the second makes clear that CallerPrincipalCallback is explicitly intended to allow container-specific handling for this, and the third says that the container may perform "principal mapping", with the only constraint being that "it must be possible to configure the handler" such that it establishes the argument Principal as the caller principal.

As I read it, the spec allows the default "configuration" of the container's callback handler to substitute a different principal.

It seems like it is. If it were just a requirement to return the principal that's currently in the subject, there would be no issue. This requirement is tying what's in the subject to what the HAM (or any other auth mechanism) put there, so it's effectively a constraint on what the container can do with the principals that any authentication mechanism, not just HAM, puts in a subject.

Very indirectly, perhaps, but the requirement is not new as JSR 196 already mandates it. The path where the Principal travels from the HAM to the callback handler and then back again from e.g. HttpServletRequest.getUserPrincipal should already be covered. The requirement in JSR 375 is to make sure the Principal doesn't get lost between there and when it's ultimately returned from SecurityContext.getCallerPrincipal.
 
If it must be able to return what a HAM put in the Subject, then there is a constraint -- i.e., you must be able to get back the original principal if you substitute a different one for the caller. JASPIC is less restrictive, as I read it; it allows you to "map" the caller principal, and has no other explicit constraint, except that it must be possible to "configure" the handler to return the original principal. (That's possible in WebLogic, but doing so would break a lot of things, for the reasons listed above.)

JASPIC indeed demands that it must be possible, and I double checked with the involved spec leads back then that this was indeed the case, and this was confirmed.

I think I've discussed this with Ron in the past, unfortunately I don't remember the specifics of what he may have said on the topic.

As I mentioned, in practice all servers appear to be capable of returning the principal as-is. It's perhaps not easy for GlassFish, JBoss, WebSphere, Liberty, TomEE, etc either, but somehow they do manage to fulfil this requirement.

WebLogic does some things other servers don't. The fact that we sign principals makes a pure JASPIC implementation that doesn't map principals incompatible with large chunks of the system (our authorization subsystem, mainly). WebLogic was doing this long before JASPIC; not sure why BEA didn't work to clarify this concern at the time JASPIC was being developed.

Another note as to the wrapping/unwrapping that is going on in some containers. While EE doesn't standardize this, most containers have ways of accessing the current caller's Subject, and retrieving its principals. It seems inconsistent to me that if you get the Subject, and then pull the "caller principal" out of the Subject, that you might get a different principal than you would if you called HttpServletRequest.getUserPrincipal().

In my experience, there are generally a couple reasons why someone would want to use a custom principal. One is for portability across platforms, and that's a legitimate requirement. The other is to represent some specific aspect or attribute of a user other than the caller identity or groups. I've seen principals used to represent roles, or carry other attributes of a user (e.g., "employee id"). Or someone might want to use, e.g., a KerberosPrincipal to represent the kerberos principal name of a user, as distinct from the "caller identity". Sometimes people want to keep a credential in a principal, but that should really be kept as an actual Credential object in the Subject.

People indeed have all sorts of reasons, the links referenced show a few. People don't put in a custom principal type for nothing, they have a reason for doing that, and the existing specs as well as various proprietary frameworks recognised and acknowledged this a long time ago by offering APIs that allow authentication mechanisms to set a custom principal.

Well, I'm playing devil's advocate here a little -- there may well be good reasons for customer caller/group principals, but I'd like to explore what the specific reasons are. It may be that, in the end, standard types for caller/groups would eliminate some of the reasons, and "auxiliary" principals, added to a Subject in addition to the primary caller/group principals, would eliminate others. I wonder how much of the "need" is predicated on the lack of standardization up to now.

The bottomline IHMO is that the spec should be portable and consistent here. Returning container specific types by default is neither, and violates the principle of least surprising (you put in an A, you get back a B).

Agree we should be portable and consistent, but we also need a standard that can be integrated into existing containers without disrupting existing ecosystems.

If we don't, we risk the standard being irrelevant, because containers won't implement it, or they will find a way to make it available, to pass the TCK, without it being usable/useful for real applications in real deployments.

(And, I would add, returning from HttpServletRequest.getUserPrincipal() that can't actually be found, unwrapped, in the Subject also violates the principal of least surprise.)

Or, a simpler, easier approach -- standardize the actual types, at least in terms of an interface or base type. For example, if we standardized on CallerPrincipal (and we might want to make it an interface, not a concrete type), then everybody would know what type represented a user.

We could take a look at how to represent the principal so that's its easier for WebLogic to fulfil the requirement.

CallerPrincipal being an interface or not has in fact been discussed in the EG, but it's important to also have a concrete type so user's aren't required to perform the mundane implementation of that interface for every project out there. Easy of use is one of the prime drivers behind JSR 375 after al.

Agree re: concrete classes, and an interface wouldn't solve all problems of inheritance. A flexible-yet-uniform model for Principals, that allows both applications and containers to provide custom logic, will be difficult to develop.

If a container needed a special implementation (like WebLogic, to handle signing and serialization) it could substitute its own impl, but preserve the interface. Application code would then get back a type that it understood.

An interface would be very helpful to distinguish the caller principal when browsing the bag of principals in the Subject. Still, at the end of the day, it must be possible for the exact type to be returned from SecurityContect#getCallerPrincipal.

If a user puts an A in the HAM, the expectation is simply that this A is returned later. Why otherwise would the user ever put A in, if A can't be retrieved and is just lost?

I think in many cases, if not most, the developer doesn't really care what the principal is, they just want to establish the caller, and they're trying to do it in a portable way that's not tied to a specific container. Or they may be authoring a policy file that refers to principals, and therefore need to know what Principal class to write the policy against. In some cases, they may have a proprietary identifier or something that they want to associate with a user.

And there may be other legitimate reasons as well, but I'd like to see an existence proof of one that can't be addressed by standardizing principals.


Either approach would make it hard for applications to add their own specific behavior to caller/group principals, but how often is that necessary? If there's really a use case for that, there might still be ways to address that, but is that a real concern?

Its apparently a real concern. See the tweet from Mark Strugberg (there were some from other EE experts as well) and the many questions about this over the last decade or so. Clearly people have their reasons.

I saw that and, not to beat a dead horse, but he asserted the need without motivating it. Maybe this is one of those things like using char[] for passwords -- received wisdom that may not be necessary ... ;)

(I was finally convinced on that question by someone who pointed out to me privately that even char[] can get moved around during gc, leaving ghost copies in memory.)
 
Could auxiliary principal types be used where custom behavior is needed? (I.e., types other than user/group)?

WebLogic could perhaps threat the principal that was set by the HAM as a second (auxiliary) principal in the Subject, and use its own principal for whatever it needs to use this. That would be fine and not unprecedented, as containers not rarely put additional principals into the Subject for internal purposes.

The only requirement here is that SecurityContect#getCallerPrincipal returns the original one.

That's a thought, but we would need some way to track which principal was the HAM's choice, and it would still lead to surprising results when HttpServletRequest.getCallerPrincpal() a different principal from the one used by the system to represent the caller for authorization, etc.

As I think about it, principal signing will be an issue for WebLogic in this context as well. With JASPIC, the callback handler gives us the ability to map and sign principals, but HAM doesn't expose that. (I plan to start a separate thread to discuss the authenticate() method and what the contract is there.)

Perhaps it's an idea to additionally have a SecurityContect#getContainerCallerPrincipal that returns the WebLogic principal, should any code ever need that? Would that help the WebLogic case?

Perhaps -- that may be a good solution if we can't arrive at a true integration that doesn't require that distinction.

Regards,

Will


Kind regards,
Arjan Tijms






 

Will

 
, except in cases where they want to use JACC, in which case the principal types specified in the corresponding policy file may be an issue. (As a side note, I'm baffled by what the JASPIC spec means by a "JSR 115 compatible runtime".) It's necessary for WebLogic to support configurations such that JASPIC and JACC work together, but the vast majority of our customers do not use JACC, and therefore rely on the principal mapping our default callback handler does.

If users use JACC and work with the Subject they indeed have a somewhat related issue. We had earlier discussed a couple of ways to make this easier, like a kind of "reverse callback" where you can extract the caller principal and groups from the Subject again. I.e. Principal getCallerPrincipalFromSubject(subject);

This was also discussed in the context of the standardised group to role mapper, but we unfortunately never came to specifying that one for this spec release.

Another option was to do a "reverse wrapping" by having a getContainerPrincipal() method in CallerPrincipal, so that one can always easily find the CallerPrincipal in the Subject, but containers can always have their own version directly tied to that as well.
 

Interestingly, the GroupPrincipalCallback does not have a constructor that takes principal objects -- it takes only an array of names, essentially forcing the container's own representation of groups.

Indeed, this is maybe because there are no APIs in Java EE that actually return group principals or allow group principals for input. I.e. the existing HttpServletRequest.isUserInRole takes a string,

 

It doesn't appear that our HAM interface provides access to the CallerPrincipalCallback (or GroupPrincipalCallback).

So, assuming I've characterized the issue correctly, I'd like to propose an alternative, that allows containers to rely on proprietary representations of caller principal while still supporting use cases (like JACC) where principal type matters. As described in chapter 2 of the PRD, if containers use CallerPrincipal as a base class for container-specific caller principals, then we have the best of both worlds -- a standard base principal type, CallerPrincipal, that can safely be used in JACC policy files, and for other purposes, while still allowing the container to map to the "local" representation of a caller principal when necessary.

Thoughts? Have I correctly characterized the problem? Does my proposal meet the requirements, or am I missing something?

I think the problem is correctly characterized indeed, but for this version of the spec JACC and the Subject can be left as they are ;) The only requirement at this point as explained above is that SecurityContextImpl.getCallerPrincipal() returns the correct type. How a container accomplishes that is its own internal concern.

Hope this clarifies the intention and requirement sufficiently.

Kind regards,
Arjan Tijms


 

Will

On 05/23/2017 07:49 PM, Arjan Tijms wrote:
Hi,

I noticed that in the spec text a few essentials were removed in the security context.

For instance the part here: 

https://github.com/javaee-security-spec/security-spec/commit/db51cc841e5cb3d8feedbf52e15f31a8f2420105#diff-0164c7c2792d791d98efabe67dc90021L169

Before it said:
The _getCallerPrincipal()_ method is provided to retrieve the _Principal_ that represents the caller's name. It MUST be possible for the application to downcast this _Principal_ to the exact _Principal_ type that was set by the _HttpAuthenticationMechanism_ (possibly via an _IdentityStore_) or a JASPIC _ServerAuthModule_.
But it now it just says:
The _getCallerPrincipal()_ method retrieves the _Principal_ representing the caller.
Why was the downcast part removed?

This is really important and quite an amount of people (Java EE experts even like Mark Struberg and Romain) asked for this on Twitter and elsewhere. This aspect also comes at no cost for us since JASPIC already requires it.

It would be great if this could be put back.

Thanks!

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


Arjan Tijms
 

Hi,

On Fri, May 26, 2017 at 10:42 PM, Will Hopkins <will.hopkins@...> wrote:


On 05/26/2017 03:24 AM, Arjan Tijms wrote:
I wonder then, how does WebLogic fulfil the JSR 196 requirement that it must be possible to return the exact principal?

I haven't exhaustively searched the spec, but AFAICT, this is what JASPIC 1.1, Maintenance Release B, says about this:
  • Section 3.8.4 of Servlet Container Profile:  "In both cases, the HttpServletRequest must be modified as necessary to ensure that the Principal returned by getUserPrincipal and the String returned by getRemoteUser correspond, respectively, to the Principal established by validateRequest (via the CallerPrincipalCallback) and to the String obtained by calling getName on the established Principal."

The way the JASPIC spec works is that the profiles supersede or more specifically specify the general requirements as described in the Chapter 1 and 2 and in the JavaDoc (the JavaDoc is general for all profiles). So this *could* be interpreted as saying that the Principal that was used must be returned (as the Subject is not mentioned here).
 
  • Section B.1 of Issues:  "Resolution– Defined the CallerPrincipalCallback and GroupPrincipalCallback. The container provided CallbackHandler will handle these callbacks by distinguishing (in some container specific way) the Principals identified in the corresponding Callback within a Subject passed in the Callback."
The way I interpret it here, is that the principal being put in the Subject may be (and in fact, always is in practice) container specific. The Subjects seems specifically designed to be non-portable, or in other words most usages of the Subject in that way is always non-portable in a standard way. This may sound confusing, but it's like the properties attribute of say @DataSourceDefiniton. The attribute is standard, but the data it carries is mostly non-portable (vendor specific).
 

  • Javadoc for CallerPrincipalCallback:  "The handler may perform principal mapping of non-null argument Principal values, but it must be possible to configure the handler such that it establishes the non-null argument Principal as the caller principal."

Indeed, so this is what I mentioned above (see quote): "how does WebLogic fulfil the JSR 196 requirement that it *must be possible* to return the exact principal"

I discussed the wording here with Ron a long time back, as it's not entirely ideal. "must be possible" is unfortunately sufficiently vague that vendors can argue to comply with the letter of the spec but not the spirit. With the spirit being (my interpretation at least) is that JASPIC favours portable authentication modules, but allows for some escape hatches for vendors wanting to be non or less portable in certain situations.

If it's really needed to take advantage of the server specific features, one can always use the server specific authentication modules. But if portability is favoured then JASPIC (and now the Java EE security API) comes into play.

As for the principal signing that you mentioned, I haven't had a need for this, but I happened to have a need for authentication modules that could work on GlassFish, WildFly and Liberty. Now if I would have needed principal signing, I probably would not bother with JASPIC and go straight for the WebLogic native modules then.

 
I think I've discussed this with Ron in the past, unfortunately I don't remember the specifics of what he may have said on the topic.

I have had some mail discussions with him about this too, which I'll try to dig up. But one way or the other the fact that it must be possible (after some configuration, whether that's the default or not) to return the exact principal seems to be pretty clear.

Another pointer is that there's currently a bug in GlassFish which causes the container specific principal to be returned. This is clearly a bug as the GF code very clearly preserves the original principal, but then due to a combination of things returns the wrong one from HttpServletRequest.getUserPrincipal.

Now not only has this bug been reported (by someone other than me, "proving" that people care about this), that case was also confirmed by Ron as a bug.


 
WebLogic does some things other servers don't. The fact that we sign principals makes a pure JASPIC implementation that doesn't map principals incompatible with large chunks of the system (our authorization subsystem, mainly). WebLogic was doing this long before JASPIC; not sure why BEA didn't work to clarify this concern at the time JASPIC was being developed.

Maybe they did, but since no other vendor seems to have issues with this they may have been overruled here?

 

Another note as to the wrapping/unwrapping that is going on in some containers. While EE doesn't standardize this, most containers have ways of accessing the current caller's Subject, and retrieving its principals. It seems inconsistent to me that if you get the Subject, and then pull the "caller principal" out of the Subject, that you might get a different principal than you would if you called HttpServletRequest.getUserPrincipal().

All full profile containers have a way of accessing the current caller's Subject, since this is mandated by the spec.

I understand what you mean here, but there's already no portable way to get the "caller principal" out of this Subject, which is by itself a very big and real problem for portable authorization modules.

But, since there's no portable way to get the caller principal to begin with, the fact it would be different from HttpServletRequest.getUserPrincipal() would not really apply. 

I did btw coded up some utility code to get to the correct Principals for most servers. See here; 



 
Well, I'm playing devil's advocate here a little -- there may well be good reasons for customer caller/group principals, but I'd like to explore what the specific reasons are. It may be that, in the end, standard types for caller/groups would eliminate some of the reasons, and "auxiliary" principals, added to a Subject in addition to the primary caller/group principals, would eliminate others. I wonder how much of the "need" is predicated on the lack of standardization up to now.

Very often it's extra attributes, extra information about the caller, flags that the authentication mechanism sets on the caller and that triggers e.g. extra review or auditing downstream. JSR 351 (The Identity API) may have addressed some of these things, but unfortunately 351 was withdrawn.

Occasionally it's also the exact type that's being tracked to see for example which authentication mechanism was used to authenticate. If it was an OAuth2 Facebook one, the application code renders "logged-in with Facebook" and if it wasn't Facebook it renders something else.

I've also once seen an EncryptedPrincipal that the application code would know to decrypt in certain cases.

But in general it's a matter of not bleeding container types into the application. Java EE security has been perceived as arcane and difficult exactly because of the many container specific things. One of the goals of JSR 375 next to being easy to use is to require no container specific handling whatsoever by default (which implicitly makes its easier to use again, so that kinda follows from the first goal).

JASPIC did some great steps in making this *possible*, so one way or another every vendor must support this already in "some" configuration.

 
Agree we should be portable and consistent, but we also need a standard that can be integrated into existing containers without disrupting existing ecosystems.

True but till so far WebLogic seems to be the only container that seems to have issues with this. I tested each and every JASPIC implementation there is and it works everywhere (tbh, I do need to retest TMaxSoft JEUS again).

That doesn't mean of course that it isn't important to find a workable solution for WebLogic, but as it stands it looks like it's not a problem that disrupts a large part of the Java EE ecosystem.

 
If we don't, we risk the standard being irrelevant, because containers won't implement it, or they will find a way to make it available, to pass the TCK, without it being usable/useful for real applications in real deployments.

(And, I would add, returning from HttpServletRequest.getUserPrincipal() that can't actually be found, unwrapped, in the Subject also violates the principal of least surprise.)

As mentioned above, the usage of the Subject is currently non-portable anyway, so while that is a concern by itself, it's not a concern for now.

That said, a hypothetical method that does Principal principal = getCallerPrincipalFromSubject(subject); should indeed need to return the same Principal type as HttpServletRequest.getUserPrincipal() and SecurityContext.getCallerPrincipal() return.

 
I think in many cases, if not most, the developer doesn't really care what the principal is,

While in many cases the Principal with only the name is indeed enough, from personal experience and by judging from all the question about this throughout the years I think that also in many other cases just the Principal is certainly not enough.

The other way around, how many developers actually *want* the default return type to be an unknown container specific Principal? I think that are even fewer cases.
 

I saw that and, not to beat a dead horse, but he asserted the need without motivating it.

Well, Twitter is a not ideal to motivate things in much detail. He motivated it in a private chat with me and it basically boiled down to having extra attributes on the principal that his actual customers need.

 
Maybe this is one of those things like using char[] for passwords -- received wisdom that may not be necessary ... ;)

(I was finally convinced on that question by someone who pointed out to me privately that even char[] can get moved around during gc, leaving ghost copies in memory.)

Interesting, thanks for sharing ;)

 

As I think about it, principal signing will be an issue for WebLogic in this context as well. With JASPIC, the callback handler gives us the ability to map and sign principals, but HAM doesn't expose that.

It actually does as a low level "escape hatch" for those authentication mechanisms that really need it:

    /**
     * Returns the low level JSR 196 handler that the runtime provided when creating this {@link HttpMessageContext},
     * and which this context uses to communicate the authentication details to the runtime.
     * 
     * <p>
     * <em>Note:</em> This is a low level object that most higher level code would not need to use directly.
     * 
     * @return the handler that the runtime provided to this context
     */
    CallbackHandler getHandler();


 
Perhaps -- that may be a good solution if we can't arrive at a true integration that doesn't require that distinction.

Okay, let's keep that in mind then ;)

There's some amount of precedent in Java EE here, where the spec demands a portable type to be returned by default, but allows access to the container specific version via some unwrap method. E.g. the JPA EntityManager and Query types spring to mind.

Another option that I think I remember coming up in a discussion with Ron before is to make the configuration that JASPIC talks about portable, so that the authentication mechanism can set whether it wants to allow mapping of the Principal or not.

E.g.

From the validateRequest method:

return httpMessageContext
                .portable()
                .notifyContainerAboutLogin(
                    principal, groups)

or

return httpMessageContext
                .allowContainerMapping(false)
                .notifyContainerAboutLogin(
                    principal, groups)

etc

The syntax and naming is just illustrative and this could be done in many ways.

Thoughts?

Kind regards,
Arjan Tijms






 

Regards,

Will



Kind regards,
Arjan Tijms






 

Will

 
, except in cases where they want to use JACC, in which case the principal types specified in the corresponding policy file may be an issue. (As a side note, I'm baffled by what the JASPIC spec means by a "JSR 115 compatible runtime".) It's necessary for WebLogic to support configurations such that JASPIC and JACC work together, but the vast majority of our customers do not use JACC, and therefore rely on the principal mapping our default callback handler does.

If users use JACC and work with the Subject they indeed have a somewhat related issue. We had earlier discussed a couple of ways to make this easier, like a kind of "reverse callback" where you can extract the caller principal and groups from the Subject again. I.e. Principal getCallerPrincipalFromSubject(subject);

This was also discussed in the context of the standardised group to role mapper, but we unfortunately never came to specifying that one for this spec release.

Another option was to do a "reverse wrapping" by having a getContainerPrincipal() method in CallerPrincipal, so that one can always easily find the CallerPrincipal in the Subject, but containers can always have their own version directly tied to that as well.
 

Interestingly, the GroupPrincipalCallback does not have a constructor that takes principal objects -- it takes only an array of names, essentially forcing the container's own representation of groups.

Indeed, this is maybe because there are no APIs in Java EE that actually return group principals or allow group principals for input. I.e. the existing HttpServletRequest.isUserInRole takes a string,

 

It doesn't appear that our HAM interface provides access to the CallerPrincipalCallback (or GroupPrincipalCallback).

So, assuming I've characterized the issue correctly, I'd like to propose an alternative, that allows containers to rely on proprietary representations of caller principal while still supporting use cases (like JACC) where principal type matters. As described in chapter 2 of the PRD, if containers use CallerPrincipal as a base class for container-specific caller principals, then we have the best of both worlds -- a standard base principal type, CallerPrincipal, that can safely be used in JACC policy files, and for other purposes, while still allowing the container to map to the "local" representation of a caller principal when necessary.

Thoughts? Have I correctly characterized the problem? Does my proposal meet the requirements, or am I missing something?

I think the problem is correctly characterized indeed, but for this version of the spec JACC and the Subject can be left as they are ;) The only requirement at this point as explained above is that SecurityContextImpl.getCallerPrincipal() returns the correct type. How a container accomplishes that is its own internal concern.

Hope this clarifies the intention and requirement sufficiently.

Kind regards,
Arjan Tijms


 

Will

On 05/23/2017 07:49 PM, Arjan Tijms wrote:
Hi,

I noticed that in the spec text a few essentials were removed in the security context.

For instance the part here: 

https://github.com/javaee-security-spec/security-spec/commit/db51cc841e5cb3d8feedbf52e15f31a8f2420105#diff-0164c7c2792d791d98efabe67dc90021L169

Before it said:
The _getCallerPrincipal()_ method is provided to retrieve the _Principal_ that represents the caller's name. It MUST be possible for the application to downcast this _Principal_ to the exact _Principal_ type that was set by the _HttpAuthenticationMechanism_ (possibly via an _IdentityStore_) or a JASPIC _ServerAuthModule_.
But it now it just says:
The _getCallerPrincipal()_ method retrieves the _Principal_ representing the caller.
Why was the downcast part removed?

This is really important and quite an amount of people (Java EE experts even like Mark Struberg and Romain) asked for this on Twitter and elsewhere. This aspect also comes at no cost for us since JASPIC already requires it.

It would be great if this could be put back.

Thanks!

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803



Guillermo González de Agüero
 

Hi,

El vie., 26 de mayo de 2017 22:42, Will Hopkins <will.hopkins@...> escribió:


On 05/26/2017 03:24 AM, Arjan Tijms wrote:
Hi,

On Fri, May 26, 2017 at 2:31 AM, Will Hopkins <will.hopkins@...> wrote:

In WebLogic's case, it doesn't wrap the principal, so it's not possible to get back any "original" principal by unwrapping it. Implementing a wrapping scheme would be difficult, perhaps impossible, due to the way WebLogic principals are signed (to prevent spoofing) and must be Serializable (so that they can be sent across the wire in RMI calls).

I wonder then, how does WebLogic fulfil the JSR 196 requirement that it must be possible to return the exact principal?

I haven't exhaustively searched the spec, but AFAICT, this is what JASPIC 1.1, Maintenance Release B, says about this:
  • Section 3.8.4 of Servlet Container Profile:  "In both cases, the HttpServletRequest must be modified as necessary to ensure that the Principal returned by getUserPrincipal and the String returned by getRemoteUser correspond, respectively, to the Principal established by validateRequest (via the CallerPrincipalCallback) and to the String obtained by calling getName on the established Principal."
  • Section B.1 of Issues:  "Resolution– Defined the CallerPrincipalCallback and GroupPrincipalCallback. The container provided CallbackHandler will handle these callbacks by distinguishing (in some container specific way) the Principals identified in the corresponding Callback within a Subject passed in the Callback."
  • Javadoc for CallerPrincipalCallback:  "The handler may perform principal mapping of non-null argument Principal values, but it must be possible to configure the handler such that it establishes the non-null argument Principal as the caller principal."
The first quote tells you that it's the result of handling CallerPrincipalCallback that should be returned, the second makes clear that CallerPrincipalCallback is explicitly intended to allow container-specific handling for this, and the third says that the container may perform "principal mapping", with the only constraint being that "it must be possible to configure the handler" such that it establishes the argument Principal as the caller principal.

As I read it, the spec allows the default "configuration" of the container's callback handler to substitute a different principal.


It seems like it is. If it were just a requirement to return the principal that's currently in the subject, there would be no issue. This requirement is tying what's in the subject to what the HAM (or any other auth mechanism) put there, so it's effectively a constraint on what the container can do with the principals that any authentication mechanism, not just HAM, puts in a subject.

Very indirectly, perhaps, but the requirement is not new as JSR 196 already mandates it. The path where the Principal travels from the HAM to the callback handler and then back again from e.g. HttpServletRequest.getUserPrincipal should already be covered. The requirement in JSR 375 is to make sure the Principal doesn't get lost between there and when it's ultimately returned from SecurityContext.getCallerPrincipal.
 
If it must be able to return what a HAM put in the Subject, then there is a constraint -- i.e., you must be able to get back the original principal if you substitute a different one for the caller. JASPIC is less restrictive, as I read it; it allows you to "map" the caller principal, and has no other explicit constraint, except that it must be possible to "configure" the handler to return the original principal. (That's possible in WebLogic, but doing so would break a lot of things, for the reasons listed above.)

JASPIC indeed demands that it must be possible, and I double checked with the involved spec leads back then that this was indeed the case, and this was confirmed.

I think I've discussed this with Ron in the past, unfortunately I don't remember the specifics of what he may have said on the topic.


As I mentioned, in practice all servers appear to be capable of returning the principal as-is. It's perhaps not easy for GlassFish, JBoss, WebSphere, Liberty, TomEE, etc either, but somehow they do manage to fulfil this requirement.

WebLogic does some things other servers don't. The fact that we sign principals makes a pure JASPIC implementation that doesn't map principals incompatible with large chunks of the system (our authorization subsystem, mainly). WebLogic was doing this long before JASPIC; not sure why BEA didn't work to clarify this concern at the time JASPIC was being developed.

Another note as to the wrapping/unwrapping that is going on in some containers. While EE doesn't standardize this, most containers have ways of accessing the current caller's Subject, and retrieving its principals. It seems inconsistent to me that if you get the Subject, and then pull the "caller principal" out of the Subject, that you might get a different principal than you would if you called HttpServletRequest.getUserPrincipal().


In my experience, there are generally a couple reasons why someone would want to use a custom principal. One is for portability across platforms, and that's a legitimate requirement. The other is to represent some specific aspect or attribute of a user other than the caller identity or groups. I've seen principals used to represent roles, or carry other attributes of a user (e.g., "employee id"). Or someone might want to use, e.g., a KerberosPrincipal to represent the kerberos principal name of a user, as distinct from the "caller identity". Sometimes people want to keep a credential in a principal, but that should really be kept as an actual Credential object in the Subject.

People indeed have all sorts of reasons, the links referenced show a few. People don't put in a custom principal type for nothing, they have a reason for doing that, and the existing specs as well as various proprietary frameworks recognised and acknowledged this a long time ago by offering APIs that allow authentication mechanisms to set a custom principal.

Well, I'm playing devil's advocate here a little -- there may well be good reasons for customer caller/group principals, but I'd like to explore what the specific reasons are. It may be that, in the end, standard types for caller/groups would eliminate some of the reasons, and "auxiliary" principals, added to a Subject in addition to the primary caller/group principals, would eliminate others. I wonder how much of the "need" is predicated on the lack of standardization up to now.
Just a doubt, could this standarization still be done before going final? That could be a very useful addition. But it won't help this case if it needs to wait until the next release.

The bottomline IHMO is that the spec should be portable and consistent here. Returning container specific types by default is neither, and violates the principle of least surprising (you put in an A, you get back a B).

Agree we should be portable and consistent, but we also need a standard that can be integrated into existing containers without disrupting existing ecosystems.

If we don't, we risk the standard being irrelevant, because containers won't implement it, or they will find a way to make it available, to pass the TCK, without it being usable/useful for real applications in real deployments.

(And, I would add, returning from HttpServletRequest.getUserPrincipal() that can't actually be found, unwrapped, in the Subject also violates the principal of least surprise.)


Or, a simpler, easier approach -- standardize the actual types, at least in terms of an interface or base type. For example, if we standardized on CallerPrincipal (and we might want to make it an interface, not a concrete type), then everybody would know what type represented a user.

We could take a look at how to represent the principal so that's its easier for WebLogic to fulfil the requirement.

CallerPrincipal being an interface or not has in fact been discussed in the EG, but it's important to also have a concrete type so user's aren't required to perform the mundane implementation of that interface for every project out there. Easy of use is one of the prime drivers behind JSR 375 after al.

Agree re: concrete classes, and an interface wouldn't solve all problems of inheritance. A flexible-yet-uniform model for Principals, that allows both applications and containers to provide custom logic, will be difficult to develop.


If a container needed a special implementation (like WebLogic, to handle signing and serialization) it could substitute its own impl, but preserve the interface. Application code would then get back a type that it understood.

An interface would be very helpful to distinguish the caller principal when browsing the bag of principals in the Subject. Still, at the end of the day, it must be possible for the exact type to be returned from SecurityContect#getCallerPrincipal.

If a user puts an A in the HAM, the expectation is simply that this A is returned later. Why otherwise would the user ever put A in, if A can't be retrieved and is just lost?

I think in many cases, if not most, the developer doesn't really care what the principal is, they just want to establish the caller, and they're trying to do it in a portable way that's not tied to a specific container. Or they may be authoring a policy file that refers to principals, and therefore need to know what Principal class to write the policy against. In some cases, they may have a proprietary identifier or something that they want to associate with a user.

And there may be other legitimate reasons as well, but I'd like to see an existence proof of one that can't be addressed by standardizing principals.



Either approach would make it hard for applications to add their own specific behavior to caller/group principals, but how often is that necessary? If there's really a use case for that, there might still be ways to address that, but is that a real concern?

Its apparently a real concern. See the tweet from Mark Strugberg (there were some from other EE experts as well) and the many questions about this over the last decade or so. Clearly people have their reasons.

I saw that and, not to beat a dead horse, but he asserted the need without motivating it. Maybe this is one of those things like using char[] for passwords -- received wisdom that may not be necessary ... ;)

(I was finally convinced on that question by someone who pointed out to me privately that even char[] can get moved around during gc, leaving ghost copies in memory.)

 
Could auxiliary principal types be used where custom behavior is needed? (I.e., types other than user/group)?

WebLogic could perhaps threat the principal that was set by the HAM as a second (auxiliary) principal in the Subject, and use its own principal for whatever it needs to use this. That would be fine and not unprecedented, as containers not rarely put additional principals into the Subject for internal purposes.

The only requirement here is that SecurityContect#getCallerPrincipal returns the original one.

That's a thought, but we would need some way to track which principal was the HAM's choice, and it would still lead to surprising results when HttpServletRequest.getCallerPrincpal() a different principal from the one used by the system to represent the caller for authorization, etc.

As I think about it, principal signing will be an issue for WebLogic in this context as well. With JASPIC, the callback handler gives us the ability to map and sign principals, but HAM doesn't expose that. (I plan to start a separate thread to discuss the authenticate() method and what the contract is there.)


Perhaps it's an idea to additionally have a SecurityContect#getContainerCallerPrincipal that returns the WebLogic principal, should any code ever need that? Would that help the WebLogic case?

Perhaps -- that may be a good solution if we can't arrive at a true integration that doesn't require that distinction.
As I underarstand, this would be an additional method, not replacing the existing one. Since the problem it solves seems to affect only WebLogic, could it be added just to the RI? If real usage demonstrates it is a needed feature, it would be moved to the spec in the future.

Regards,

Will



Kind regards,
Arjan Tijms






 

Will

 
, except in cases where they want to use JACC, in which case the principal types specified in the corresponding policy file may be an issue. (As a side note, I'm baffled by what the JASPIC spec means by a "JSR 115 compatible runtime".) It's necessary for WebLogic to support configurations such that JASPIC and JACC work together, but the vast majority of our customers do not use JACC, and therefore rely on the principal mapping our default callback handler does.

If users use JACC and work with the Subject they indeed have a somewhat related issue. We had earlier discussed a couple of ways to make this easier, like a kind of "reverse callback" where you can extract the caller principal and groups from the Subject again. I.e. Principal getCallerPrincipalFromSubject(subject);

This was also discussed in the context of the standardised group to role mapper, but we unfortunately never came to specifying that one for this spec release.

Another option was to do a "reverse wrapping" by having a getContainerPrincipal() method in CallerPrincipal, so that one can always easily find the CallerPrincipal in the Subject, but containers can always have their own version directly tied to that as well.
 

Interestingly, the GroupPrincipalCallback does not have a constructor that takes principal objects -- it takes only an array of names, essentially forcing the container's own representation of groups.

Indeed, this is maybe because there are no APIs in Java EE that actually return group principals or allow group principals for input. I.e. the existing HttpServletRequest.isUserInRole takes a string,

 

It doesn't appear that our HAM interface provides access to the CallerPrincipalCallback (or GroupPrincipalCallback).

So, assuming I've characterized the issue correctly, I'd like to propose an alternative, that allows containers to rely on proprietary representations of caller principal while still supporting use cases (like JACC) where principal type matters. As described in chapter 2 of the PRD, if containers use CallerPrincipal as a base class for container-specific caller principals, then we have the best of both worlds -- a standard base principal type, CallerPrincipal, that can safely be used in JACC policy files, and for other purposes, while still allowing the container to map to the "local" representation of a caller principal when necessary.

Thoughts? Have I correctly characterized the problem? Does my proposal meet the requirements, or am I missing something?

I think the problem is correctly characterized indeed, but for this version of the spec JACC and the Subject can be left as they are ;) The only requirement at this point as explained above is that SecurityContextImpl.getCallerPrincipal() returns the correct type. How a container accomplishes that is its own internal concern.

Hope this clarifies the intention and requirement sufficiently.

Kind regards,
Arjan Tijms


 

Will

On 05/23/2017 07:49 PM, Arjan Tijms wrote:
Hi,

I noticed that in the spec text a few essentials were removed in the security context.

For instance the part here: 

https://github.com/javaee-security-spec/security-spec/commit/db51cc841e5cb3d8feedbf52e15f31a8f2420105#diff-0164c7c2792d791d98efabe67dc90021L169

Before it said:
The _getCallerPrincipal()_ method is provided to retrieve the _Principal_ that represents the caller's name. It MUST be possible for the application to downcast this _Principal_ to the exact _Principal_ type that was set by the _HttpAuthenticationMechanism_ (possibly via an _IdentityStore_) or a JASPIC _ServerAuthModule_.
But it now it just says:
The _getCallerPrincipal()_ method retrieves the _Principal_ representing the caller.
Why was the downcast part removed?

This is really important and quite an amount of people (Java EE experts even like Mark Struberg and Romain) asked for this on Twitter and elsewhere. This aspect also comes at no cost for us since JASPIC already requires it.

It would be great if this could be put back.

Thanks!

Kind regards,
Arjan Tijms

-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803


-- 
Will Hopkins | WebLogic Security Architect | +1.781.442.0310
Oracle Application Development
35 Network Drive, Burlington, MA 01803