JAAS JDBCRealm with JPA entities does not work

1

I want to use JAAS in my project, configuring a JDBCRealm through JPA entities. The authentication seems to work correctly, for example, I try to access facelet /admin/analysis.xhtml and redirect me to facet login.xhtml . When I enter the username and password the user shows me an error page 403 of glassfish indicating that I am not allowed to access. But this user does have assigned the role Administrator in the roles table.

Next I expose all the configuration:

JPA entities:

@Entity(name = "USERS")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "USER_NAME")
    private String userName;
    @Column(name = "PASSWD", length = 32, 
            columnDefinition = "VARCHAR(32)")
    private char[] password;
    @OneToOne(fetch = FetchType.EAGER, 
      cascade = CascadeType.ALL, mappedBy = "user")
    private Role role;
    private String name;
    private String lastname;
    @ManyToOne
    private Province province;

    public User() {
    }

    public User(String userName, char[] password, ROLE role) {
        this.userName = userName;
        this.password = hashPassword(password);
        this.role = new Role(role, this);
    }

    public char[] getPassword() {
        return password;
    }

    public void setPassword(char[] password) {
        this.password = hashPassword(password);
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
        role.setUser(this);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public Province getProvince() {
        return province;
    }

    public void setProvince(Province province) {
        this.province = province;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final User other = (User) obj;
        if ((this.userName == null) ? (other.userName != null) : 
                    !this.userName.equals(other.userName)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 83 * hash + (this.userName != null ? this.userName.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return "User{" + "userName=" + userName + ", password=" + password + ", role=" + role + '}';
    }



    private char[] hashPassword(char[] password) {
        char[] encoded = null;
        try {
            ByteBuffer passwdBuffer = 
              Charset.defaultCharset().encode(CharBuffer.wrap(password));
            byte[] passwdBytes = passwdBuffer.array();
            MessageDigest mdEnc = MessageDigest.getInstance("MD5");
            mdEnc.update(passwdBytes, 0, password.length);
            encoded = new BigInteger(1, mdEnc.digest()).toString(16).toCharArray();
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(User.class.getName()).log(Level.SEVERE, null, ex);
        }

        return encoded;
    }
}



@Entity(name = "ROLES")
public class Role implements Serializable {

    public static enum ROLE {
        ADMINISTRATOR, USER
    }

    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "ROLE_NAME")
    @Enumerated(EnumType.STRING)
    private ROLE role;
    @Id
    @OneToOne
    @JoinColumn(name = "USER_NAME")
    private User user;

    protected Role() {
    }

    protected Role(ROLE role, User user) {
        this.role = role;
        this.user = user;
    }

    public ROLE getRole() {
        return role;
    }

    public void setRole(ROLE role) {
        this.role = role;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Role other = (Role) obj;
        if (this.role != other.role) {
            return false;
        }
        if (this.user != other.user && (this.user == null || 
                    !this.user.equals(other.user))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 89 * hash + (this.role != null ? this.role.hashCode() : 0);
        hash = 89 * hash + (this.user != null ? this.user.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return "Role{" + "role=" + role + ", user=" + user + '}';
    }


} 

The JDBCRealm:

And finally the deployment descriptor configuration of the web layer:

<security-constraint>
   <display-name>Security Constraints</display-name>
   <web-resource-collection>
      <web-resource-name>Only Admin</web-resource-name>
      <description>only admin resources</description>
      <url-pattern>/admin/*</url-pattern>
   </web-resource-collection>
   <auth-constraint>
      <description/>
      <role-name>ADMINISTRATOR</role-name>
   </auth-constraint>
</security-constraint>
<login-config>
   <auth-method>FORM</auth-method>
   <realm-name>JDBCRealm</realm-name>
   <form-login-config>
      <form-login-page>/login.xhtml</form-login-page>
      <form-error-page>/login-error.xhtml</form-error-page>
   </form-login-config>
</login-config>
<security-role>
   <description>Administradores</description>
   <role-name>ADMINISTRATOR</role-name>
</security-role>
<security-role>
  <description>Usuario normal</description>
  <role-name>USER</role-name>
</security-role>

The database has the following records:

INSERT INTO SERGIO11.USERS (USER_NAME, LASTNAME, "NAME", PASSWD, PROVINCE_ID) 
    VALUES ('sergio11', 'Sánchez', 'Sergio', 'eaa66f1a644c8a09ca3c584f415c0c49', NULL);

INSERT INTO SERGIO11.ROLES (ROLE_NAME, USER_NAME) 
    VALUES ('ADMINISTRATOR', 'sergio11');

Thank you very much in advance;) !!

    
asked by Sergio Sánchez Sánchez 20.10.2016 в 22:50
source

0 answers