Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [es-dev] User principal and role check consistency between specs

Hi,

On Sun, Jun 24, 2018 at 4:28 PM Guillermo González de Agüero <z06.guillermo@xxxxxxxxx> wrote:
Servlet, JAX-WS and EJB behaviour is theoretically controlled by JACC.

This is indeed the case. Basically all specs in Java EE are united by this "invisible backbone", where JACC is indeed basically the controller of. JASPIC is the only standard SPI in Java EE that can put something into this backbone in an official way.

That's basically why by 'just' using JASPIC, EE 7 security was able to be automatically compatible with Servlet, EJB, etc.
 
JAX-WS should inherit the Servlet rules when implemented on top of them (which is not mandatory).

JAX-WS can use either Servlet or EJB as an endpoint, but in case of JAX-WS there's actually the SOAP profile of JASPIC that comes into play. EE Security has ignored that profile for now. I'm not a super big SOAP expert, but I think different kinds of authentication mechanisms for SOAP are rare. SOAP has its own WSS security, which means that there's essentially a single standard authentication mechanism and little need to ever replace that. In Payara/GlassFish/Metro that is com.sun.xml.wss.provider.ServerSecurityAuthModule. 

However, that authentication mechanism does inject the authenticated identity into the same backbone again (using JASPIC, or in GF/Payara its predecessor JAuth), so if you inject a JAX-WS endpoint with the EE security context, you get the correct identity again.

 
But Security has always been difficult on Java EE and so users have relied on a lot of home-grown solutions, like overriding HttpServletRequest or javax.ws.rs.core.SecurityContext methods to control the caller identity. That approach presents the issue that the identity is not controlled by the container and thus not propagated between components.

Indeed, in that case the wrapper HttpServletRequest would not draw its data from this backbone and only callers of HttpServletRequest#getUserPrinciple would see that principle.
 

The "is caller in role" methods can also be problematic. Imagine the following situations:
- On a Servlet based JAX-RS resource/JAX-WS service, with a HttpServletRequestWrapper that overrides the getUserPrincipal()/isUserInRole() methods might return different results than the javax.ws.rs.core.SecurityContext and WebServiceContext equivalent methods.
- On an EJB based JAX-RS resource, with a custom javax.ws.rs.core.SecurityContext overriding the getUserPrincipal()/isUserInRole() methods, EJBContext might return different results that SecurityContext.

Indeed, doing custom security by overriding the objects where you query the roles will always lead to inconsistencies. You really have to inject the security data into that backbone to be consistent. This is what people sometimes don't really get.

 
- In any case, it's unspecified where CDI takes its injectable Principal from [2].

Well, it should logically be taken from this same backbone again. But CDI implementations such as Weld do require containers to implement a container specific SPI for that, as there wasn't any other API available before EE Security.

 
- Things like @RolesAllowed and Servlet security constraints won't work with the "dynamic" roles.

Not 100% sure what you mean here. Dynamic roles as implemented by JACC providers do work with the EJB interceptors behind @RolesAllowed, and Servlet security constraints, at least they do in a full Java EE Server (which *must* use JACC for these).
 

In addition to that problems, there's no guarantee that all the "get caller principal" methods will return the same object. The former JSR 375 EG couldn't agree to return the user defined Principal (via JASPIC) as the caller principal due to some shortcomings in WebLogic.

For the sake of getting the spec released in that timeframe with Will being the WebLogic security architect as well, we indeed had to compromise there, although the getPrincipalsByType should be usable here.

For the next version of JASPIC I'd really like to close the gap that JASPIC left open here (this is where it says that the container is free to return another type, but that it must be possible to configure the container to return the right type, but then doesn't say how to configure this).

 
To improve this situation, my personal take on this is we should push other specs to:
- Servlet: when there's a JSR375 implementation on the classpath, login must be done via an HttpAuthenticationMechanism.

For the isCallerInRole etc consistency this wouldn't be strictly needed. Login/authentication via proprietary mechanisms (like the Tomcat Authenticator) already injects into the same backbone that JASPIC also injects into, and everything basically works.

For consistency Servlet could technically model all of its internal authentication mechanisms (FORM, BASIC, CLIENT-CERT) to be JASPIC SAMs. I vaguely recall either Mark from Tomcat or Greg from Jetty mentioning this once. They could do this outside EE.

