Search code examples
authenticationjsf-2glassfish-3jaas

Keep getting HTTP Status 403 after login to webapplication secured with glassfish security realm


Setup:

  • glassfish 3.1.1
  • JSF 2.1
  • jdbcRealm with postgreSQL

After typing valid user credentials to the login form I get logged in and redirected to the next page. But if I leave that page and go to another one, which is in the allowed url-pattern of course, I get the "HTTP Status 403 - Access to the requested resource has been denied". After that I can not visit any site of the webapp anymore.

The login only works, if I set the Standard-Realm in glassfish's server-config/security to my own realm!

I get one warning in the server log at deploy time:

Warnung: Keine Principals zugeordnet zu Rolle [USER].
(Warning: No principals mapped to role [USER])

If I remove the JSESSIONID with Chrome Debugger, I can login again. Looks like the Session gets destroyed on the server side after visiting one allowed website or something?!

I attached some relevant sources. I think it has nothing to do with the Realm and so on, since the login mechanism works and there are no exceptions...

web.xml

<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>jdbcRealm</realm-name>
    <form-login-config>
        <form-login-page>/faces/login.xhtml</form-login-page>
        <form-error-page>/faces/loginError.xhtml</form-error-page>
    </form-login-config>
</login-config>

<security-constraint>
    <web-resource-collection>
        <web-resource-name>User</web-resource-name>
        <url-pattern>/faces/user/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>ADMIN</role-name>
    </auth-constraint>
</security-constraint>

glassfish-web-app.xml (Added manually)

<glassfish-web-app>
<security-role-mapping>
    <role-name>USER</role-name>
    <group-name>USER</group-name>
</security-role-mapping>
</glassfish-web-app>

login.xhtml

<h:form>
<h:outputLabel for="usernameInput">
    Username:
</h:outputLabel>
<h:inputText id="usernameInput" value="#{authBackingBean.username}" 
             required="true" />
<br />
<h:outputLabel for="passwordInput">
    Password:
</h:outputLabel>
<h:inputSecret id="passwordInput" value="#{authBackingBean.password}" 
               required="true" />
<br />
<h:commandButton value="Login" 
                 action="#{authBackingBean.login}" />

AuthBackingBean

@Stateless
@Named
public class AuthBackingBean {

    private String username;
    private String password;

    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String login() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        try {
            request.login(this.username, this.password);
        } catch (ServletException e) {
            context.addMessage(null, new FacesMessage("Login failed."));
            return "loginError";
        }
        return "user/index";
    }

    public void logout() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        try {
            request.logout();
        } catch (ServletException e) {
            context.addMessage(null, new FacesMessage("Logout failed."));
        }
    }
}

P.S: I'm really disappointed about oracle's f***ed up documentation since it contains many logical errors, typos and copy/paste errors. It's unstructured, hard to read and overloaded. (sorry but that had to be said)


Solution

  • This is hilarious, after hours of testing and writing this question I found the answer one minute after posting it:

    I activated "Standard-Principal auf Rollenzuordnung" (Standard-Principal to Rolemapping) in server-config/security and now it works.