Discussion: SecurityContext


Will Hopkins
 

I'd like to start a thread to discuss some issues related to SecurityContext.

The first, and most important, in my view, is how it's structured. I originally understood SecurityContext to be an API that was available everywhere (or at least in most containers), providing a set of common APIs that would be useful/usable everywhere. However, it now has a number of Servlet-specific methods on it.

I'm not against having container-specific functionality. We want this to be useful, and different containers have different security needs/behaviors. But as it stands now, the implementation is inelegant, at the very least. We want things to be simple and useful, but that doesn't mean we shouldn't follow OOP practices.

I think SecurityContext should either be refactored into a base/abstract class containing truly common methods, and container-specific sub-classes for container-specific behavior, or we should make the existing methods generic enough that they are applicable everywhere.

The latter approach involves substantially more change, obviously, but the idea would be to, e.g., write a generic hasAccessToResource(Resource r) method to replace the existing hasAccessToWebResource() methods. We could consider leaving authenticate the way it is, since it would be much harder to provide in a generic way.

Personally, I like the base-class/sub-class better -- it's simpler to achieve, and allows for container-specific behaviors. It requires little of developers other than being aware of what container their code is running in, if they want to use container-specific behavior. It's still essentially a common interface, but where we have container-specific behavior it's implemented in an OOP way.

Another issue is somewhat related. As currently spec'd, SecurityContext is REQUIRED only in servlet and ejb containers, but containers MAY provide it in other containers. There has been feedback that it should be available in all containers. I'm open to having it in more containers, but I think the set of containers needs to be enumerated, and for each enumerated container there needs to be a known, portable way to implement the required functionality, and an implementation in soteria. Otherwise, we're just imposing a somewhat arbitrary (all containers), and potentially difficult, implementation on container vendors.

Anybody want to sign up to enumerate the containers, and figure out which methods make sense in which containers? The only one that seems truly universal is getCallerPrincipal().

Thanks,

Will

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


Werner Keil
 

Will,

The interface has a couple of imports, javax.ejb.SessionContext only seems to come from JavaDoc. Maybe it should be removed as JavaDoc will work without it. There is no use of it by any method. 

I'm not sure, if it was a good idea to turn the interface into an abstract class, but what http://docs.oracle.com/javaee/7/api/javax/servlet/ServletRequest.html itself shows is a sub-interface like http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html. Either this way or via implementing classes (unless an abstract class is really seen much better, some APIs like CDI have just a small number of classes) some methods like

AuthenticationStatus authenticate(HttpServletRequest request, HttpServletResponse response, AuthenticationParameters parameters);
could be factored out specific to Servlet containers.


Plus 
boolean hasAccessToWebResource(String resource);
in its current form. There is no reference to the Servlet spec, but the JavaDoc and method name are tightly coupled to the Servlet spec. 
I asked Arjan earlier if this could be made more generic in the sense of 
boolean hasAccessToResource(String resource);

