servlet-spec
  1. servlet-spec
  2. SERVLET_SPEC-61

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

    Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Labels:
      None

      Description

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

        Activity

        Hide
        balusc added a comment -

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

        Show
        balusc added a comment - 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) .
        Hide
        arjan tijms added a comment -

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

        Show
        arjan tijms added a comment - @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.
        Hide
        Shing Wai Chan added a comment -

        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.

        Show
        Shing Wai Chan added a comment - 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.
        Hide
        Darious3 added a comment -

        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.

        Show
        Darious3 added a comment - 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.
        Hide
        arjan tijms added a comment -

        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?

        Show
        arjan tijms added a comment - 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?
        Hide
        kithouna added a comment -

        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.

        Show
        kithouna added a comment - 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.

          People

          • Assignee:
            Shing Wai Chan
            Reporter:
            arjan tijms
          • Votes:
            3 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated: