JAAS - request.isUserInRole always returning false

Asked

Viewed 439 times

1

I am implementing a JAAS with only 2 types of users, one type will be an Administrator and another will be a Collaborator. Instead of creating separate directories for administrator and 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 one tutorial that worked normally.

Now that the project really started, I opened a new project and this time I’m not succeeding, I’ve reviewed the code and configuration several times and I can’t find the error.

The request.isUserInRole method always returns false.

I created a User table, Group and User relationship table and also a view that has the columns of the other tables with name_user, password_user and name_group.

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

Context of JAAS: jdbcRealm JNDI : Rap Users Table: vw_rap_grp_usr User Name Column: user_name Column of Passwords: password Group Table: vw_rap_grp_usr Group Names Column: name_group

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 present me any error, but always prints "None of them..." as I put in Systemoutprintln.

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

2 answers

1

How’s your Glassfish setting? Which stack is returning when you input correct data? For the moment forget the authorization, just authenticate the user by checking that the returned Main is not null. Comment the tags <security-role> and check first if the access to DB is OK, do a debug and analyze the Principal.

I’m not very familiar with JSF but why are you using login declaratively ? Just create a form and call send a POST to /j_security_check, passing a j_username and a j_password

Provide more data of the error itself that you are getting that maybe I can help you better. Because apparently there’s nothing wrong with your setup. If you find it necessary to take a look here at Github that has some examples of me from JAAS.

Hugs

1

I discovered the mistake, I was actually doing what a lot of people also did but I was a believer that 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 put as group-name. Thank you so much for your help!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.