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,

Responses inline

El dom., 24 jun. 2018 21:01, Rudy De Busscher <rdebusscher@xxxxxxxxx> escribió:
Hi,

Why the different approach for the frameworks?

Servlet: when there's a JSR375 implementation on the classpath, ...
JAX-RS: deprecate javax.ws.rs.core.SecurityContext ...

Why not always define that "if there's a JSR375 implementation on the classpath, .... needs to delegate to javax.security.enterprise.SecurityContext. ... "
My proposal can be reworded to:
- Everywhere: if there's JSR375, delegate to it.
- JAX-RS and CDI: in addition, deprecate its SecurityContext

My reasoning is:
- Servlet deals with container authentication and propagates identity. I see value on those methods on a standalone container as they will interact with it. Servlet also is the only portable entrypoint for login that I'm aware lf.
- EJB: again, security methods interact with the container. You can bootstrap an embedded EJB container where you won't have CDI (so no JSR 375). EJB integrates with container security via @RolesAllowed and @RunAs. Therefore I see some value on these methods. Also I don't think it makes sense to put much time into this spec.
- JAX-WS: I have only basic experience with JAX-WS so I can only recommend to delegate. Others will have to say on this. But similar to EJB, I don't think we should dedicate too much effort on this.

Now, CDI. You'll define your "CustomUserPrincipal" with some additional properties and register via your HttpAuthenticationMechanism. Then you'll "@Inject Principal principal", only to get a "WebLogicUserPrincipal", which is useless for your case.

JSR 375 couldn't solve the problem of the caller principal, so it provided a way to get the Principals by type [1]. From now on, I think the recommended way to inject the caller principal is to define your own producer:

@Produces
public CustomUserPrincipal produce() {
    return securityContext.getPrincipalsBytype(CustomUserPrincipal.class).iterator().next();
}

I think CDI took the responsibility to produce the caller principal just because there were no other spec to do it. Now there's the Security spec which is a better place for it.

Regarding JAX-RS, my point here is that JAX-RS only interacts with the container security via the default implementation of javax.ws.rs.core.SecurityContext. I see two usecases for this class:
- Gather information about the caller.
- Configure a home grown authentication system.

The first usecase is superseded by the JSR 375 Security Context, when available. The second one invalidates all container security integration, such as Servlet security constraints and EJB @RolesAllowed. There was a case for this on full Java EE containers when JASPIC was the only available authentication system, which is overly complex for simple cases.

Now the Security API solves it, at least on full containers, but there are other situations:
- You can use JAX-RS standalone without Servlet. Then you won't have any integrated security, so the class is of little value. You will have to implement you own authentication system where you won't even need to use Principals and roles.
- JAX-RS 3.0 will predictably mandate CDI [2], so if you run it on top of a Servlet container, you'll only need to add the JSR 375 dependency (CDI extension) to your classpath to get a full authentication system. If you don't want to add the dependency, you'll still be able to @Context HttpServletRequest to check for the user principal and roles.

javax.ws.rs.core.SecurityContext provides two more methods. One to get an arbitrary string representing the authentication scheme, with four predefined values for the Servlet supported ones (seems like the return value for other authentication mechanisms is undefined). And the other method to get whether the request was done over HTTPS. This last method is the only one that isn't covered anywhere else.

[1] https://javaee.github.io/javaee-spec/javadocs/javax/security/enterprise/SecurityContext.html#getPrincipalsByType-java.lang.Class-
[2] https://github.com/eclipse-ee4j/jaxrs-api/issues/569


Can you explain what you mean by "JASPIC should always be mandated, even outside Jakarta EE containers."

Are we enforcing that each servlet container needs to include JASPIC (and JACC)?
JASPIC, yes. Incidentally, this should help Servlet+JAX-RS containers to make it easier to provide your container integrated authentication.

As often pointed by Arjan Tijms [3], the Servlet spec already recommends implementations to always use JASPIC, even outside Java EE containers.

But this is of most interest for the JASPIC project and it's really not part of this discussion (I'll move this point there).


regards
Rudy



On Sun, 24 Jun 2018 at 17:28, Guillermo González de Agüero <z06.guillermo@xxxxxxxxx> wrote:
Hi,

There was some discussion around JAX-RS and the Security API integration on another thread [1]. Before opening a thread on the JAX-RS list to consider deprecating their SecurityContext class, I'd like to gather your opinion on the broad part of this topic.

Currently, the following specs (besides Security spec and JACC) provide a way to get the user principal and/or check user roles:
  Spec        User Principal                                                                   User in role                      
 ------------ ----------------------------------------------------------------------- -----------------------------------
  Servlet    HttpServletRequest#getUserPrincipal()                           HttpServletRequest#isUserInRole() 
  JAX-RS     javax.ws.rs.core.SecurityContext#getUserPrincipal()     javax.ws.rs.core.SecurityContext#isUserInRole()
  JAX-WS    WebServiceContext#getUserPrincipal()                           WebServiceContext#isUserInRole()  
  EJB          EJBContext#getCallerPrincipal()                                       EJBContext#isCallerInRole()       
  CDI          @Inject Principal principal                                                -

Servlet, JAX-WS and EJB behaviour is theoretically controlled by JACC. JAX-WS should inherit the Servlet rules when implemented on top of them (which is not mandatory).

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.

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.
- In any case, it's unspecified where CDI takes its injectable Principal from [2].
- Things like @RolesAllowed and Servlet security constraints won't work with the "dynamic" roles.

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.

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. 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). JASPIC should always be mandated, even outside Jakarta EE containers.
- 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.
- 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.
- CDI: deprecate Principal injection and delegate its obtention to SecurityContext#getCallerPrincipal.

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

What do you all think about this? Do you think this is worth pushing other specs to work on?


Regards,

Guillermo González de Agüero
_______________________________________________
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
_______________________________________________
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