J2EE security and sessions

0

I am using jdbc-realm and the appropriate configuration of web.xml to authenticate certain resources with authentication. The form uses tags j_security_check , j_username and j_password .

Protecting them protects them well, but if I try to login, let's not attack the protected resource, I get an error of

Estado http 400 Referencia directa al formulario de conexión (página de formulario de login) inválida

That is, it does not redirect me to the resource, which by the user role, should go. I use jsf and EJB and I'm totally new with these technologies.

Could someone tell me what I'm missing or what I'm doing wrong?

    
asked by Rak 07.11.2016 в 19:58
source

1 answer

2

When using jdbcRealm , it is good to use security managed by the container , i.e., container-managed-security for authentication and authorization of resources in your app. instead of manipulating it from the code itself, although depending on the requirements, it may be necessary and there is another way to delegate the "login" to the application server.

The server is the one who will be responsible for authenticating and authorizing users depending on their role in the application. and to activate the servlet that handles this process, you have to create a html form according to Servlet specification :

the form should go on a separate page that usually only contains the form to login:

           

Then in the Descriptor de Despliegue (web.xml) we must add the configuration that will tell the server:

  • what are the resources (pages, folders) that will be restricted depending on the role of the user
  • We establish the existant roles
  • We set the route of the login page
  • We establish information protection (SSL)

web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" 
         xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">    


<security-constraint>
    <display-name>Restricción 1</display-name>
    <web-resource-collection>
        <web-resource-name>resources</web-resource-name>
        <description />            
        <url-pattern>/protected/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>appUser</role-name>
        <role-name>appAdmin</role-name>
    </auth-constraint>
</security-constraint>

<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>appRealm</realm-name>
    <form-login-config>
        <form-login-page>/index.xhtml</form-login-page>
        <form-error-page>/public/forbidden.xhtml</form-error-page>
    </form-login-config>
</login-config>


<security-role>
    <role-name>appUser</role-name>
</security-role>


<security-role>
    <role-name>appAdmin</role-name>
</security-role>   

<error-page>
    <error-code>403</error-code>
    <location>/public/forbidden.xhtml</location>
</error-page>

</web-app>

Now we have to map the roles with the groups in the database and this depends a lot on the Server that is being used, for this example I do it with Glassfish

we create a file glassfish-web.xml or sun-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD GlassFish Application Server 3.0 Servlet 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_3_0-0.dtd">
<sun-web-app error-url="">

    <security-role-mapping>
        <role-name>appUser</role-name>
        <group-name>1</group-name>
    </security-role-mapping>

    <security-role-mapping>
        <role-name>appAdmin</role-name>
        <group-name>2</group-name>
    </security-role-mapping>

  <class-loader delegate="true"/>
  <jsp-config>
    <property name="keepgenerated" value="true">
      <description>Keep a copy of the generated servlet class' java code.</description>
    </property>
  </jsp-config>
</sun-web-app>

Now we create the database that will contain the info for this to work:

CREATE TABLE 'tabla_usuarios'(

    correo VARCHAR(255),
    pwd VARCHAR(255) NOT NULL,    
    PRIMARY KEY (correo)

)ENGINE=INNODB DEFAULT CHARACTER SET UTF8;


CREATE TABLE grupos(

    correo VARCHAR(255),
    grupo  VARCHAR(30), 
    PRIMARY KEY(correo)

)ENGINE=INNODB DEFAULT CHARACTER SET UTF8;

These would be the minimum requirements for the DB.

The only thing missing now is to create the realm (realm) on the server.

We open the administration console, localhost:4848 and go to:

Configurations >> Server-Config >> Security >> Realms

We create a new realm:

  • The name must be the same as the one set in realm-name
  • We select from select the option that jdbcRealm has
  • Then we fill in the boxes with the corresponding information:

    • JAAS Context = jdbcRealm
    • JNDI = jndi_name (in glassfish-resources.xml is found)
    • User Table = user_table
    • User Name Column = user_table.mail
    • Password Column = user_table.pwd
    • Group Table = groups
    • Group Table User Name Column = groups.mail
    • Group Name Column = groups.group
    • Password Encryption Algorithm = SHA-256
    • Datablase User = user_to_accesso_a_db
    • Database Password = db_user_password

    The rest of the boxes can be left blank but you have to have one thing in mind, from Glassfish 4.+ this forces us to use an algorithm to encrypt the passwords, so I have put SHA-256 now to save users you have to save your passwords in SHA-256 at the time you register them so that JAAS works.

    To encrypt:

    public static String encriptar(String contrasena) throws NoSuchAlgorithmException{
    
        byte[] bytes = MessageDigest.getInstance("SHA-256").digest(contrasena.getBytes());
    
        return DatatypeConverter.printHexBinary(bytes).toLowerCase();
    }
    
        
    answered by 22.11.2016 в 01:18