5 Replies Latest reply on Jan 5, 2006 6:26 AM by Nigel White

    Need to programatically check access to a URL.

    Nigel White Newbie

      I have a custom JAAS login module worknig fine in JBoss. I have container-managed access control to my various web URIs, and that works fine.

      Now, I need to be able to, in code, determine whether the current user has access to a certain URL.

      This is obviously to decide whether or not to display certain links. It's no good offering them "/restricted/management.jsp" if they don't have the "manager" role.

      I could check isUserInRole("manager"), but that's too much hardcoding, I just want to ask the container whether the user can access "/restricted/management.jsp".

        • 1. Re: Need to programatically check access to a URL.
          Nigel White Newbie

          Fluff!!!!!

          Back from holiday.

          Still need to do this.

          Any ideas?

          • 2. Re: Need to programatically check access to a URL.
            Anil Saldanha Master

            Why don't u place resources that need to be accessed by management under "/restricted/management/" and protect.

            Explain to me why an application based role like "manager" that is checked via isUserInRole("manager") to be mapped against an operational/deployment role- is a lot of hardcoding? You are free to define as many app roles as you need.

            Keep it simple.

            Have a look at JACC and our realm that deals with permissions in

            org.jboss.web.tomcat.security.JaccAuthorizationRealm
            

            Maybe that may give you some more ideas.

            • 3. Re: Need to programatically check access to a URL.
              Nigel White Newbie

               

              "anil.saldhana@jboss.com" wrote:
              Why don't u place resources that need to be accessed by management under "/restricted/management/" and protect.

              Explain to me why an application based role like "manager" that is checked via isUserInRole("manager") to be mapped against an operational/deployment role- is a lot of hardcoding? You are free to define as many app roles as you need.

              Keep it simple.

              Have a look at JACC and our realm that deals with permissions in
              org.jboss.web.tomcat.security.JaccAuthorizationRealm
              

              Maybe that may give you some more ideas.


              I don't want links to appear to pages that the user is not authorized to get to.

              But calling isUserInRole("manager") before writing "<a href=\"/management/stats.jsp\">" is hardcoding knowledge that is encoded declaratively in web.xml into the java! What is the point of having declarative security in web.xml, enforced by the container if I'm going to have to add that knowledge into the java code?

              What I need is isAuthorizedURL("\"/management/stats.jsp\"") which checks with the container whether the URL is available to the current user's roles.

              • 4. Re: Need to programatically check access to a URL.
                Nigel White Newbie

                Right. After wading through the source code of JaccAuthorizationRealm, I have the following test working:

                import java.util.Set;
                import java.security.Policy;
                import java.security.Principal;
                import java.security.AccessController;
                import java.security.CodeSource;
                import java.security.ProtectionDomain;
                import javax.security.auth.Subject;
                import javax.security.jacc.PolicyContext;
                import javax.security.jacc.WebResourcePermission;
                import org.jboss.web.tomcat.security.JaccContextValve;
                


                ...

                 private static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container";
                



                ...

                 Subject caller = null;
                 try
                 {
                 caller = (Subject)PolicyContext.getContext(SUBJECT_CONTEXT_KEY);
                 }
                 catch (Exception e)
                 {
                 System.out.println("Failed to get subject from PolicyContext\n" + e);
                 }
                 if (caller == null)
                 {
                 System.out.println("Access to /restricted/test.jsp is denied");
                 }
                 else
                 {
                 WebResourcePermission perm = new WebResourcePermission("/restricted/test.jsp", "");
                 Policy policy = Policy.getPolicy();
                
                 Set principalsSet = caller.getPrincipals();
                 Principal[] principals = new Principal[principalsSet.size()];
                 principalsSet.toArray(principals);
                
                 CodeSource webCS = (CodeSource)JaccContextValve.activeCS.get();
                 ProtectionDomain pd = new ProtectionDomain(webCS, null, null, principals);
                 boolean allowed = policy.implies(pd, perm);
                 if (allowed)
                 System.out.println("Access to /restricted/test.jsp is permitted");
                 else
                 System.out.println("Access to /restricted/test.jsp is NOT permitted");
                 }
                


                There should be a standard way of doing this.

                • 5. Re: Need to programatically check access to a URL.
                  Nigel White Newbie

                  OK, the CodeSource can be got in a non container-specific way:

                   String loadPath = this.getClass().getProtectionDomain().getCodeSource().getLocation().toString();
                   webCS = new CodeSource(new URL(loadPath.substring(0, loadPath.indexOf("/WEB-INF") + 1)), (Certificate[])null);
                  


                  So, now I have my LoginModule generating this information at login time, and then saving itself in the HttpSession. I have implemented a method in it:

                   public boolean isURLAuthorized(String URLString)
                   {
                   return policy.implies(protDomain, new WebResourcePermission(URLString, ""));
                   }
                  


                  So, now I can check availability of URLs in my tag handlers that output links.