plus a different wording in the JavaDoc or using Servlet and other cases only as examples.
The term "resource" is crucial to REST (http://restful-api-design.readthedocs.io/en/latest/resources.html), so I am sure, JAX-RS and RESTful Web Services would also benefit from using this JSR, but the wording "section 13.8 of the Servlet specification" is so tightly coupled to the Servlet standard, that at least it does not seem easy to apply it to other kinds of resources.

If that's the case, this method should probably go into a Servlet specific interface or class. Otherwise please let's try to name and document it in a way that does not tie it to a single implementation or container.

Kind Regards,
Werner


Arjan Tijms
 

Hi,

On Wed, May 31, 2017 at 12:31 PM, Werner Keil <werner.keil@...> wrote:

If that's the case, this method should probably go into a Servlet specific interface or class. Otherwise please let's try to name and document it in a way that does not tie it to a single implementation or container.


Do note that while the method gives an outcome for a Servlet container resource, it should be perfectly valid to query it from any other containers.

E.g. an EJB bean composing an email message on behalf of a caller with an http link in that email.

Kind regards,
Arjan Tijms

 


Kind Regards,
Werner



Guillermo González de Agüero
 

Hi,

If this needs to be changed, I'd go for a mixed approach:
- On one hand, the split into a generic base+container specific classes is a flexible idea, but has the potential problem that Arjan explained: users in need of multiple container specific classes. Forcing them to inject multiple security contexts would be very uggly.
- On the other hand, the "generic methods" approach usually ends in too abstract solutions that are hard to use.

But what if we add a new hasPermission(Permission) method to a base SecurityContext...

public class SecurityContext {
    public boolean hasPermission(Permission permission) {
         // ...
    }
}


And Servlet specific features are moved to a new ServletSecurityContext:

public class ServletSecurityContext extends SecurityContext {
        public boolean hasAccessToWebResource(String url, String ...methods) {
            return hasPermission(new WebResourcePermission(url, methods));
        }
}


This would reduce the need for the container specific classes by providing generic enough features on the base SecurityContext, while the specific ones will be simpler to use.

What do you all think about this?


More responses inline:

On Wed, May 31, 2017 at 3:38 AM, Will Hopkins <will.hopkins@...> wrote:
I'd like to start a thread to discuss some issues related to SecurityContext.

The first, and most important, in my view, is how it's structured. I originally understood SecurityContext to be an API that was available everywhere (or at least in most containers), providing a set of common APIs that would be useful/usable everywhere. However, it now has a number of Servlet-specific methods on it.

I'm not against having container-specific functionality. We want this to be useful, and different containers have different security needs/behaviors. But as it stands now, the implementation is inelegant, at the very least. We want things to be simple and useful, but that doesn't mean we shouldn't follow OOP practices.

I think SecurityContext should either be refactored into a base/abstract class containing truly common methods, and container-specific sub-classes for container-specific behavior, or we should make the existing methods generic enough that they are applicable everywhere.

The latter approach involves substantially more change, obviously, but the idea would be to, e.g., write a generic hasAccessToResource(Resource r) method to replace the existing hasAccessToWebResource() methods. We could consider leaving authenticate the way it is, since it would be much harder to provide in a generic way.

Personally, I like the base-class/sub-class better -- it's simpler to achieve, and allows for container-specific behaviors. It requires little of developers other than being aware of what container their code is running in, if they want to use container-specific behavior. It's still essentially a common interface, but where we have container-specific behavior it's implemented in an OOP way.

Another issue is somewhat related. As currently spec'd, SecurityContext is REQUIRED only in servlet and ejb containers, but containers MAY provide it in other containers. There has been feedback that it should be available in all containers. I'm open to having it in more containers, but I think the set of containers needs to be enumerated, and for each enumerated container there needs to be a known, portable way to implement the required functionality, and an implementation in soteria. Otherwise, we're just imposing a somewhat arbitrary (all containers), and potentially difficult, implementation on container vendors.
I understand.

 Btw, what's the full list of Java EE Containers? The Java EE tutorial taks about four of them:
- EJB container
- Servlet container
- Application client container
- Applet container

JAX-RS for example is not listed as a container, but I'd expect the SecurityContext to work there. Of course, the majority of JAX-RS implementations are built on top of a Servlet, but I don't know if it is mandated to work that way when running on Java EE. I'm not sure if JAX-WS is in a similar situation.

 

Anybody want to sign up to enumerate the containers, and figure out which methods make sense in which containers? The only one that seems truly universal is getCallerPrincipal().

Thanks,

Will

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

Regards,


Mark Struberg
 

No, this would not remove the need for a customer specific Principal imo.

Permissions alon are _not_ enough in most real world cases.

Again, think about a multi tenant system etc.

LieGrue,
strub

Am 31.05.2017 um 18:03 schrieb Guillermo González de Agüero <z06.guillermo@gmail.com>:

Hi,

If this needs to be changed, I'd go for a mixed approach:
- On one hand, the split into a generic base+container specific classes is a flexible idea, but has the potential problem that Arjan explained: users in need of multiple container specific classes. Forcing them to inject multiple security contexts would be very uggly.
- On the other hand, the "generic methods" approach usually ends in too abstract solutions that are hard to use.

But what if we add a new hasPermission(Permission) method to a base SecurityContext...

public class SecurityContext {
public boolean hasPermission(Permission permission) {
// ...
}
}


And Servlet specific features are moved to a new ServletSecurityContext:

public class ServletSecurityContext extends SecurityContext {
public boolean hasAccessToWebResource(String url, String ...methods) {
return hasPermission(new WebResourcePermission(url, methods));
}
}

This would reduce the need for the container specific classes by providing generic enough features on the base SecurityContext, while the specific ones will be simpler to use.

What do you all think about this?


More responses inline:

On Wed, May 31, 2017 at 3:38 AM, Will Hopkins <will.hopkins@oracle.com> wrote:
I'd like to start a thread to discuss some issues related to SecurityContext.

The first, and most important, in my view, is how it's structured. I originally understood SecurityContext to be an API that was available everywhere (or at least in most containers), providing a set of common APIs that would be useful/usable everywhere. However, it now has a number of Servlet-specific methods on it.

I'm not against having container-specific functionality. We want this to be useful, and different containers have different security needs/behaviors. But as it stands now, the implementation is inelegant, at the very least. We want things to be simple and useful, but that doesn't mean we shouldn't follow OOP practices.

I think SecurityContext should either be refactored into a base/abstract class containing truly common methods, and container-specific sub-classes for container-specific behavior, or we should make the existing methods generic enough that they are applicable everywhere.

The latter approach involves substantially more change, obviously, but the idea would be to, e.g., write a generic hasAccessToResource(Resource r) method to replace the existing hasAccessToWebResource() methods. We could consider leaving authenticate the way it is, since it would be much harder to provide in a generic way.

Personally, I like the base-class/sub-class better -- it's simpler to achieve, and allows for container-specific behaviors. It requires little of developers other than being aware of what container their code is running in, if they want to use container-specific behavior. It's still essentially a common interface, but where we have container-specific behavior it's implemented in an OOP way.

Another issue is somewhat related. As currently spec'd, SecurityContext is REQUIRED only in servlet and ejb containers, but containers MAY provide it in other containers. There has been feedback that it should be available in all containers. I'm open to having it in more containers, but I think the set of containers needs to be enumerated, and for each enumerated container there needs to be a known, portable way to implement the required functionality, and an implementation in soteria. Otherwise, we're just imposing a somewhat arbitrary (all containers), and potentially difficult, implementation on container vendors.
I understand.

Btw, what's the full list of Java EE Containers? The Java EE tutorial taks about four of them:
- EJB container
- Servlet container
- Application client container
- Applet container

JAX-RS for example is not listed as a container, but I'd expect the SecurityContext to work there. Of course, the majority of JAX-RS implementations are built on top of a Servlet, but I don't know if it is mandated to work that way when running on Java EE. I'm not sure if JAX-WS is in a similar situation.



Anybody want to sign up to enumerate the containers, and figure out which methods make sense in which containers? The only one that seems truly universal is getCallerPrincipal().

Thanks,

Will

--
Will Hopkins | WebLogic Security Architect |
+1.781.442.0310

Oracle Application Development
35 Network Drive, Burlington, MA 01803




Regards,

Guillermo González de Agüero

[1] https://docs.oracle.com/javaee/7/tutorial/overview004.htm


Arjan Tijms
 

Hi,

I think if we split out we're basically undoing what the SecurityContext is aiming for; a one step entry point. Splitting things out has already been done. That's the JAX-RS SecurityContext, and the EJB SessionContext and what have you.

hasAccessToWebResource with a generic hasAccessToResource does sound nice, but don't forget that hasAccessToWebResource can also be called from other "containers".

JAX-RS is indeed not its own container. I have to double check, but I think in Java EE it must work with Servlet, and only outside Java EE is it allowed to build on something else (which is practice as far as I know has never really happened, apart from some very experimental code).

The entire idea of a container in the traditional sense is also fading away largely, so I'm not sure we really have to design for that tbh. EJB should eventually be completely replaced by CDI + various interceptors. Shame not more steps for that were taken this cycle.

There is the concept of security inflow though. A Java EE server can be entered via a JCA connector as well, of which the JMS connector tied to a MDB is a specific case. JCA has some interested security aspects as well, and even uses some JASPIC types.

Kind regards,
Arjan Tijms




On Wed, May 31, 2017 at 6:03 PM, Guillermo González de Agüero <z06.guillermo@...> wrote:
Hi,

If this needs to be changed, I'd go for a mixed approach:
- On one hand, the split into a generic base+container specific classes is a flexible idea, but has the potential problem that Arjan explained: users in need of multiple container specific classes. Forcing them to inject multiple security contexts would be very uggly.
- On the other hand, the "generic methods" approach usually ends in too abstract solutions that are hard to use.

But what if we add a new hasPermission(Permission) method to a base SecurityContext...

public class SecurityContext {
    public boolean hasPermission(Permission permission) {
         // ...
    }
}


And Servlet specific features are moved to a new ServletSecurityContext:

public class ServletSecurityContext extends SecurityContext {
        public boolean hasAccessToWebResource(String url, String ...methods) {
            return hasPermission(new WebResourcePermission(url, methods));
        }
}


This would reduce the need for the container specific classes by providing generic enough features on the base SecurityContext, while the specific ones will be simpler to use.

What do you all think about this?


More responses inline:

On Wed, May 31, 2017 at 3:38 AM, Will Hopkins <will.hopkins@...> wrote:
I'd like to start a thread to discuss some issues related to SecurityContext.

The first, and most important, in my view, is how it's structured. I originally understood SecurityContext to be an API that was available everywhere (or at least in most containers), providing a set of common APIs that would be useful/usable everywhere. However, it now has a number of Servlet-specific methods on it.

I'm not against having container-specific functionality. We want this to be useful, and different containers have different security needs/behaviors. But as it stands now, the implementation is inelegant, at the very least. We want things to be simple and useful, but that doesn't mean we shouldn't follow OOP practices.

I think SecurityContext should either be refactored into a base/abstract class containing truly common methods, and container-specific sub-classes for container-specific behavior, or we should make the existing methods generic enough that they are applicable everywhere.

The latter approach involves substantially more change, obviously, but the idea would be to, e.g., write a generic hasAccessToResource(Resource r) method to replace the existing hasAccessToWebResource() methods. We could consider leaving authenticate the way it is, since it would be much harder to provide in a generic way.

Personally, I like the base-class/sub-class better -- it's simpler to achieve, and allows for container-specific behaviors. It requires little of developers other than being aware of what container their code is running in, if they want to use container-specific behavior. It's still essentially a common interface, but where we have container-specific behavior it's implemented in an OOP way.

Another issue is somewhat related. As currently spec'd, SecurityContext is REQUIRED only in servlet and ejb containers, but containers MAY provide it in other containers. There has been feedback that it should be available in all containers. I'm open to having it in more containers, but I think the set of containers needs to be enumerated, and for each enumerated container there needs to be a known, portable way to implement the required functionality, and an implementation in soteria. Otherwise, we're just imposing a somewhat arbitrary (all containers), and potentially difficult, implementation on container vendors.
I understand.

 Btw, what's the full list of Java EE Containers? The Java EE tutorial taks about four of them:
- EJB container
- Servlet container
- Application client container
- Applet container

JAX-RS for example is not listed as a container, but I'd expect the SecurityContext to work there. Of course, the majority of JAX-RS implementations are built on top of a Servlet, but I don't know if it is mandated to work that way when running on Java EE. I'm not sure if JAX-WS is in a similar situation.

 

Anybody want to sign up to enumerate the containers, and figure out which methods make sense in which containers? The only one that seems truly universal is getCallerPrincipal().

Thanks,

Will

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

Regards,



Guillermo González de Agüero
 

Hi Mark,

The need for the custom principal is clear to me ;)

