JAAS - request.isUserInRole always returning false

1

I am implementing a JAAS with only 2 types of users, one type will be Administrator and the other will be Contributor. Instead of creating separate directories for admin and for collaborator, I want both to access the same page, the difference is that the administrator will have some components like rendered="true" more than the collaborator.

I did a test project and followed this tutorial that worked normally.

Now that the project started in earnest, I opened a new project and this time I'm not getting it, I've already reviewed the code and configuration several times and can not find the error.

The request.isUserInRole method always returns false.

I have created a User, Group, and a UserGroup table, and also a view that has the columns of other tables with username, user_password, and group_name.

In glassfish, I created a Realm with the following settings:

JAAS Context: jdbcRealm JNDI: Rap User's Table: vw_rap_grp_usr User Name Column: user_name Password column: username Group Table: vw_rap_grp_usr Group Names Column: group_name

My web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>Gestão de Projetos</display-name>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
  <security-constraint>
    <web-resource-collection>
        <web-resource-name>Admin Area</web-resource-name>
        <url-pattern>/faces/inter/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>Administrador</role-name>
    </auth-constraint>
  </security-constraint>
  <security-constraint>
    <web-resource-collection>
        <web-resource-name>Colaborador Area</web-resource-name>
        <url-pattern>/faces/inter/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>Colaborador</role-name>
        <role-name>Administrador</role-name>
    </auth-constraint>
  </security-constraint>

  <login-config>
    <auth-method>FORM</auth-method>
    <realm-name>GestaoDeProjetosRealm</realm-name>
    <form-login-config>
        <form-login-page>/faces/login.xhtml</form-login-page>
        <form-error-page>/faces/login.xhtml</form-error-page>
    </form-login-config>
  </login-config>
  <security-role>
    <role-name>Administrador</role-name>
  </security-role>
  <security-role>
    <role-name>Colaborador</role-name>
  </security-role>  
  <error-page>
    <error-code>403</error-code>
    <location>/faces/AccessDenied.xhtml</location>
  </error-page>
  <welcome-file-list>
        <welcome-file>faces/login.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

My faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>

<!-- =========== FULL CONFIGURATION FILE ================================== -->

<faces-config version="2.0"
              xmlns="http://java.sun.com/xml/ns/javaee" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">   

    <navigation-rule>
        <from-view-id>/login.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>falha</from-outcome>
            <to-view-id>/login.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>       
    <navigation-rule>
        <from-view-id>/login.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>administrador</from-outcome>
            <to-view-id>inter/index.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>
    <navigation-rule>
        <from-view-id>/login.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>colaborador</from-outcome>
            <to-view-id>inter/index.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>

</faces-config>

And the LoginBean.java

@ManagedBean
public class LoginBean implements Serializable{

    private String usuario;
    private String senha;

    // getters e setters - ocultei para não ficar muito extenso 

    public LoginBean() {
        HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
        if (session != null) {
            session.invalidate();
        }
    }

    public String logar() {
        String message = "";
        String navto = "";
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();

        try {            
            request.login(usuario, senha);            
            Principal principal = request.getUserPrincipal();            
            if (request.isUserInRole("Administrador")) {                
                message = "Username : " + principal.getName() + " You are an Administrator, you can really f**k things up now";
                navto = "administrador";
            } else if (request.isUserInRole("Colaborador")) {                
                message = "Username : " + principal.getName() + " You are only a Manager, Don't you have a Spreadsheet to be working on??";
                navto = "colaborador";
            }else {
                System.out.println("Nenhum deles...");
            }   

            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, null));
            return navto;
        } catch (ServletException e) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "An Error Occured: Login failed", null));
            e.printStackTrace();
            return "falha";
        }
    }

    public void logout() {
        HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
        if (session != null) {
            session.invalidate();
        }
        FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(FacesContext.getCurrentInstance(), null, "/login.xhtml");
    }

}

The output does not show any errors, but always prints "None of them ..." as I put it in SystemOutPrintln.

Another observation is that if I put an invalid user or password, it shows the message "An Error Occured: Login failed" according to try catch, but if the user and password are valid, the screen remains on the login screen but with a ball in the left corner.

    
asked by anonymous 09.06.2014 / 17:05

2 answers

1

How is your configuration in Glassfish? What stack is returning when you put correct data? For the moment forget the authorization, just authenticate the user by checking that the returned Principal is not null. Comment out the <security-role> tags and first check if DB access is OK, debug and parse Principal .

I'm not very knowledgeable about JSF, but why are you using declarative login? Just create a form and call send a POST to /j_security_check , passing j_username and j_password

Provide more error data per se than you are getting that maybe I can help you better. Because apparently nothing is wrong with your setup. If you find it necessary to look here at the Github that has some examples of mine from JAAS.

Hugs

    
09.06.2014 / 19:03
1

I discovered the mistake, in fact I was doing what a lot of people did, but I was believing I was doing it right. I was confusing the role with the group, so in security-role-mapping I reversed what was to be role-name I put as group-name. Thank you very much for the help!

    
09.06.2014 / 22:55