Hi everybody. I want to share my approach to authentication using Spring Security 4.2, getting the user credentials from HSQLDB, and with localized messages in the login page, in case someone can benefit from it. It will seem like a very long post, but if you compare to other methods described here and here, you'll see that the amount of coding you need to do to get it working is not that much, and it allows for basic authentication for simpler use cases, presenting a localized login page with some basic messages in case of wrong login information, and even a simple message when you log out.
Note: I don't include relogin nor CSRF protection, because in my case those two things are no required (at least, not in the short-mid future).
1. Create two tables in your HSQLDB engine:
Code:
CREATE TABLE IF NOT EXISTS users ( username VARCHAR(50) NOT NULL, password VARCHAR(50) NOT NULL, mode VARCHAR(50) NOT NULL, language VARCHAR(50) NOT NULL, enabled BOOLEAN NOT NULL, CONSTRAINT users_pk PRIMARY KEY (username) ) CREATE TABLE IF NOT EXISTS authorities ( username VARCHAR(50) NOT NULL, authority VARCHAR(50) NOT NULL, FOREIGN KEY (username) REFERENCES users(username) )
Code:
insert into users(username,password,mode,language,enabled) values ('user','abc','basic','es',TRUE) insert into authorities(username,AUTHORITY) values ('user', 'ROLE_USER')
Code:
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <!-- Basic security configuration --> <http auto-config="true" use-expressions="true"> <!-- Security exceptions to allow proper login page resource loading --> <intercept-url pattern="/resources/**" access="permitAll"/> <intercept-url pattern="/login.jsp*" access="permitAll"/> <intercept-url pattern="/**" access="hasRole('ROLE_USER')" /> <form-login login-page="/login.jsp" default-target-url="/myApp.html" always-use-default-target="true" authentication-failure-url="/login.jsp?error" username-parameter="username" password-parameter="password" /> <logout logout-url="/logout" logout-success-url="/login.jsp?logout" /> <!-- disable csrf protection --> <csrf disabled="true"/> </http> <!-- Specify the dataSource used for validating user login information with HSQLDB --> <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <beans:property name="driverClassName" value="org.hsqldb.jdbcDriver"/> <beans:property name="url" value="jdbc:hsqldb:hsql://localhost/myApp" /> <beans:property name="username" value="sa" /> <beans:property name="password" value="" /> </beans:bean> <!-- Define the queries required to validate users stored in HSQLDB's DB --> <authentication-manager> <authentication-provider> <jdbc-user-service data-source-ref="dataSource" users-by-username-query="select username,password, enabled from users where username=?" authorities-by-username-query="select username, authority from authorities where username =? " /> </authentication-provider> </authentication-manager> <!-- OPTIONAL: Specify the resources to be used for login page localization --> <beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <!-- MyAppRerources is the 'base name' for all my .properties files which contain the translated texts in the login page --> <beans:property name="basename" value="classpath:/co/myCompany/myApp/shared/i18n/MyAppResources" /> <beans:property name="defaultEncoding" value="UTF-8" /> </beans:bean> </beans:beans>
Code:
<!-- Default page to serve: note that this isn't your default html page anymore... --> <!-- That page is going to be the one you go to after you authenticate, and it's configured above in --> <!-- applicationContext.xml using default-target-url="/myApp.html" --> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> <!-- Servlets --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Code:
<%@page isELIgnored ="false" %> <%@page contentType="text/html;charset=UTF-8" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@taglib prefix="spring" uri="http://www.springframework.org/tags" %> <html> <head> <title>My App</title> <link href="<%= request.getContextPath() %>/resources/css/login.css" rel="stylesheet" type="text/css" /> </head> <body class="login t_center" onload="document.f.username.focus();"> <div class="content-login clearfix"> <div class="content-display clearfix"> <div class="log-in clearfix;"> <img class="logo-login" src="<%= request.getContextPath() %>/resources/images/login_logo.png" alt="App Logo" /> <div class="top-log-in"> </div> <div class="body-log-in clearfix"> <h2 class="header-login"><spring:message code="login"/></h2> <form name="f" action="/login" method="POST"> <label><spring:message code="userName"/></label> <input id="username" type="text" name="username" /> <label><spring:message code="password"/></label> <input id="password" type="password" name="password" /> <c:if test="${param.error != null}"> <div> <label><spring:message code="wrongLogin"/></label> </div> </c:if> <c:if test="${param.logout != null}"> <div class="alert alert-success"> <label><spring:message code="logoutSuccessfull"/></label> </div> </c:if> <input class="login-button" name="submit" type="submit" value="<spring:message code="submit"/>"/> </form> </div> <div class="bottom-log-in"> </div> </div> <input id="wrongLogin" type="text" value="<spring:message code="wrongLogin"/>" style="display: none;"/> <input id="logoutSuccessfull" type="text" value="<spring:message code="logoutSuccessfull"/>" style="display: none;"/> </div> </div> </body> </html>
6.1 MyAppResources_en.properties
Code:
userName = User password = Password login = User Login submit = Login wrongLogin = Wrong user or password! logoutSuccessfull = Successful logout!
Code:
userName = Usuario password = Clave login = Ingreso de Usuarios submit = Ingresar wrongLogin = Usuario o clave incorrectos! logoutSuccessfull = Fin de sesión exitoso!
Comment