My comments were just regarding Will proposal to refactor the SecurityContext class.


Regards,

Guillermo González de Agüero

Guillermo González de Agüero

On Wed, May 31, 2017 at 6:14 PM, Mark Struberg via Groups.Io <struberg@...> wrote:
No, this would not remove the need for a customer specific Principal imo.

Permissions alon are _not_ enough in most real world cases.

Again, think about a multi tenant system etc.

LieGrue,
strub

> Am 31.05.2017 um 18:03 schrieb Guillermo González de Agüero <z06.guillermo@...>:
>
> Hi,
>
> If this needs to be changed, I'd go for a mixed approach:
> - On one hand, the split into a generic base+container specific classes is a flexible idea, but has the potential problem that Arjan explained: users in need of multiple container specific classes. Forcing them to inject multiple security contexts would be very uggly.
> - On the other hand, the "generic methods" approach usually ends in too abstract solutions that are hard to use.
>
> But what if we add a new hasPermission(Permission) method to a base SecurityContext...
>
> public class SecurityContext {
>     public boolean hasPermission(Permission permission) {
>          // ...
>     }
> }
>
>
> And Servlet specific features are moved to a new ServletSecurityContext:
>
> public class ServletSecurityContext extends SecurityContext {
>         public boolean hasAccessToWebResource(String url, String ...methods) {
>             return hasPermission(new WebResourcePermission(url, methods));
>         }
> }
>
> This would reduce the need for the container specific classes by providing generic enough features on the base SecurityContext, while the specific ones will be simpler to use.
>
> What do you all think about this?
>
>
> More responses inline:
>
> On Wed, May 31, 2017 at 3:38 AM, Will Hopkins <will.hopkins@...> wrote:
> I'd like to start a thread to discuss some issues related to SecurityContext.
>
> The first, and most important, in my view, is how it's structured. I originally understood SecurityContext to be an API that was available everywhere (or at least in most containers), providing a set of common APIs that would be useful/usable everywhere. However, it now has a number of Servlet-specific methods on it.
>
> I'm not against having container-specific functionality. We want this to be useful, and different containers have different security needs/behaviors. But as it stands now, the implementation is inelegant, at the very least. We want things to be simple and useful, but that doesn't mean we shouldn't follow OOP practices.
>
> I think SecurityContext should either be refactored into a base/abstract class containing truly common methods, and container-specific sub-classes for container-specific behavior, or we should make the existing methods generic enough that they are applicable everywhere.
>
> The latter approach involves substantially more change, obviously, but the idea would be to, e.g., write a generic hasAccessToResource(Resource r) method to replace the existing hasAccessToWebResource() methods. We could consider leaving authenticate the way it is, since it would be much harder to provide in a generic way.
>
> Personally, I like the base-class/sub-class better -- it's simpler to achieve, and allows for container-specific behaviors. It requires little of developers other than being aware of what container their code is running in, if they want to use container-specific behavior. It's still essentially a common interface, but where we have container-specific behavior it's implemented in an OOP way.
>
> Another issue is somewhat related. As currently spec'd, SecurityContext is REQUIRED only in servlet and ejb containers, but containers MAY provide it in other containers. There has been feedback that it should be available in all containers. I'm open to having it in more containers, but I think the set of containers needs to be enumerated, and for each enumerated container there needs to be a known, portable way to implement the required functionality, and an implementation in soteria. Otherwise, we're just imposing a somewhat arbitrary (all containers), and potentially difficult, implementation on container vendors.
> I understand.
>
>  Btw, what's the full list of Java EE Containers? The Java EE tutorial taks about four of them:
> - EJB container
> - Servlet container
> - Application client container
> - Applet container
>
> JAX-RS for example is not listed as a container, but I'd expect the SecurityContext to work there. Of course, the majority of JAX-RS implementations are built on top of a Servlet, but I don't know if it is mandated to work that way when running on Java EE. I'm not sure if JAX-WS is in a similar situation.
>
>
>
> Anybody want to sign up to enumerate the containers, and figure out which methods make sense in which containers? The only one that seems truly universal is getCallerPrincipal().
>
> Thanks,
>
> Will
>
> --
> Will Hopkins | WebLogic Security Architect |
> +1.781.442.0310
>
> Oracle Application Development
> 35 Network Drive, Burlington, MA 01803
>
>
>
>
> Regards,
>
> Guillermo González de Agüero
>
> [1] https://docs.oracle.com/javaee/7/tutorial/overview004.htm
>






Mark Struberg
 

Yes sorry, didn't git it that there are 2 Threads which are coverying very similar - albeit different - things.

LieGrue,
strub

Am 31.05.2017 um 18:22 schrieb Guillermo González de Agüero <z06.guillermo@gmail.com>:

Hi Mark,

The need for the custom principal is clear to me ;)

My comments were just regarding Will proposal to refactor the SecurityContext class.


Regards,

Guillermo González de Agüero

Guillermo González de Agüero

On Wed, May 31, 2017 at 6:14 PM, Mark Struberg via Groups.Io <struberg=yahoo.de@groups.io> wrote:
No, this would not remove the need for a customer specific Principal imo.

Permissions alon are _not_ enough in most real world cases.

Again, think about a multi tenant system etc.

LieGrue,
strub

Am 31.05.2017 um 18:03 schrieb Guillermo González de Agüero <z06.guillermo@gmail.com>:

Hi,

If this needs to be changed, I'd go for a mixed approach:
- On one hand, the split into a generic base+container specific classes is a flexible idea, but has the potential problem that Arjan explained: users in need of multiple container specific classes. Forcing them to inject multiple security contexts would be very uggly.
- On the other hand, the "generic methods" approach usually ends in too abstract solutions that are hard to use.

But what if we add a new hasPermission(Permission) method to a base SecurityContext...

public class SecurityContext {
public boolean hasPermission(Permission permission) {
// ...
}
}


And Servlet specific features are moved to a new ServletSecurityContext:

public class ServletSecurityContext extends SecurityContext {
public boolean hasAccessToWebResource(String url, String ...methods) {
return hasPermission(new WebResourcePermission(url, methods));
}
}

This would reduce the need for the container specific classes by providing generic enough features on the base SecurityContext, while the specific ones will be simpler to use.

What do you all think about this?


More responses inline:

On Wed, May 31, 2017 at 3:38 AM, Will Hopkins <will.hopkins@oracle.com> wrote:
I'd like to start a thread to discuss some issues related to SecurityContext.

The first, and most important, in my view, is how it's structured. I originally understood SecurityContext to be an API that was available everywhere (or at least in most containers), providing a set of common APIs that would be useful/usable everywhere. However, it now has a number of Servlet-specific methods on it.

I'm not against having container-specific functionality. We want this to be useful, and different containers have different security needs/behaviors. But as it stands now, the implementation is inelegant, at the very least. We want things to be simple and useful, but that doesn't mean we shouldn't follow OOP practices.

I think SecurityContext should either be refactored into a base/abstract class containing truly common methods, and container-specific sub-classes for container-specific behavior, or we should make the existing methods generic enough that they are applicable everywhere.

The latter approach involves substantially more change, obviously, but the idea would be to, e.g., write a generic hasAccessToResource(Resource r) method to replace the existing hasAccessToWebResource() methods. We could consider leaving authenticate the way it is, since it would be much harder to provide in a generic way.

Personally, I like the base-class/sub-class better -- it's simpler to achieve, and allows for container-specific behaviors. It requires little of developers other than being aware of what container their code is running in, if they want to use container-specific behavior. It's still essentially a common interface, but where we have container-specific behavior it's implemented in an OOP way.

Another issue is somewhat related. As currently spec'd, SecurityContext is REQUIRED only in servlet and ejb containers, but containers MAY provide it in other containers. There has been feedback that it should be available in all containers. I'm open to having it in more containers, but I think the set of containers needs to be enumerated, and for each enumerated container there needs to be a known, portable way to implement the required functionality, and an implementation in soteria. Otherwise, we're just imposing a somewhat arbitrary (all containers), and potentially difficult, implementation on container vendors.
I understand.

Btw, what's the full list of Java EE Containers? The Java EE tutorial taks about four of them:
- EJB container
- Servlet container
- Application client container
- Applet container

JAX-RS for example is not listed as a container, but I'd expect the SecurityContext to work there. Of course, the majority of JAX-RS implementations are built on top of a Servlet, but I don't know if it is mandated to work that way when running on Java EE. I'm not sure if JAX-WS is in a similar situation.



Anybody want to sign up to enumerate the containers, and figure out which methods make sense in which containers? The only one that seems truly universal is getCallerPrincipal().

Thanks,

Will

--
Will Hopkins | WebLogic Security Architect |
+1.781.442.0310

Oracle Application Development
35 Network Drive, Burlington, MA 01803




Regards,

Guillermo González de Agüero

[1] https://docs.oracle.com/javaee/7/tutorial/overview004.htm





reza_rahman@...
 

It is indeed a shame we didn't do more to step away from EJB in Java EE 7 and Java EE 8. One thing I was hoping would come out of this JSR is interceptor versions of @RolesAllowed, etc.

-------- Original message --------
From: Arjan Tijms <arjan.tijms@...>
Date: 5/31/17 12:20 PM (GMT-05:00)
To: javaee-security-spec@javaee.groups.io
Subject: Re: [javaee-security-spec] Discussion: SecurityContext

Hi,

I think if we split out we're basically undoing what the SecurityContext is aiming for; a one step entry point. Splitting things out has already been done. That's the JAX-RS SecurityContext, and the EJB SessionContext and what have you.

hasAccessToWebResource with a generic hasAccessToResource does sound nice, but don't forget that hasAccessToWebResource can also be called from other "containers".

JAX-RS is indeed not its own container. I have to double check, but I think in Java EE it must work with Servlet, and only outside Java EE is it allowed to build on something else (which is practice as far as I know has never really happened, apart from some very experimental code).

The entire idea of a container in the traditional sense is also fading away largely, so I'm not sure we really have to design for that tbh. EJB should eventually be completely replaced by CDI + various interceptors. Shame not more steps for that were taken this cycle.

There is the concept of security inflow though. A Java EE server can be entered via a JCA connector as well, of which the JMS connector tied to a MDB is a specific case. JCA has some interested security aspects as well, and even uses some JASPIC types.

Kind regards,
Arjan Tijms




On Wed, May 31, 2017 at 6:03 PM, Guillermo González de Agüero <z06.guillermo@...> wrote:
Hi,

If this needs to be changed, I'd go for a mixed approach:
- On one hand, the split into a generic base+container specific classes is a flexible idea, but has the potential problem that Arjan explained: users in need of multiple container specific classes. Forcing them to inject multiple security contexts would be very uggly.
- On the other hand, the "generic methods" approach usually ends in too abstract solutions that are hard to use.

But what if we add a new hasPermission(Permission) method to a base SecurityContext...

public class SecurityContext {
    public boolean hasPermission(Permission permission) {
         // ...
    }
}


And Servlet specific features are moved to a new ServletSecurityContext:

public class ServletSecurityContext extends SecurityContext {
        public boolean hasAccessToWebResource(String url, String ...methods) {
            return hasPermission(new WebResourcePermission(url, methods));
        }
}


This would reduce the need for the container specific classes by providing generic enough features on the base SecurityContext, while the specific ones will be simpler to use.

What do you all think about this?


More responses inline:

On Wed, May 31, 2017 at 3:38 AM, Will Hopkins <will.hopkins@...> wrote:
I'd like to start a thread to discuss some issues related to SecurityContext.

The first, and most important, in my view, is how it's structured. I originally understood SecurityContext to be an API that was available everywhere (or at least in most containers), providing a set of common APIs that would be useful/usable everywhere. However, it now has a number of Servlet-specific methods on it.

I'm not against having container-specific functionality. We want this to be useful, and different containers have different security needs/behaviors. But as it stands now, the implementation is inelegant, at the very least. We want things to be simple and useful, but that doesn't mean we shouldn't follow OOP practices.

I think SecurityContext should either be refactored into a base/abstract class containing truly common methods, and container-specific sub-classes for container-specific behavior, or we should make the existing methods generic enough that they are applicable everywhere.

The latter approach involves substantially more change, obviously, but the idea would be to, e.g., write a generic hasAccessToResource(Resource r) method to replace the existing hasAccessToWebResource() methods. We could consider leaving authenticate the way it is, since it would be much harder to provide in a generic way.

Personally, I like the base-class/sub-class better -- it's simpler to achieve, and allows for container-specific behaviors. It requires little of developers other than being aware of what container their code is running in, if they want to use container-specific behavior. It's still essentially a common interface, but where we have container-specific behavior it's implemented in an OOP way.

