I have created a custom login page for a legacy java web app using Spring Security and a JSP page. The legacy app does NOT use Spring MVC. I preview it in MyEclipse and it applies my CSS styles. But when I run it in debug mode and look at it with Firefox it has problems. 1) The CSS is not rendered. 2) After submitting the form, it gets redirected to the CSS file, so the browser shows the text of the CSS file!
I've been over this for a couple of days, and haven't found a solution on this site or any other. I've never had to use JSP or Spring Security before, so I'm not even sure of the culprit. Can anyone point out where I'm screwing up?
My login.jsp file:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" session="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:url value="/user_pass_login" var="loginUrl"/>
<html>
<HEAD>
<link href="Tracker.css" type="text/css" rel="stylesheet">
<TITLE>ATP3 Login</TITLE>
</HEAD>
<body onload='document.loginForm.username.focus();'>
<DIV id="login_body"
align="center" >
<h1>Sample Tracker Login</h1>
<form id="loginForm" name="loginForm" action="${loginUrl}" method="post">
<c:if test="${param.error != null}">
<div class="alert alert-error">
Failed to login.
<c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">
<BR /><BR />Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
</c:if>
</div>
</c:if>
<c:if test="${param.logout != null}">
<div class="alert alert-success">You have been logged out.</div>
</c:if>
<BR />
<label for="username">Username:</label>
<input
type="text"
id="username"
name="username" />
<BR />
<BR />
<label for="password">Password: </label>
<input
type="password"
id="password"
name="password" />
<BR />
<BR />
<div class="form-actions">
<input
id="submit"
class="btn"
name="submit"
type="submit"
value="Login" />
</div>
</form>
</DIV>
</body>
</html>
After logging in I get redirected to the url for my CSS file, Tracker.css:
/** Add css rules here for your application. */
/** Example rules used by the template application (remove for your app) */
h1 {
font-size: 2em;
font-weight: bold;
color: #000555;
margin: 40px 0px 70px;
text-align: center;
}
#login_body, #formLogin {
color: #000555;
background-color: #F6FCED;
}
.sendButton {
display: block;
font-size: 16pt;
}
/** Most GWT widgets already have a style name defined */
.gwt-DialogBox {
width: 400px;
}
...
After thinking about what @Santosh Joshi said, I reviewed the security settings within my Spring Security configuration XML file. And here is what was happening:
- When the login.jsp first loads it doesn't have access to the Tracker.css file, because the security settings prevent it (see below for the corrected file), so the page isn't formatted.
- When the user successfully logs in, the CSS file is found, but since the JSP is malformed, it just spews the CSS file.
The Fix
- I modified the login.jsp as follows:
- Remove line 1 with xml definition
- Move line 4 with a url variable declaration to just above the form tag
- Add an html document type definition just below the JSP directives
I added a permission line to the Spring Security XML http tag
The new login.jsp file
<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" session="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<HEAD>
<link href="Tracker.css" type="text/css" rel="stylesheet">
<TITLE>ATP3 Login</TITLE>
</HEAD>
<body onload='document.loginForm.username.focus();'>
<DIV id="login_body"
align="center" >
<h1>Sample Tracker Login</h1>
<c:url value="/user_pass_login" var="loginUrl"/>
<form id="loginForm" name="loginForm" action="${loginUrl}" method="post">
<c:if test="${param.error != null}">
<div class="alert alert-error">
Failed to login.
<c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">
<BR /><BR />Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
</c:if>
</div>
</c:if>
<c:if test="${param.logout != null}">
<div class="alert alert-success">You have been logged out.</div>
</c:if>
<BR />
<label for="username">Username:</label>
<input
type="text"
id="username"
name="username" />
<BR />
<BR />
<label for="password">Password: </label>
<input
type="password"
id="password"
name="password" />
<BR />
<BR />
<div class="form-actions">
<input
id="submit"
class="btn"
name="submit"
type="submit"
value="Login" />
</div>
</form>
</DIV>
</body>
</html>
Here is a snippet from the security XML file. Note the new intercept-url tag for Tracker.css:
<!-- This is where we configure Spring-Security -->
<http auto-config="true"
use-expressions="true"
disable-url-rewriting="true">
<intercept-url pattern="/"
access="permitAll"/>
<intercept-url pattern="/login*"
access="permitAll"/>
<intercept-url pattern="/login*/*"
access="permitAll"/>
<intercept-url pattern="/favicon.ico"
access="permitAll"/>
<intercept-url pattern="/Tracker.css"
access="permitAll"/>
<intercept-url pattern="/**"
access="hasAnyRole('ROLE_ADMIN','ROLE_WRITE','ROLE_READ')"/>
<form-login login-page="/login.jsp"
login-processing-url="/user_pass_login"
username-parameter="username"
password-parameter="password" />
</http>