Login issue with DatabaseServerLoginModule in JBos

2020-05-02 13:21发布

问题:

I get a ServeletException: Failed to authenticate a principal when I attempt to login with the DatabaseServerLoginModule. I'm guessing the issue is either how passwords are written to the db or the rolesQuery that is incorrect. I certainly can use suggestions on how to troubleshoot at this point. Here is my setup:

login-config.xml

<application-policy name = "Avengers">
  <authentication>
    <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required">
       <module-option name = "dsJndiName">java:/jdbc/thor_ds</module-option>
       <module-option name = "principalsQuery">SELECT password FROM usertable WHERE username = ?</module-option>
       <module-option name="rolesQuery" value="SELECT groupid, 'Roles' FROM grouptable WHERE username=?" />
       <!--<module-option name="rolesQuery" value="SELECT gt.groupid as 'userRoles', gt.groupid as 'Roles' FROM grouptable as gt WHERE username=?" />-->
       <module-option name="hashAlgorithm">MD5</module-option>
       <module-option name="hashEncoding">base64</module-option>
    </login-module>
  </authentication>
</application-policy>  

jboss-web.xml

<jboss-web>
  <context-root>/Avengers</context-root>
  <security-domain>java:/jaas/Avengers</security-domain>
</jboss-web>

mysql-init.sql

create table usertable (
    username varchar(128) NOT NULL PRIMARY KEY,
    password varchar(128) NOT NULL,
    email varchar(128) NOT NULL,
    firstname varchar(128) NOT NULL,
    lastname varchar(128) NOT NULL
);

create table grouptable(
    username varchar(128) NOT NULL,
    groupid  varchar(128) NOT NULL,
    CONSTRAINT GROUP_PK PRIMARY KEY(username, groupid),
    CONSTRAINT USER_FK FOREIGN KEY(username) REFERENCES usertable(username)
        ON DELETE CASCADE ON UPDATE RESTRICT
);

insert into usertable(username,password,email,firstname,lastname) 
    values ('admin', '21232f297a57a5a743894a0e4a801fc3','','','');
insert into grouptable(username,groupid) values ('admin', 'USER');
insert into grouptable(username,groupid) values ('admin', 'ADMIN');

Snippet from web.xml

<security-constraint>
    <display-name>Admin</display-name>
    <web-resource-collection>
        <web-resource-name>Admin Views</web-resource-name>
        <url-pattern>/admin/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>USER</role-name>
        <role-name>ADMIN</role-name>
    </auth-constraint>
</security-constraint>
<security-constraint>
    <display-name>Compass Web</display-name>
    <web-resource-collection>
        <web-resource-name>Monitoring Module</web-resource-name>
        <url-pattern>/monitor/*</url-pattern>
    </web-resource-collection>
    <web-resource-collection>
        <web-resource-name>Core Web Module</web-resource-name>
        <url-pattern>/main/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>USER</role-name>
        <role-name>ADMIN</role-name>
    </auth-constraint>
</security-constraint>
<security-constraint>
    <display-name>Login</display-name>
    <web-resource-collection>
        <web-resource-name>Login Pages</web-resource-name>
        <url-pattern>/login/*</url-pattern>
    </web-resource-collection>
</security-constraint>
<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>avengers</realm-name>
    <form-login-config>
        <form-login-page>/login/login.xhtml</form-login-page>
        <form-error-page>/login/error.xhtml</form-error-page>
    </form-login-config>
</login-config>
<security-role>
    <description/>
    <role-name>ADMIN</role-name>
</security-role>
<security-role>
    <description/>
    <role-name>USER</role-name>
</security-role>

My UserBean.login()

public String login() {

    System.out.println("user "+username+" is attempting to login...");

    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
    try {
        request.login(this.username, this.password);
        this.cUser = Utils.getEntityManager().find(MyUser.class, username);
        System.out.println("User "+username+" successfully logged in...");
    } catch (ServletException e) {
        // Handle unknown username/password in request.login().
        context.addMessage(null, new FacesMessage("Invalid Login Credentials"));
        System.err.println("Invalid Login Credentials");
        e.printStackTrace();

        return "/login/error.xhtml";
    }

    return "/main/index.xhtml";
}

回答1:

I was able to get help with this on the jboss as forums. My solution was to revise the markup of the rolesQuery from:

<module-option name="rolesQuery" 
    value="SELECT groupid, 'Roles' FROM grouptable WHERE username=?" />

to this:

<module-option name="rolesQuery">
   SELECT groupid, 'Roles' FROM grouptable WHERE username=?
</module-option>

I also had to change the encoding style to HEX. Here is my working login-config.xml.

<application-policy name="Avengers">
    <authentication>
       <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required">
          <module-option name="dsJndiName">java:/jdbc/thor_ds</module-option>
          <module-option name="principalsQuery">SELECT password FROM usertable WHERE username = ?</module-option>
          <module-option name="rolesQuery">SELECT groupid, 'Roles' FROM grouptable WHERE username=?</module-option>
          <module-option name="hashAlgorithm">MD5</module-option>
          <module-option name="hashEncoding">HEX</module-option>
          <!--<module-option name="hashEncoding">base64</module-option>-->
       </login-module>
    </authentication>
 </application-policy>