Another issue is somewhat related. As currently spec'd, SecurityContext is REQUIRED only in servlet and ejb containers, but containers MAY provide it in other containers. There has been feedback that it should be available in all containers. I'm open to having it in more containers, but I think the set of containers needs to be enumerated, and for each enumerated container there needs to be a known, portable way to implement the required functionality, and an implementation in soteria. Otherwise, we're just imposing a somewhat arbitrary (all containers), and potentially difficult, implementation on container vendors.
I understand.

 Btw, what's the full list of Java EE Containers? The Java EE tutorial taks about four of them:
- EJB container
- Servlet container
- Application client container
- Applet container

JAX-RS for example is not listed as a container, but I'd expect the SecurityContext to work there. Of course, the majority of JAX-RS implementations are built on top of a Servlet, but I don't know if it is mandated to work that way when running on Java EE. I'm not sure if JAX-WS is in a similar situation.

 

Anybody want to sign up to enumerate the containers, and figure out which methods make sense in which containers? The only one that seems truly universal is getCallerPrincipal().

Thanks,

Will

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

Regards,



Arjan Tijms
 

Hi,

On Wed, May 31, 2017 at 6:33 PM, reza_rahman <reza_rahman@...> wrote:
It is indeed a shame we didn't do more to step away from EJB in Java EE 7 and Java EE 8. One thing I was hoping would come out of this JSR is interceptor versions of @RolesAllowed, etc.

Absolutely, still not sure how something relatively simple as @RolesAllowed did not get in. Contributing factors were of course low amount of resources, time spend on other things including things that eventually did not get in (like the authorization rules), and some confusion about nothing new that could be added anymore even before the EDR was published.

RoleMapper, as mentioned, is another thing that I really wanted to get in, and simple (CDI) events like AuthenticatedEvent and LoggedOutEvent etc.

Kind regards,
Arjan Tijms

 

-------- Original message --------
From: Arjan Tijms <arjan.tijms@...>
Date: 5/31/17 12:20 PM (GMT-05:00)
Subject: Re: [javaee-security-spec] Discussion: SecurityContext

Hi,

I think if we split out we're basically undoing what the SecurityContext is aiming for; a one step entry point. Splitting things out has already been done. That's the JAX-RS SecurityContext, and the EJB SessionContext and what have you.

hasAccessToWebResource with a generic hasAccessToResource does sound nice, but don't forget that hasAccessToWebResource can also be called from other "containers".

JAX-RS is indeed not its own container. I have to double check, but I think in Java EE it must work with Servlet, and only outside Java EE is it allowed to build on something else (which is practice as far as I know has never really happened, apart from some very experimental code).

The entire idea of a container in the traditional sense is also fading away largely, so I'm not sure we really have to design for that tbh. EJB should eventually be completely replaced by CDI + various interceptors. Shame not more steps for that were taken this cycle.

There is the concept of security inflow though. A Java EE server can be entered via a JCA connector as well, of which the JMS connector tied to a MDB is a specific case. JCA has some interested security aspects as well, and even uses some JASPIC types.

Kind regards,
Arjan Tijms




On Wed, May 31, 2017 at 6:03 PM, Guillermo González de Agüero <z06.guillermo@...> wrote:
Hi,

If this needs to be changed, I'd go for a mixed approach:
- On one hand, the split into a generic base+container specific classes is a flexible idea, but has the potential problem that Arjan explained: users in need of multiple container specific classes. Forcing them to inject multiple security contexts would be very uggly.
- On the other hand, the "generic methods" approach usually ends in too abstract solutions that are hard to use.

But what if we add a new hasPermission(Permission) method to a base SecurityContext...

public class SecurityContext {
    public boolean hasPermission(Permission permission) {
         // ...
    }
}


And Servlet specific features are moved to a new ServletSecurityContext:

public class ServletSecurityContext extends SecurityContext {
        public boolean hasAccessToWebResource(String url, String ...methods) {
            return hasPermission(new WebResourcePermission(url, methods));
        }
}


This would reduce the need for the container specific classes by providing generic enough features on the base SecurityContext, while the specific ones will be simpler to use.

What do you all think about this?


More responses inline:

On Wed, May 31, 2017 at 3:38 AM, Will Hopkins <will.hopkins@...> wrote:
I'd like to start a thread to discuss some issues related to SecurityContext.

The first, and most important, in my view, is how it's structured. I originally understood SecurityContext to be an API that was available everywhere (or at least in most containers), providing a set of common APIs that would be useful/usable everywhere. However, it now has a number of Servlet-specific methods on it.

I'm not against having container-specific functionality. We want this to be useful, and different containers have different security needs/behaviors. But as it stands now, the implementation is inelegant, at the very least. We want things to be simple and useful, but that doesn't mean we shouldn't follow OOP practices.

I think SecurityContext should either be refactored into a base/abstract class containing truly common methods, and container-specific sub-classes for container-specific behavior, or we should make the existing methods generic enough that they are applicable everywhere.

The latter approach involves substantially more change, obviously, but the idea would be to, e.g., write a generic hasAccessToResource(Resource r) method to replace the existing hasAccessToWebResource() methods. We could consider leaving authenticate the way it is, since it would be much harder to provide in a generic way.

Personally, I like the base-class/sub-class better -- it's simpler to achieve, and allows for container-specific behaviors. It requires little of developers other than being aware of what container their code is running in, if they want to use container-specific behavior. It's still essentially a common interface, but where we have container-specific behavior it's implemented in an OOP way.

Another issue is somewhat related. As currently spec'd, SecurityContext is REQUIRED only in servlet and ejb containers, but containers MAY provide it in other containers. There has been feedback that it should be available in all containers. I'm open to having it in more containers, but I think the set of containers needs to be enumerated, and for each enumerated container there needs to be a known, portable way to implement the required functionality, and an implementation in soteria. Otherwise, we're just imposing a somewhat arbitrary (all containers), and potentially difficult, implementation on container vendors.
I understand.

 Btw, what's the full list of Java EE Containers? The Java EE tutorial taks about four of them:
- EJB container
- Servlet container
- Application client container
- Applet container

JAX-RS for example is not listed as a container, but I'd expect the SecurityContext to work there. Of course, the majority of JAX-RS implementations are built on top of a Servlet, but I don't know if it is mandated to work that way when running on Java EE. I'm not sure if JAX-WS is in a similar situation.

 

Anybody want to sign up to enumerate the containers, and figure out which methods make sense in which containers? The only one that seems truly universal is getCallerPrincipal().

Thanks,

Will

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

Regards,




Bill Shannon
 

Arjan Tijms wrote on 05/31/17 03:41 AM:
Hi,

On Wed, May 31, 2017 at 12:31 PM, Werner Keil <werner.keil@...> wrote:

If that's the case, this method should probably go into a Servlet specific interface or class. Otherwise please let's try to name and document it in a way that does not tie it to a single implementation or container.


Do note that while the method gives an outcome for a Servlet container resource, it should be perfectly valid to query it from any other containers.

E.g. an EJB bean composing an email message on behalf of a caller with an http link in that email.
I assume this is about hasAccessToWebResource...