Within an EE container, Will already opened the doors for implementations being allowed to delegate between the Server build-in or EE Security provided authentication mechanisms. This doesn't matter for the data that javax.security.enterprise.SecurityContext returns. As mentioned above, whether you authenticate using a Servlet container proprietary mechanism or via JASPIC/HttpAuthenticationMechanism, javax.security.enterprise.SecurityContext should always return the same data.

Still, it would indeed be nice if web.xml's <login-config><auth-method>FORM</auth-method></login-config> and @FormAuthenticationMechanismDefinition in an EE environment would be mandated to use the exact same (EE Security) authentication mechanism. Currently they are going to completely different implementations, although these implementations should work in the same way and have the same outcome.

 
In those cases, users are pointed to customize the
javax.security.enterprise.SecurityContext in order to provide custom behaviour, instead of wrapping the HttpServletRequest. Role checks are done against the SecurityContext (which in turn will delegate to JACC by default).

If -everything- in EE would use javax.security.enterprise.SecurityContext as their primary source for the isCallerInRole query, this could almost work, but I think it's not the best place to do this really. For one, decorating SecurityContext would still be inconsistent then with code using JACC directly. Using JACC directly is rare, but still legal. 

Also, custom JACC plug-ins/extensions would be the dedicated place in EE for custom "authorization behaviour". Currently this is far too difficult to implement for application developers to be of practical use, but this can be made much easier. The proof of concept I did for EE Security 1.0 showed a way, but there was no time left to discuss and polish that for inclusion in 1.0, but it should definitely be on the roadmap for the next version.

 
JASPIC should always be mandated, even outside Jakarta EE containers.

Absolutely, the Servlet spec already says that this *should* be used. Basically the only spec change is that *should* has to be changed into *must*. Last time around in the Servlet spec discussions about this we were almost there.

 
- JAX-RS: deprecate javax.ws.rs.core.SecurityContext and strongly recommend users to directly use the Security API. JAX-RS doesn't even have a portable way to define security constraints (Servlet integration is optional). Users will still be able to implement home grown security if they don't want/can't use the Security API.

Definite +100 for this. Several other treads discussed this as well, and this seems to have a majority support. There's just no need to duplicate this in EE and specs in EE are already big enough. Now that some can be trimmed a little they really should.

 
- EJB and JAX-WS: if there are new releases of these specs, they should mandate the security methods to delegate to javax.security.enterprise.SecurityContext. EJB Lite and standalone JAX-WS would be outside this rule. @RolesAllowed checks are done agains SecurityContext.

As mentioned, this would not be absolutely necessary for data consistency, but it would free up some code from having to use proprietary/internal APIs. Jakarta EE itself would be implemented using Jakarta EE itself then (just like Mojarra in Payara for instance uses standard Servlet APIs and doesn't use say Tomcat specific APIs instead)
 
- CDI: deprecate Principal injection and delegate its obtention to SecurityContext#getCallerPrincipal.

+100 here too. The CDI EG and specifically the spec lead wanted to be out of the business of providing built-in beans that are the responsibility of other specs. The Security spec should provide the built-in bean for Principal related things, and the Servlet spec should provide the built-in beans for the Servlet artefacts.

 
We get the follwing benefits from this:
- Every "getCallerPrincipal" method returns the same instance. As of now, there's still no guarantee that the instance will be the one defined by the user. But if we are able to eventually remove the concept of "platform-specific" principal representations, all methods will automatically get the user principal. For the time being, they will at least all return the same representation.

I think for the guarantee that say HttpServletRequest#getUserPrincipal returns the custom principal this is not strictly needed. It should already do that when using JASPIC. See the "custom principal" tests here: https://arjan-tijms.omnifaces.org/2016/12/the-state-of-portable-authentication-in.html

Only WebLogic is failing that one. According to the spec WebLogic *must* be able to be configured to that is doesn't fail this test. But as said, it's not specified how this should be configured, and I wasn't able to figure this out from the WebLogic documentation.
 
- Users who need to do application-managed identities will only need to provide an @Alternative SecurityContext and all security related methods will return consistent results. The identity won't be propagated to the container, but container facilities like @RolesAllowed should still work.

Also as mentioned above, it will be all security related methods except for direct usage of the JACC APIs. Even though it's an option, I'd rather see we make it really, really easy to provide custom JACC rules. This should be as easy, or even easier than providing an @Alternative SecurityContext.

Kind regards,
Arjan


 
_______________________________________________
es-dev mailing list
es-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/es-dev

Back to the top