Declarative Security does not work

This topic has 6 replies, 2 voices, and was last updated 5 years, 2 months ago by soma.

  • Author
    Posts
  • #11192
     soma
    Participant

    Hi All,

    I am trying to set up Declarative Security but it does not work properly. I guess I missed some settings.

    After the successfull login user have access to the general protected pages but same user can not open an url which is protected by <security-constraint>. User gets http 403.

    web.xml:

    <web-app ... version="3.1">
        <filter>
            <filter-name>Agent</filter-name>
            <filter-class>com.sun.identity.agents.filter.AmAgentFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>Agent</filter-name>
            <url-pattern>/*</url-pattern>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>INCLUDE</dispatcher>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>ERROR</dispatcher>
        </filter-mapping>
    
        <error-page>
            <error-code>403</error-code>
            <location>/authentication/accessdenied.html</location>
        </error-page>
        <error-page>
            <error-code>404</error-code>
            <location>/public/notfound.html</location>
        </error-page>
    
        <security-constraint>
            <web-resource-collection>
                <web-resource-name>Private static content</web-resource-name>
                <url-pattern>/rest/*</url-pattern>
            </web-resource-collection>
            <auth-constraint>
                <role-name>id=employee,ou=group,dc=openam,dc=forgerock,dc=org</role-name>
            </auth-constraint>
        </security-constraint>
    
        <security-role>
            <role-name>id=employee,ou=group,dc=openam,dc=forgerock,dc=org</role-name>
        </security-role>
    </web-app>

    User configuration:

    User is in the proper group
    user details

    My info servlet returns with these data:

    • auth type: PROGRAMMATIC
      remote user: andy
      user principal: andy
      user principal list: andy

    Source code of my info servlet:

    public void doGet(...) 
    {
        ...
        String message = "auth type: ";
        out.println(message + request.getAuthType() + NEW_LINE);
    
        message = "remote user: ";
        out.println(message + request.getRemoteUser() + NEW_LINE);
    
        message = "user principal: ";
        out.println(message + request.getUserPrincipal().getName() + NEW_LINE);
    
        message = "user principal list: " ;
        Principal userPrincipal = request.getUserPrincipal();
        WebPrincipal genericPrincipal = (WebPrincipal) userPrincipal;
        if (genericPrincipal == null)
            out.println(message + "NULL" + NEW_LINE);
        else
            out.println(message + genericPrincipal.toString() + NEW_LINE);
    }

    Could you please help me?

    • This topic was modified 5 years, 3 months ago by soma.
    • This topic was modified 5 years, 3 months ago by Peter Major.
    #11198
     Peter Major
    Moderator

    * When working with declarative security, you really ought to mention the container you are using.
    * if getRemoteUser is working, then chances are that declarative security is working already.

    Best would be to enable message level debug logging to see what roles your user gets associated with. Have you configured privileged attribute mapping based on group membership on the Application tab?

    #11212
     soma
    Participant

    Hi,

    Thanks for the reply.
    EE container what i use is GlassFish Server 3.1.2 and default ‘Privilege Attributes Processing’ settings were used before I posted my question on the forum.

    I checked doc about the mentioned ‘Privilege Attributes Processing’ settings and I played with it but role base authorization still does not work :(

    I modified a little bit the content of my web.xml file and I updated my servlet’s code in order to show more info about http servlet request.

    servlet code:

    
    // auth type
    sout("auth type: " + request.getAuthType())
    
    // remote user
    sout("remote user: " + request.getRemoteUser())
    
    // user principal
    java.security.Principal javaPrincipal = request.getUserPrincipal();
    
    if (javaPrincipal == null)
        sout("principal: null")
    else {
        sout("principal class: " +javaPrincipal.getClass().getCanonicalName())
        sout("principal name: " + javaPrincipal.getName())
    
        if (javaPrincipal instanceof com.sun.enterprise.security.web.integration.WebPrincipal) {
            WebPrincipal webPrincipal = (WebPrincipal) javaPrincipal;
            Set<Principal> principals = webPrincipal.getSecurityContext().getSubject().getPrincipals();
    
            int index = 0;
            for (Principal p : principals) {
                index++;
                sout("web principal subject " + index + ": " + p.getName())
            }
        }
    }
    
    // user in role
    request.isUserInRole("AUTHENTICATED_USERS")
    request.isUserInRole("SALES")
    request.isUserInRole("sales")
    request.isUserInRole("id=sales,ou=group,dc=openam,dc=forgerock,dc=org")
    

    The content of my web web.xml file is roughly same then before except the security-constraint section. I use this settings right now:

    
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Private static content</web-resource-name>
            <url-pattern>/rest/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>id=sales,ou=group,dc=openam,dc=forgerock,dc=org</role-name>
            <role-name>AUTHENTICATED_USERS</role-name>
            <role-name>SALES</role-name>
            <role-name>sales</role-name>
        </auth-constraint>
    </security-constraint>
    
    <security-role>
        <role-name>id=sales,ou=group,dc=openam,dc=forgerock,dc=org</role-name>
    </security-role>
    <security-role>
        <role-name>AUTHENTICATED_USERS</role-name>
    </security-role>
    <security-role>
        <role-name>SALES</role-name>
    </security-role>
    <security-role>
        <role-name>sales</role-name>
    </security-role>
    

    (1)
    I have created a new group with name “sales” and i added demo user to this group. I also created a new ‘Privileged Attribute Mapping’ key-value pair: [id=sales,ou=group,dc=openam,dc=forgerock,dc=org]=sales

    The result of my info servlet:

    
    PROTECTED Info Servlet
    
    server time: Sun Jun 12 15:40:19 CEST 2016
    auth type: PROGRAMMATIC
    remote user: demo
    
    principal
    principal class: com.sun.enterprise.security.web.integration.WebPrincipal
    principal name: demo
    web principal subject 1: demo
    web principal subject 2: ANYONE
    web principal subject 3: sales
    web principal subject 4: id=sales,ou=group,dc=openam,dc=forgerock,dc=org
    web principal subject 5: AUTHENTICATED_USERS
    
    user in 'AUTHENTICATED_USERS' role: false
    user in 'SALES' role: false
    user in 'sales' role: false
    user in 'id=sales,ou=group,dc=openam,dc=forgerock,dc=org' role: false
    

    The result seems good for me but I still get a http 403 when I try to open any uri under the role protected uri (‘rest/*’).

    Why the result of my all request.isUserInRole(…) calls are FALSE?

    (2) When I removed user from the group then the result of my info servlet is:

    
    web principal subject 1: demo
    web principal subject 2: ANYONE
    web principal subject 3: AUTHENTICATED_USERS
    

    It is okay, two subjects are gone. But why two? I do not understand it.

    (3) Is the role name attribute in web.xml case sensitive or not? I have just added two attributes in the web.xml (‘SALES’ and ‘sales’) just be sure do not miss something. Maybe the ‘Privileged Attributes To Lower Case’ settings are managed to this behavior?

    Could you please tell me what setting is missing from my configuration and why URIs protected by roles are not accessible?

    Thx.

    #11213
     soma
    Participant

    Do I really need to put almost the same stuff to these three config files in case of glassfish 3.x server?

    1) web.xml

    
    <security-role id="SR_MANAGER_ROLE">
        <role-name>MANAGER_ROLE</role-name>
    </security-role>
    

    2) application.xml

    
    <security-role id="SR_MANAGER_ROLE">
        <role-name>MANAGER_ROLE</role-name>
    </security-role>
    

    3) sun-application.xml

    
    <security-role-mapping>
        <role-name>MANAGER_ROLE</role-name>
        <group-name>id=manager,ou=group,dc=openam,dc=forgerock,dc=org</group-name>
    </security-role-mapping>
    

    Why I need to map things on the OpenAM console and map the same things in the above mentioned 3 files as well?

    • This reply was modified 5 years, 3 months ago by soma.
    #11339
     soma
    Participant

    Thanks you for @peter-major this issue is solved.

    I recommend to everybody with same issue to read this old doc: Introduction to Security in the Java EE Platform.

    The key point was to understand that the configuration of role based authorization depends on the used java container.

    In case of GlassFish 3.1.2 there are two xml files what I had to modify: web.xml and sun-web.xml (or glassfish-web.xml).

    web.xml:

    
    <filter>
        <filter-name>Agent</filter-name>
        <filter-class>com.sun.identity.agents.filter.AmAgentFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Agent</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>
    ...
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>pivate content</web-resource-name>
            <url-pattern>/rest/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>SALES_ROLE</role-name>
        </auth-constraint>
    </security-constraint>
    
    <security-role>
        <role-name>SALES_ROLE</role-name>
    </security-role>
    

    sun-web.xml

    <sun-web-app>
    <security-role-mapping>
    <role-name>SALES_ROLE</role-name>
    <group-name>id=sales,ou=group,dc=openam,dc=forgerock,dc=org</group-name>
    </security-role-mapping>
    </sun-web-app>

    Group name comes from OpenAM. If you want to check what exactly OpenAM sets then agent log level needs to be set to debug (message) level and search for AUTHENTICATED_USERS in the log (glassfish-3.1.2.2/openam/j2ee_agent/Agent_001/logs/debug/debug.out)

    In my case I could see this in the log:

    
    AmRealm.authenticate: user: demo, authenticated: true, attributes: [sales, id=sales,ou=group,dc=openam,dc=forgerock,dc=org, AUTHENTICATED_USERS]
    

    The rest is up to security role mapping and *.xml configurations. That is all.
    Thanks.

    #11930
     soma
    Participant

    I just want to complete this topic and share the solution with u.

    The solution described above works with with GlassFish 3.1.2.2.

    In case of Tomcat 8.0.23 I use the following settings.

    web.xml

    
    <filter>
        <filter-name>Agent</filter-name>
        <filter-class>com.sun.identity.agents.filter.AmAgentFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Agent</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>
    
    <welcome-file-list>
       <welcome-file>/public/welcome.html</welcome-file>
    </welcome-file-list>
    
    <error-page>
       <error-code>403</error-code>
       <location>/authentication/accessdenied.html</location>
    </error-page>
    <error-page>
       <error-code>404</error-code>
       <location>/public/notfound.html</location>
    </error-page>
    
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>role protected content</web-resource-name>
            <url-pattern>/rest/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>id=sales,ou=group,dc=openam,dc=forgerock,dc=org</role-name>
        </auth-constraint>
    </security-constraint>
    
    <login-config>
       <auth-method>FORM</auth-method>
       <form-login-config>
          <form-login-page>/authentication/login.html</form-login-page>
          <form-error-page>/authentication/accessdenied.html</form-error-page>
       </form-login-config>
    </login-config>
    
    <security-role>
        <role-name>id=sales,ou=group,dc=openam,dc=forgerock,dc=org</role-name>
    </security-role>
    

    login.html

    
    <html>
       <head>
          <meta charset="UTF-8">
          <title>login page</title>
       </head>
       <body>
          If you are able to see this page in the deployed application, it implies that either you have
          not enabled web-tier declarative security, or you have not provided a mechanism for application
          level customized form login processing.
       </body>
    </html>
    

    Settings on OpenAM web Console
    * Agents > J2EE > [agent name]
    – Global > General > Filter Mode > only J2EE_POLICY
    – Application > Login Form URI: /demo-tomcat-1.0/authentication/login.html
    – Application > Access Denied URI: [demo-tomcat-1.0]=/demo-tomcat-1.0/authentication/accessdenied.html
    – Application > Not Enforced URIs: /demo-tomcat-1.0/, /demo-tomcat-1.0/public/*, /demo-tomcat-1.0/index.html

    Users belong to the ‘sales’ group (id=sales,ou=group,dc=openam,dc=forgerock,dc=org) have access to resources /rest/*. Users who do not member of this group get accessdenied.html result.

    Hope this description helps you guys.

    #11931
     soma
    Participant

    The result of my info servlet:

    
    PROTECTED Info Servlet
    
    server time: Fri Jul 08 11:58:54 CEST 2016
    auth type: FORM
    remote user: demo
    
    principal
    principal class: org.apache.catalina.realm.GeneralPrincipal
    principal name: demo
    web principal subject 1: AUTHENTICATED_USERS
    web principal subject 2: id=sales,ou=group,dc=openam,dc=forgerock,dc=org
    
    user in 'AUTHENTICATED_USERS' role: true
    user in 'SALES' role: false
    user in 'sales' role: false
    user in 'id=sales,ou=group,dc=openam,dc=forgerock,dc=org' role: true
    
Viewing 7 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.

©2021 ForgeRock - we provide an identity and access platform to secure every online relationship for the enterprise market, educational sector and even entire countries. Click to view our privacy policy and terms of use.

Log in with your credentials

Forgot your details?