As I read the spec, the resource name is relative to the web module.  If you're not in a web container, what names can you use?  If your app has two war files, which web module is the name relative to?  Presumably the one you're running in, which means it's not useful if you're not running in a web container.  Well, unless the EJB module is exposing web services of some sort.


Arjan Tijms
 

Hi,

On Thu, Jun 1, 2017 at 12:28 AM, Bill Shannon <bill.shannon@...> wrote:
As I read the spec, the resource name is relative to the web module.  If you're not in a web container, what names can you use?  If your app has two war files, which web module is the name relative to?  Presumably the one you're running in, which means it's not useful if you're not running in a web container.  Well, unless the EJB module is exposing web services of some sort.

You're absolutely right, good catch!

Okay, I was wrong here then. When called from another container or "entry point" into the application (not sure what you would call inflow into a JCA connector exactly), you cannot just call that method.

For a next spec release I could imagine a JNDI like namespace prefix, with java:app/[module name] querying for a specific module in the application and java:module being the default for the current module (which would then throw an IllegalArgumentException if called from an EJB module).

E.g.

From an EJB:

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2

/admin
java:module/admin

Throws IllegalArgumentException 

----

From web module app1

/admin
java:module/admin

Queries for /admin for app1, where /admin must be treated equal to java:module/admin

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2, where java:app/app1/admin must be treated equal to java:module/admin

Thoughts?

Kind regards,
Arjan Tijms




 



Bill Shannon
 

Using JNDI-style names for resource names would be confusing.

What's the use case for this method in general, and for using this method with a resource that's in another module?

Arjan Tijms wrote on 05/31/17 03:51 PM:

Hi,

On Thu, Jun 1, 2017 at 12:28 AM, Bill Shannon <bill.shannon@...> wrote:
As I read the spec, the resource name is relative to the web module.  If you're not in a web container, what names can you use?  If your app has two war files, which web module is the name relative to?  Presumably the one you're running in, which means it's not useful if you're not running in a web container.  Well, unless the EJB module is exposing web services of some sort.

You're absolutely right, good catch!

Okay, I was wrong here then. When called from another container or "entry point" into the application (not sure what you would call inflow into a JCA connector exactly), you cannot just call that method.

For a next spec release I could imagine a JNDI like namespace prefix, with java:app/[module name] querying for a specific module in the application and java:module being the default for the current module (which would then throw an IllegalArgumentException if called from an EJB module).

E.g.

From an EJB:

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2

/admin
java:module/admin

Throws IllegalArgumentException 

----

From web module app1

/admin
java:module/admin

Queries for /admin for app1, where /admin must be treated equal to java:module/admin

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2, where java:app/app1/admin must be treated equal to java:module/admin

Thoughts?

Kind regards,
Arjan Tijms




 




Arjan Tijms
 

Hi,

The general use case for the method is letting the application find out whether a caller has access to certain resources and (mainly) adjusting rendering of links based on that.

A specific use case of this is dynamically rendering a menu with links to pages present in an application, based on what a user is allowed to access. Menu entries could be entirely omitted (so the user only sees entries to pages that are accessible, a common case), or could be rendered differently (say in red, or with a lock symbol next to it).

An extremely simplified example of this can be seen in a small demo app we did here: 


When menus are a little bit more sophisticated, there's often a need to know upfront about entire patterns of pages, for example when testing for /admin/* fails we can omit the entire admin sub header including introduction text. Otherwise we would need to see if the user has access to at least one page.

Roles can be used, and they are in practice, but that assumes the rendering code has knowledge of which role corresponds to which resource, something which doesn't allows remain stable and then necessitates updating code at multiple locations.

A use case where the EJB module could use knowledge about this is as mentioned when sending out emails, which is often done from business services. Another one woud be where an EJB module calls an internal (rest) service. I agree that the EJB module needing to know about the web permissions would be far less common, and would even be more practical with a method that, as Will suggested earlier, also took a Principal as input (things like email sending often happens in batches and asynchronously).

A hasAccessTo is an existing method that has been in use with various frameworks in different forms for some time. One of these is our own OmniFaces project, where we have implemented this here in a slightly different variant:


Hope this made it more clear.

Kind regards,
Arjan Tijms









On Thu, Jun 1, 2017 at 1:02 AM, Bill Shannon <bill.shannon@...> wrote:
Using JNDI-style names for resource names would be confusing.

What's the use case for this method in general, and for using this method with a resource that's in another module?

Arjan Tijms wrote on 05/31/17 03:51 PM:
Hi,

On Thu, Jun 1, 2017 at 12:28 AM, Bill Shannon <bill.shannon@...> wrote:
As I read the spec, the resource name is relative to the web module.  If you're not in a web container, what names can you use?  If your app has two war files, which web module is the name relative to?  Presumably the one you're running in, which means it's not useful if you're not running in a web container.  Well, unless the EJB module is exposing web services of some sort.

You're absolutely right, good catch!

Okay, I was wrong here then. When called from another container or "entry point" into the application (not sure what you would call inflow into a JCA connector exactly), you cannot just call that method.

For a next spec release I could imagine a JNDI like namespace prefix, with java:app/[module name] querying for a specific module in the application and java:module being the default for the current module (which would then throw an IllegalArgumentException if called from an EJB module).

E.g.

From an EJB:

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2

/admin
java:module/admin

Throws IllegalArgumentException 

----

From web module app1

/admin
java:module/admin

Queries for /admin for app1, where /admin must be treated equal to java:module/admin

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2, where java:app/app1/admin must be treated equal to java:module/admin

Thoughts?

Kind regards,
Arjan Tijms




 





Bill Shannon
 

Using this across modules would introduce a tight coupling that probably isn't desirable.  Roles really do seem like a better approach in that case.  Or the module could provide an API that could be called to determine if the caller has "admin permission" or whatever needs to be tested to influence the behavior of the calling module.

Having a way for a web module to test whether access is allowed to one of the resources of that same web module seems fine.

Arjan Tijms wrote on 05/31/2017 04:34 PM:

Hi,

The general use case for the method is letting the application find out whether a caller has access to certain resources and (mainly) adjusting rendering of links based on that.

A specific use case of this is dynamically rendering a menu with links to pages present in an application, based on what a user is allowed to access. Menu entries could be entirely omitted (so the user only sees entries to pages that are accessible, a common case), or could be rendered differently (say in red, or with a lock symbol next to it).

An extremely simplified example of this can be seen in a small demo app we did here: 


When menus are a little bit more sophisticated, there's often a need to know upfront about entire patterns of pages, for example when testing for /admin/* fails we can omit the entire admin sub header including introduction text. Otherwise we would need to see if the user has access to at least one page.

Roles can be used, and they are in practice, but that assumes the rendering code has knowledge of which role corresponds to which resource, something which doesn't allows remain stable and then necessitates updating code at multiple locations.

A use case where the EJB module could use knowledge about this is as mentioned when sending out emails, which is often done from business services. Another one woud be where an EJB module calls an internal (rest) service. I agree that the EJB module needing to know about the web permissions would be far less common, and would even be more practical with a method that, as Will suggested earlier, also took a Principal as input (things like email sending often happens in batches and asynchronously).

