jakartaee / servlet

Jakarta Servlet
https://eclipse.org/ee4j/servlet
Other
263 stars 85 forks source link

Provide an isAccessAllowed method to see if user has access to URL #61

Open glassfishrobot opened 11 years ago

glassfishrobot commented 11 years ago

Following the Servlet spec, security constraints can be specified in web.xml. The Servlet container internally uses these to determine whether the current user has access to a given URL (Servlet 3.0 specification Section 12.1).

There is however no method in the public API that user code can use to do the same check. A use case for this would be the rendering of a list of links (e.g. in a menu), where the requirement is to not render those links where the user does not have access to. Without a means to ask the Servlet container about the access for every link, the code must either duplicate the URL-role association somewhere (perhaps in a custom XML file), or has to duplicate the algorithm from Section 12.1.

Both solutions are not ideal, since the container already maintains this association and already has an implementation of said algorithm.

Therefor I would like to request a "boolean isAccessAllowed(String url, String role)" method to be provided by the Servlet API, perhaps added to HttpServletRequest, that user code can use to determine if the current user has access to a given URL (relative to the context root of the web app).

glassfishrobot commented 6 years ago
glassfishrobot commented 11 years ago

@glassfishrobot Commented Reported by arjan_t

glassfishrobot commented 11 years ago

@glassfishrobot Commented balusc said: Putting it on ServletContext makes more sense. Having it on HttpServletRequest would be only useful if you'd like to check it against the currently logged-in user as in boolean isAccessAllowed(String url).

glassfishrobot commented 11 years ago

@glassfishrobot Commented arjan_t said: @balusc, you're right. Unfortunately I can't edit the description anymore.

Having two versions of the requested method would be ideal; one to do the check for the current user, and one to do the check for a given role independent of who the current user is.

glassfishrobot commented 11 years ago

@glassfishrobot Commented @shingwaichan said: This can be achieved by checking javax.security.jacc.WebResourcePermission in JACC.

I am not sure whether it is necessary to provide the same functionality in Servlet spec. Adding it to the bucket of FUTURE_RELEASE.

glassfishrobot commented 11 years ago

@glassfishrobot Commented darious3 said: Shing, does this mean that JACC will be a mandatory part of Servlet in the future?

At the moment JACC is not available in the Java EE Web Profile, and certainly not in Servlet Containers. JACC is also a bit difficult and arcane to work with. Even in the Java EE Full Profile an easier method to do this check would be a plus.

glassfishrobot commented 10 years ago

@glassfishrobot Commented arjan_t said:

This can be achieved by checking javax.security.jacc.WebResourcePermission in JACC.

The problem is that even in containers that should support JACC (i.e. full Java EE implementations) JACC just isn't always there, but has to be "enabled". See e.g. the weblogic instructions:

To enable the WebLogic JACC Provider from the command line, you must specify the following system property/value pairs:

Property: java.security.manager

Value: No value required.

Property: java.security.policy

Value: A valid weblogic.policy file, specified using either a relative or an absolute pathname

Property: javax.security.jacc.PolicyConfigurationFactory.provider

Value: weblogic.security.jacc.simpleprovider.PolicyConfigurationFactoryImpl

Property: javax.security.jacc.policy.provider

Value: weblogic.security.jacc.simpleprovider.SimpleJACCPolicy

Property: weblogic.security.jacc.RoleMapperFactory.provider

Value: weblogic.security.jacc.simpleprovider.RoleMapperFactoryImpl

Source: http://docs.oracle.com/cd/E24329_01/web.1211/e24485/server_prot.htm#i1037363

I think it would not be unreasonable to assume that very few if any developers let alone anyone from IT will do this just to enable what should be a relatively simple utility method.

I also wonder how exactly you would code both versions of the required functionality with JACC. I can think of code such as the following;

Subject subject = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");

          boolean test = Policy.getPolicy().implies( new ProtectionDomain(
new CodeSource(null, (Certificate[]) null),
null, null, 
subject.getPrincipals().toArray(new Principal[subject.getPrincipals().size()])
), 
new WebResourcePermission("/protected/Servlet", ""))
            ;

But this will test if the current authenticated user has access, not if a given role has access. We can't just pass in a Principal for just the role we're looking for since the representation of that is container specific, isn't it?

glassfishrobot commented 10 years ago

@glassfishrobot Commented kithouna said:

The problem is that even in containers that should support JACC (i.e. full Java EE implementations) JACC just isn't always there, but has to be "enabled".

It's even worse...

Some containers don't even ship with a default JACC provider! WebSphere only ships with a JACC provider that is a client for an external Tivolo Access Manager server. There is no such thing as a default internal JACC provider. See http://pic.dhe.ibm.com/infocenter/wasinfo/v8r5/index.jsp?topic=%2Fcom.ibm.websphere.nd.multiplatform.doc%2Fae%2Fcsec_jaccintegrate.html

In other words, the JACC methods for getting the current Subject and asking for roles etc are just not available on WebSphere. Since WebSphere is fully Java EE certified and TCK tested we can only conclude that JACC isn't really part of Java EE. I mean, the SPI to interface with a JACC provider is, but the actual JACC functionality isn't.

glassfishrobot commented 7 years ago

@glassfishrobot Commented This issue was imported from java.net JIRA SERVLET_SPEC-61