A hasAccessTo is an existing method that has been in use with various frameworks in different forms for some time. One of these is our own OmniFaces project, where we have implemented this here in a slightly different variant:


Hope this made it more clear.

Kind regards,
Arjan Tijms









On Thu, Jun 1, 2017 at 1:02 AM, Bill Shannon <bill.shannon@...> wrote:
Using JNDI-style names for resource names would be confusing.

What's the use case for this method in general, and for using this method with a resource that's in another module?

Arjan Tijms wrote on 05/31/17 03:51 PM:
Hi,

On Thu, Jun 1, 2017 at 12:28 AM, Bill Shannon <bill.shannon@...> wrote:
As I read the spec, the resource name is relative to the web module.  If you're not in a web container, what names can you use?  If your app has two war files, which web module is the name relative to?  Presumably the one you're running in, which means it's not useful if you're not running in a web container.  Well, unless the EJB module is exposing web services of some sort.

You're absolutely right, good catch!

Okay, I was wrong here then. When called from another container or "entry point" into the application (not sure what you would call inflow into a JCA connector exactly), you cannot just call that method.

For a next spec release I could imagine a JNDI like namespace prefix, with java:app/[module name] querying for a specific module in the application and java:module being the default for the current module (which would then throw an IllegalArgumentException if called from an EJB module).

E.g.

From an EJB:

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2

/admin
java:module/admin

Throws IllegalArgumentException 

----

From web module app1

/admin
java:module/admin

Queries for /admin for app1, where /admin must be treated equal to java:module/admin

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2, where java:app/app1/admin must be treated equal to java:module/admin

Thoughts?

Kind regards,
Arjan Tijms




 






Will Hopkins
 

As a general rule, my feeling is that the owner of the resource is the entity that should authorize access to it. So that if you want to test access to, e.g., an external email module, you need to ask that module if the caller has access, rather than try to determine on your own based on some policy provisioned into your app. Evaluating policy across application contexts might be trivial for some authorization subsystems (assuming a common body of authorization policy), but might be difficult for others.

On 06/01/2017 05:37 PM, Bill Shannon wrote:
Using this across modules would introduce a tight coupling that probably isn't desirable.  Roles really do seem like a better approach in that case.  Or the module could provide an API that could be called to determine if the caller has "admin permission" or whatever needs to be tested to influence the behavior of the calling module.

Having a way for a web module to test whether access is allowed to one of the resources of that same web module seems fine.

Arjan Tijms wrote on 05/31/2017 04:34 PM:
Hi,

The general use case for the method is letting the application find out whether a caller has access to certain resources and (mainly) adjusting rendering of links based on that.

A specific use case of this is dynamically rendering a menu with links to pages present in an application, based on what a user is allowed to access. Menu entries could be entirely omitted (so the user only sees entries to pages that are accessible, a common case), or could be rendered differently (say in red, or with a lock symbol next to it).

An extremely simplified example of this can be seen in a small demo app we did here: 


When menus are a little bit more sophisticated, there's often a need to know upfront about entire patterns of pages, for example when testing for /admin/* fails we can omit the entire admin sub header including introduction text. Otherwise we would need to see if the user has access to at least one page.

Roles can be used, and they are in practice, but that assumes the rendering code has knowledge of which role corresponds to which resource, something which doesn't allows remain stable and then necessitates updating code at multiple locations.

A use case where the EJB module could use knowledge about this is as mentioned when sending out emails, which is often done from business services. Another one woud be where an EJB module calls an internal (rest) service. I agree that the EJB module needing to know about the web permissions would be far less common, and would even be more practical with a method that, as Will suggested earlier, also took a Principal as input (things like email sending often happens in batches and asynchronously).

A hasAccessTo is an existing method that has been in use with various frameworks in different forms for some time. One of these is our own OmniFaces project, where we have implemented this here in a slightly different variant:


Hope this made it more clear.

Kind regards,
Arjan Tijms









On Thu, Jun 1, 2017 at 1:02 AM, Bill Shannon <bill.shannon@...> wrote:
Using JNDI-style names for resource names would be confusing.

What's the use case for this method in general, and for using this method with a resource that's in another module?

Arjan Tijms wrote on 05/31/17 03:51 PM:
Hi,

On Thu, Jun 1, 2017 at 12:28 AM, Bill Shannon <bill.shannon@...> wrote:
As I read the spec, the resource name is relative to the web module.  If you're not in a web container, what names can you use?  If your app has two war files, which web module is the name relative to?  Presumably the one you're running in, which means it's not useful if you're not running in a web container.  Well, unless the EJB module is exposing web services of some sort.

You're absolutely right, good catch!

Okay, I was wrong here then. When called from another container or "entry point" into the application (not sure what you would call inflow into a JCA connector exactly), you cannot just call that method.

For a next spec release I could imagine a JNDI like namespace prefix, with java:app/[module name] querying for a specific module in the application and java:module being the default for the current module (which would then throw an IllegalArgumentException if called from an EJB module).

E.g.

From an EJB:

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2

/admin
java:module/admin

Throws IllegalArgumentException 

----

From web module app1

/admin
java:module/admin

Queries for /admin for app1, where /admin must be treated equal to java:module/admin

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2, where java:app/app1/admin must be treated equal to java:module/admin

Thoughts?

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,

Thinking about this a little more and reading your replies, I'm convinced now that we should indeed not make this multi-module, but just keep it to the same module only.

Thanks for letting me see this.

Kind regards,
Arjan Tijms




On Thu, Jun 1, 2017 at 11:45 PM, Will Hopkins <will.hopkins@...> wrote:
As a general rule, my feeling is that the owner of the resource is the entity that should authorize access to it. So that if you want to test access to, e.g., an external email module, you need to ask that module if the caller has access, rather than try to determine on your own based on some policy provisioned into your app. Evaluating policy across application contexts might be trivial for some authorization subsystems (assuming a common body of authorization policy), but might be difficult for others.


On 06/01/2017 05:37 PM, Bill Shannon wrote:
Using this across modules would introduce a tight coupling that probably isn't desirable.  Roles really do seem like a better approach in that case.  Or the module could provide an API that could be called to determine if the caller has "admin permission" or whatever needs to be tested to influence the behavior of the calling module.

Having a way for a web module to test whether access is allowed to one of the resources of that same web module seems fine.

Arjan Tijms wrote on 05/31/2017 04:34 PM:
Hi,

The general use case for the method is letting the application find out whether a caller has access to certain resources and (mainly) adjusting rendering of links based on that.

A specific use case of this is dynamically rendering a menu with links to pages present in an application, based on what a user is allowed to access. Menu entries could be entirely omitted (so the user only sees entries to pages that are accessible, a common case), or could be rendered differently (say in red, or with a lock symbol next to it).

An extremely simplified example of this can be seen in a small demo app we did here: 


When menus are a little bit more sophisticated, there's often a need to know upfront about entire patterns of pages, for example when testing for /admin/* fails we can omit the entire admin sub header including introduction text. Otherwise we would need to see if the user has access to at least one page.

Roles can be used, and they are in practice, but that assumes the rendering code has knowledge of which role corresponds to which resource, something which doesn't allows remain stable and then necessitates updating code at multiple locations.

A use case where the EJB module could use knowledge about this is as mentioned when sending out emails, which is often done from business services. Another one woud be where an EJB module calls an internal (rest) service. I agree that the EJB module needing to know about the web permissions would be far less common, and would even be more practical with a method that, as Will suggested earlier, also took a Principal as input (things like email sending often happens in batches and asynchronously).

A hasAccessTo is an existing method that has been in use with various frameworks in different forms for some time. One of these is our own OmniFaces project, where we have implemented this here in a slightly different variant:


Hope this made it more clear.

Kind regards,
Arjan Tijms









On Thu, Jun 1, 2017 at 1:02 AM, Bill Shannon <bill.shannon@...> wrote:
Using JNDI-style names for resource names would be confusing.

What's the use case for this method in general, and for using this method with a resource that's in another module?

Arjan Tijms wrote on 05/31/17 03:51 PM:
Hi,

On Thu, Jun 1, 2017 at 12:28 AM, Bill Shannon <bill.shannon@...> wrote:
As I read the spec, the resource name is relative to the web module.  If you're not in a web container, what names can you use?  If your app has two war files, which web module is the name relative to?  Presumably the one you're running in, which means it's not useful if you're not running in a web container.  Well, unless the EJB module is exposing web services of some sort.

You're absolutely right, good catch!

Okay, I was wrong here then. When called from another container or "entry point" into the application (not sure what you would call inflow into a JCA connector exactly), you cannot just call that method.

For a next spec release I could imagine a JNDI like namespace prefix, with java:app/[module name] querying for a specific module in the application and java:module being the default for the current module (which would then throw an IllegalArgumentException if called from an EJB module).

E.g.

From an EJB:

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2

/admin
java:module/admin

Throws IllegalArgumentException 

----

From web module app1

/admin
java:module/admin

Queries for /admin for app1, where /admin must be treated equal to java:module/admin

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2, where java:app/app1/admin must be treated equal to java:module/admin

Thoughts?

Kind regards,
Arjan Tijms




 






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



Will Hopkins
 

So, where does that leave us in terms of either:
  • Separating out the generic SecurityContext interface and methods from the servlet-specific methods (i.e., using "interface ServletSecurityContext extends SecurityContext"); or,
  • Changing the signatures of the servlet-specific methods (as many as possible) to be generic so they could be useful in multiple containers?
I think it's probably too late to be changing signatures, and that wouldn't work for the authenticate() method anyway.

I do think it's pretty straightforward to separate out the generic and servlet-specific methods into separate interfaces, and I don't think doing so adds any significant complexity, or interferes with ease of use -- unless you're doing something servlet-specific, you can use SecurityContext anywhere, and, if you are doing something servlet-specific, referencing a servlet-specific type (ServletSecurityContext) doesn't seem like an unreasonable burden. We would still retain the benefits of common code and common signatures for the common methods. A monolithic interface that includes methods not usable in the "current" container imposes its own complexity and usability issues, IMO.

That said, I'm OK leaving SecurityContext the way it is, if that's the consensus of the EG. Just want to close on the issue.

Regards,

Will

On 06/01/2017 07:53 PM, Arjan Tijms wrote:
Hi,

Thinking about this a little more and reading your replies, I'm convinced now that we should indeed not make this multi-module, but just keep it to the same module only.

Thanks for letting me see this.

Kind regards,
Arjan Tijms




On Thu, Jun 1, 2017 at 11:45 PM, Will Hopkins <will.hopkins@...> wrote:
As a general rule, my feeling is that the owner of the resource is the entity that should authorize access to it. So that if you want to test access to, e.g., an external email module, you need to ask that module if the caller has access, rather than try to determine on your own based on some policy provisioned into your app. Evaluating policy across application contexts might be trivial for some authorization subsystems (assuming a common body of authorization policy), but might be difficult for others.


On 06/01/2017 05:37 PM, Bill Shannon wrote:
Using this across modules would introduce a tight coupling that probably isn't desirable.  Roles really do seem like a better approach in that case.  Or the module could provide an API that could be called to determine if the caller has "admin permission" or whatever needs to be tested to influence the behavior of the calling module.

Having a way for a web module to test whether access is allowed to one of the resources of that same web module seems fine.

Arjan Tijms wrote on 05/31/2017 04:34 PM:
Hi,

The general use case for the method is letting the application find out whether a caller has access to certain resources and (mainly) adjusting rendering of links based on that.

A specific use case of this is dynamically rendering a menu with links to pages present in an application, based on what a user is allowed to access. Menu entries could be entirely omitted (so the user only sees entries to pages that are accessible, a common case), or could be rendered differently (say in red, or with a lock symbol next to it).

An extremely simplified example of this can be seen in a small demo app we did here: 


When menus are a little bit more sophisticated, there's often a need to know upfront about entire patterns of pages, for example when testing for /admin/* fails we can omit the entire admin sub header including introduction text. Otherwise we would need to see if the user has access to at least one page.

Roles can be used, and they are in practice, but that assumes the rendering code has knowledge of which role corresponds to which resource, something which doesn't allows remain stable and then necessitates updating code at multiple locations.

A use case where the EJB module could use knowledge about this is as mentioned when sending out emails, which is often done from business services. Another one woud be where an EJB module calls an internal (rest) service. I agree that the EJB module needing to know about the web permissions would be far less common, and would even be more practical with a method that, as Will suggested earlier, also took a Principal as input (things like email sending often happens in batches and asynchronously).

A hasAccessTo is an existing method that has been in use with various frameworks in different forms for some time. One of these is our own OmniFaces project, where we have implemented this here in a slightly different variant:


Hope this made it more clear.

Kind regards,
Arjan Tijms









On Thu, Jun 1, 2017 at 1:02 AM, Bill Shannon <bill.shannon@...> wrote:
Using JNDI-style names for resource names would be confusing.

What's the use case for this method in general, and for using this method with a resource that's in another module?

Arjan Tijms wrote on 05/31/17 03:51 PM:
Hi,

On Thu, Jun 1, 2017 at 12:28 AM, Bill Shannon <bill.shannon@...> wrote:
As I read the spec, the resource name is relative to the web module.  If you're not in a web container, what names can you use?  If your app has two war files, which web module is the name relative to?  Presumably the one you're running in, which means it's not useful if you're not running in a web container.  Well, unless the EJB module is exposing web services of some sort.

You're absolutely right, good catch!

Okay, I was wrong here then. When called from another container or "entry point" into the application (not sure what you would call inflow into a JCA connector exactly), you cannot just call that method.

For a next spec release I could imagine a JNDI like namespace prefix, with java:app/[module name] querying for a specific module in the application and java:module being the default for the current module (which would then throw an IllegalArgumentException if called from an EJB module).

E.g.

From an EJB:

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2

/admin
java:module/admin

Throws IllegalArgumentException 

----

From web module app1

/admin
java:module/admin

Queries for /admin for app1, where /admin must be treated equal to java:module/admin

java:app/app1/admin
java:app/app2/admin

Queries for /admin for app1 and app2, where java:app/app1/admin must be treated equal to java:module/admin

Thoughts?

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