Spring Custom AuthenticationProvider never invoked - 404 error on http://localhost:8080/igloo/j_spring_security_check - spring

I am trying to get an example of custom j_spring_security_check working on tomcat 7.0.47. Spring MVC goes to login page ok but gives error after clicking submit - what I am expecting is spring to fill in the user roles and then go to main.jsp.
spring main config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<!-- ############################################# -->
<context:component-scan base-package="frostbyte.igloo" />
<!-- ############################################# -->
<mvc:resources mapping="/resources/**" location="/resources/"/>
<!-- ############################################# -->
<mvc:annotation-driven/>
<!-- ############################################# -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- ############################################# -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages"></property>
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
<!-- ############################################# -->
</beans>
spring security config:
<?xml version="1.0" encoding="UTF-8"?>
<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-3.2.xsd">
<!-- ############################################# -->
<beans:bean id="FrostByteAuthenticationProvider" class="frostbyte.igloo.jsp.custom.FrostByteAuthenticationProvider"></beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="FrostByteAuthenticationProvider"></authentication-provider>
</authentication-manager>
<!-- ############################################# -->
<http auto-config="true" use-expressions="true">
<form-login login-processing-url="/login"
login-page="/login"
default-target-url="/main"
username-parameter="j_username"
password-parameter="j_password"
authentication-failure-url="/login?auth=fail"/>
<intercept-url pattern="/login" access="permitAll"></intercept-url>
<intercept-url pattern="/logout" access="permitAll"></intercept-url>
<intercept-url pattern="/**" access="hasRole('ADMIN')"/>
<logout logout-url="/logout" logout-success-url="/logout_success"></logout>
</http>
<!-- ############################################# -->
</beans:beans>
the AuthenticationProvider (non of these log messages ever get printed) :
package frostbyte.igloo.jsp.custom;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import frostbyte.common.FrostbyteRole;
import frostbyte.common.FrostbyteUser;
public class FrostByteAuthenticationProvider implements AuthenticationProvider
{
private static final Logger LOG = Logger.getLogger(FrostByteAuthenticationProvider.class);
#Override
public boolean supports(Class<?> authentication)
{
LOG.error("FrostByteAuthenticationProvider : supports : Marker 1");
System.out.println("FrostByteAuthenticationProvider : supports : Marker 1");
return true;
}
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException
{
LOG.error("FrostByteAuthenticationProvider : authenticate : Marker 1");
System.out.println("FrostByteAuthenticationProvider : authenticate : Marker 1");
Authentication rtn = null;
String username = authentication.getName();
String password = authentication.getCredentials().toString();
LOG.error("FrostByteAuthenticationProvider : authenticate : Marker 10 : username = "+username);
LOG.error("FrostByteAuthenticationProvider : authenticate : Marker 20 : password = "+password);
FrostbyteUser user = new FrostbyteUser(); //for test everything validates
user.setUsername(username);
user.getRoles().add(new FrostbyteRole("ADMIN"));
LOG.debug("Authenticate : Marker 100");
//if (user.getUsername().equalsIgnoreCase("username"))
if (true)
{
LOG.debug("Authenticate : Marker 200");
if (true)
//if (password.equalsIgnoreCase(user.getPassword()))
{
LOG.debug("Authenticate : Marker 300");
List<GrantedAuthority> grants = new ArrayList<GrantedAuthority>();
for (FrostbyteRole _role:user.getRoles())
{
if (_role.equals("ADMIN"))
{
for ( String __role : _role.getRoles() )
{
grants.add(new SimpleGrantedAuthority(__role.toUpperCase()));
}
}
}
rtn = new UsernamePasswordAuthenticationToken(username, password, grants);
LOG.debug("Authenticate : Marker 898,000 : rtn = "+ rtn);
}
LOG.debug("Authenticate : Marker 899,000 : rtn = "+ rtn);
}
LOG.debug("Authenticate : Marker 900,000 : rtn = "+ rtn);
return rtn;
}
}
the login jsp:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%# include file="/WEB-INF/jsp/include.jsp" %>
<meta http-equiv="pragma" content="no-cache">
<html>
<head>
<title></title>
<link rel="stylesheet" href="resources/styles.css" type="text/css" media="screen" />
<style type="text/css"></style>
</head>
<body>
request.getAttribute("message") = <%= request.getAttribute("message") %>
<br />
request.getParameter("message") = <%= request.getParameter("message") %>
<form action="<c:url value = "/j_spring_security_check" />" method="post">
<br /><br /><br />
<br /><br /><br />
<br />
<div class="containerCenterAlign">
<div class="container">
<div class="titleClass">Igloo<br /><div class="errorMessage"><%= message %></div></div>
<ul class="loginUL">
<li class="loginLeft">
<label class="loginLabel" for="j_username">Username</label>
<input id="username" name="j_username" class="loginText" type="text" value="" maxlength="150" />
<label class="loginLabel" for="j_password">Password</label>
<input id="password" name="j_password" class="loginText" type="password" value="" maxlength="150" />
</li>
<li class="loginRight">
<input type="submit" name="submit" id="submit" value="Login" class="loginSubmit" />
</li>
</ul>
<div style="clear: both; height: 2px;"></div>
</div>
</div>
</form>
</body>
</html>
include.jsp:
<%# page language="java" contentType="text/html;charset=UTF-8"%>
<%# page session="false"%>
<%# page import="java.io.*" %>
<%# page import="java.util.*" %>
<%# page import="frostbyte.*" %>
<%# page import="org.apache.log4j.*" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%# taglib prefix="s" uri="http://www.springframework.org/tags"%>
<%# taglib prefix="sform" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="frostbyte" uri="http://frostbyte/tags" %>

I managed to stumble across the fix by removing
login-processing-url="/login"
I am posting these results here since its almost impossible to find good spring tutorials, even in the 4 spring books I have. Note I also had to add filter for the resources

Related

spring MVC MAVEN: Static resource With 404

I have searched for this but didn't get the solution for the same. I got information i.e. we have to use <mvc:resources location="/resources/" mapping="/resources/**"/> and place all the static member like css/img/js inside resources folder
src
|--main
| |
| |--java
| |--resources
| |--webapp
And then we have to use either jstl or spring tags to map the resources as below:
<head>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<spring:url value="/resources/LoginForm.css" var="loginCss" />
<link rel="stylesheet" href="${loginCss}" type="text/css" />
</head>
I have developed some code by keeping all the points in mind but getting 404 error for static resources.
click here for project structure
code for dispatcher servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
">
<mvc:annotation-driven/>
<context:component-scan base-package="com.anand" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages" />
</bean>
<mvc:resources location="/resources/" mapping="/resources/**"/>
<mvc:default-servlet-handler />
</beans>
Code for loginform.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Home-Login</title>
<spring:url value="/resources/LoginForm.css" var="loginCss" />
<spring:url value="/resources/logo1.PNG" var="logo1" />
<spring:url value="/resources/img1.png" var="img1" />
<spring:url value="/resources/img2.png" var="img2" />
<spring:url value="/resources/img3.png" var="img3" />
<link rel="stylesheet" href="${loginCss}" type="text/css" />
</head>
<body class="login">
<!-- header starts here -->
<div id="facebook-Bar">
<div id="facebook-Frame">
<div id="logo"> <img src="${logo1}" /></div>
<div id="header-main-right">
<div id="header-main-right-nav">
<form:form action="loginform.html" method="post" commandName="loginform">
<table border="0" style="border:none">
<tr>
<td ><form:input type="text" tabindex="1" path="userName" placeholder="UserName" class="inputtext radius1" value="" /></td>
<td ><form:input type="password" tabindex="2" path="password" placeholder="Password" class="inputtext radius1" /></td>
<td ><input type="submit" class="fbbutton" name="login" value="Login" /></td>
</tr>
<tr>
<td><label>
<input id="persist_box" type="checkbox" name="persistent" />
<span style="color:#ccc;">Keep me logged in</span></label></td>
<td><label>forgot your password?</label></td>
</tr>
</table>
</form:form>
</div>
</div>
</div>
</div>
<div class="slideshow-container" style="width:100%;height:80%; min-width:1000px;">
<div class="mySlides fade" style="width:100%;height:100%">
<div class="numbertext">1 / 3</div>
<img src="${img1}" style="width:100%;height:100%" />
<div class="text">Caption Text</div>
</div>
<div class="mySlides fade" style="width:100%;height:100%">
<div class="numbertext">2 / 3</div>
<img src="${img2}" style="width:100%;height:100%" />
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade" style="width:100%;height:100%">
<div class="numbertext">3 / 3</div>
<img src="${img3}" style="width:100%;height:100%" />
<div class="text">Caption Three</div>
</div>
</div>
<br/>
<div style="text-align:center">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
</div>
<script>
var slideIndex = 0;
showSlides();
function showSlides() {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex> slides.length) {slideIndex = 1}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
setTimeout(showSlides, 2000); // Change image every 2 seconds
}
</script>
</body>
</html>
When it redirects me to loginform.jsp and i do F12-->network analysis, it shows me 404 for static resources like ,img1,img2,img3,logo1 and for .css file.
Click Here for F12 debug and chrome view of page without css
[[Solved]]: Finally solved the problem but i'm not sure the approach i have used here is correct or not but yeah it's working for me. Solution: i have copied the resources folder under webapp folder (i.e. WEB_INF & resources are siblings).
Click here for updated directory structure image
Please do provide better solution of this if you have for the same:
Resources inside WEB-INF are protected to be not accessible directly from the client.
In general, if it is static resources such as html, CSS, JavaScript can be placed outside WEB-INF. Static content placed outside can be therefore downloaded directly from the client browser.
Pls read Referencing a resource placed in WEB-INF folder in JSP file returns HTTP 404 on resource

No mapping found for HTTP request with URI [/.../j_spring_security_check] in DispatcherServlet with name 'servlet-dispatcher'

Plop,
Spring version: 4.0.2.RELEASE
Spring Security Version: 4.0.2.RELEASE
DB PostgreSQL Version: 9.4-1202-jdbc42
I'm trying to acces to my home page with a secure connection using spring-security.
When I try to connect with login/password I've got this error:
WARNING: No mapping found for HTTP request with URI
[/web-client-smarteo/j_spring_security_check] in DispatcherServlet
with name 'servlet-dispatcher'
When I submit with log/pass it's get me to:
http://localhost:8080/web-client-smarteo/j_spring_security_check?username=alfacamp&password=alfacam&submit=&%24%7B_csrf.parameterName%7D=%24%7B_csrf.token%7D
And show
HTTP 404 The requested ressource is unvailable
Details of my sample:
UPDATE
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dispatcher-servlet.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Spring Security Filter -->
<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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>servlet-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>servlet-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
dispatcher-servlet.xml
<mvc:annotation-driven />
<context:component-scan base-package="com.smarteo.laugustoni.*" />
[...]
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/vues/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
spring-security.xml
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/welcome**" access="hasRole('CUSTOMER')" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login
login-page="/connection"
default-target-url="/welcome"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/connection?error"
username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/connection?logout" />
<!-- enable csrf protection -->
<csrf/>
</http>
<!-- Select users and user_roles from database -->
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query=
"select usr_name,usr_password from smarteo_user where usr_name=?"
authorities-by-username-query=
"select usr_name, usr_role from smarteo_user where usr_name =? " />
</authentication-provider>
</authentication-manager>
ConnectionController.java
package com.smarteo.laugustoni.controller;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.smarteo.laugustoni.services.User.IServiceUser;
#Controller
public class ConnectionController {
#RequestMapping(value={"/", "/welcome**"}, method = RequestMethod.GET)
public String defaultPage(ModelMap pModel)
{
return "connection";
}
#RequestMapping(value="/connexion", method = RequestMethod.GET)
public ModelAndView connection(
#RequestParam(value="error", required = false) String error,
#RequestParam(value = "logout", required = false)String logout)
{
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
model.setViewName("connection");
return model;
}
Thanks for helping.
EDIT 1
connection.jsp
<%#page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#page session="true"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
<form name="loginForm" action="/j_spring_security_check">
<!-- TextBox Section -->
<div class="input-group visible">
<spring:message code="connection.label.account"/>
<input name="username" path="username" placeholder="Nom du compte" type="text" class="form-control" aria-describedby="basic-addon1"/>
<div class="alert alert-danger" role="alert"><form:errors path="username" cssclass="error"/></div>
</div><br />
<div class="input-group visible">
<spring:message code="connection.label.password"/>
<input name="password" path="password" placeholder="Mot de passe" type="password" class="form-control" aria-describedby="basic-addon1"/><br />
<div class="alert alert-danger" role="alert"><form:errors path="password" cssclass="error"/></div>
</div><br />
<!-- TextBoxSection -->
<!-- Button Section -->
<button name="submit" type="submit" class="btn btn-default visible">
<spring:message code="connection.button.label.connect"/>
</button><br />
<!-- Button Section -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
</body>
EDIT 2:
I'm now using:
<form name="loginForm" action="<c:url value='/login' />" method="POST" >
I had also change my spring-security.xml:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/welcome**" access="hasRole('CUSTOMER')" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login
login-page="/login"
default-target-url="/welcome**"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/login?logout" />
<!-- enable csrf protection -->
<csrf/>
</http>
And my ConnectionController.java
#RequestMapping(value = "/welcome**", method = RequestMethod.GET)
public String defaultPage()
{
return "home";
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(
#RequestParam(value = "error", required = false) String error,
#RequestParam(value = "logout", required = false) String logout)
{
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
model.setViewName("connection");
return model;
}
#RequestMapping(value = "/403", method = RequestMethod.GET)
public ModelAndView accesssDenied() {
ModelAndView model = new ModelAndView();
//check if user is login
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (!(auth instanceof AnonymousAuthenticationToken)) {
UserDetails userDetail = (UserDetails) auth.getPrincipal();
model.addObject("username", userDetail.getUsername());
}
model.setViewName("403");
return model;
}
I'm now getting State HTTP 405 - Request method 'POST' not supported when I'm trying to login
My problem was due to spring security version.
Indeed for 4.x you have to put the csrf in your form action.
My sources modified with the solution:
connection.jsp
<form name="loginForm" action="<c:url value='/login?${_csrf.parameterName}=${_csrf.token} }' />" method="POST" >
<!-- TextBox Section -->
<div class="input-group visible">
<spring:message code="connection.label.account"/>
<input name="username" path="username" placeholder="Nom du compte" type="text" class="form-control" aria-describedby="basic-addon1"/>
<!--<div class="alert alert-danger" role="alert"><form:errors path="username" cssclass="error"/></div>-->
</div><br />
<div class="input-group visible">
<spring:message code="connection.label.password"/>
<input name="password" path="password" placeholder="Mot de passe" type="password" class="form-control" aria-describedby="basic-addon1"/><br />
<!--<div class="alert alert-danger" role="alert"><form:errors path="password" cssclass="error"/></div>-->
</div><br />
<!-- TextBoxSection -->
<!-- Button Section -->
<input name="submit" type="submit" class="btn btn-default visible" value=<spring:message code="connection.button.label.connect"/> />
<br />
<!-- Button Section -->
</form>
spring-security.xml:
<http auto-config="true" >
<intercept-url pattern="/welcome**" access="hasRole('CUSTOMER')" />
<form-login login-page="/login"
default-target-url="/welcome"
username-parameter="username"
password-parameter="password"
authentication-failure-url="/403" />
<!-- enable csrf protection -->
<csrf disabled="true"/>
</http>

why authentication-failure-url in spring security not working

I am using spring security in my website, but when I used custom login form (JSF form), and user entered bad credentials, authentication-failure-url is not working and user is not forwarded to failed.xhtml, but index.xhtml is appeared
I don't know the reason, please help:
applicationContext.xml:
<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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
<context:component-scan base-package="com.myspring" />
<context:annotation-config />
<!-- beans configuration -->
<beans:bean id="userBo" class="com.myspring.user.bo.impl.UserBoImpl" />
<!-- security configuration -->
<http auto-config="true">
<intercept-url pattern="/login.xhtml" access="permitAll" />
<intercept-url pattern="/index.xhtml" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/authenticated.xhtml" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/views/admin/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/login.xhtml" default-target-url="/authenticated.xhtml"
authentication-failure-url="/failed.xhtml" />
<logout invalidate-session="true" delete-cookies="true" logout-success-url="/"/>
<csrf disabled="true" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="user1" password="user1Pass" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
login.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
</h:head>
<h:body>
<div style="">
<h:form id="loginFormId" prependId="false">
<div id="loginFieldsPnlId">
<div id="loginFieldUsrContId">
<h:outputText id="outTxtUserNameId" value="Username: "
name="outTxtUserNameNm"></h:outputText>
<h:inputText id="userName" required="true"
value="#{loginController.userName}"
requiredMessage="Please enter username"></h:inputText>
<h:outputLabel id="outLblUserNameId" for="userName"
name="outLblUserNameNm"></h:outputLabel>
</div>
<div id="loginFieldPassContId">
<h:outputText id="outTxtPasswordId" value="Password: "
name="outTxtPasswordNm"></h:outputText>
<h:inputSecret id="password" required="true"
value="#{loginController.password}"
requiredMessage="Please enter password" name="inTxtPasswordNm"></h:inputSecret>
<h:outputLabel id="outLblPasswordId" for="password"
name="outLblPasswordNm"></h:outputLabel>
</div>
</div>
<div id="loginBtnPanelId">
<h:commandButton id="btnLoginId" value="Login"
action="#{loginController.login}" styleClass="loginPanelBtn"></h:commandButton>
<h:commandButton id="btnCancelId" value="Cancel"
action="#{loginController.cancel}" styleClass="loginPanelBtn"
immediate="true" update="loginFormId"></h:commandButton>
</div>
</h:form>
</div>
<div>
<h:messages></h:messages>
</div>
</h:body>
</html>
and this is the loginController with login method:
package com.myspring.controllers;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
#ManagedBean
#SessionScoped
public class LoginController {
private String userName;
private String password;
#ManagedProperty(value="#{authenticationManager}")
private AuthenticationManager authenticationManager = null;
public String login() {
try {
Authentication request = new UsernamePasswordAuthenticationToken(this.getUserName(), this.getPassword());
Authentication result = authenticationManager.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
} catch (AuthenticationException e) {
e.printStackTrace();
return "failed";
}
return "success";
}
public String logout(){
SecurityContextHolder.clearContext();
return "loggedout";
}
public AuthenticationManager getAuthenticationManager() {
return authenticationManager;
}
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
public String cancel()
{
return "";
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
also I will add project structure:
Due to the fact that you are using JSF you are basically bypassing the login (and logout) functionality provided by Spring Security. Your LoginController is basically replacing that, due to that your sec:login-form and sec:legato are pretty much useless.
The solution is simple don't use JSF, you can still use Facelets to render your page, but simply include a normal form tag which posts to /login instead of an h:form tag and you can remove your LoginController.
Note: If your application is not the root application (i.e. mapped to /) you need to include the /context-path into your URL. So instead of /login use /context-path/login.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
</h:head>
<h:body>
<div style="">
<form id="loginFormId" method="post" action="/login">
<div id="loginFieldsPnlId">
<div id="loginFieldUsrContId">
<label>Username:<label>
<input type="text" id="username" name="username" />
</div>
<div id="loginFieldPassContId">
<label>Password:<label>
<input type="password" id="password" name="password" />
</div>
</div>
<div id="loginBtnPanelId">
<button>Login</button>
</div>
</form>
</div>
</h:body>
</html>
If you still want to use JSF and the LoginController then don't directly use the AuthenticationManager but forward the request to the /login URL that way Spring Security will take over after JSF has done the required validation.

Hibernate null pointer exception

I'm getting a null pointer exception at the following line in my DAO:
Session session = sessionFactory.getCurrentSession();
I'm not entirely sure why as I print to the console the correct values using the session/sessionFactory instances but when I try to output the same values in my jsp I get the null pointer exception.
My xml configuration:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"`
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:annotation-config></context:annotation-config>
<context:component-scan base-package="com.sga.app.dao"></context:component-scan>
<jee:jndi-lookup jndi-name="jdbc/springSgaDb" id="dataSource"
expected-type="javax.sql.DataSource">
</jee:jndi-lookup>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.sga.app.beans</value>
<value>com.sga.app.dao</value>
</list>
</property>
<property name="annotatedClasses">
<array>
<value>com.sga.app.dao.DisplayStatsDAO</value>
</array>
</property>
<!-- -->
</bean>
<bean id="exceptionTranslator"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">
</bean>
<tx:annotation-driven />
</beans>
My DAO:
package com.sga.app.dao;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.sga.app.beans.UserBean;
#SuppressWarnings("unchecked")
#Component("displayStatsDAO")
#Transactional
#Repository
#Configuration
public class DisplayStatsDAO implements Serializable {
private static final long serialVersionUID = 1L;
#Autowired
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Bean
public DisplayStatsDAO displayStatsDAO() {
return new DisplayStatsDAO();
}
public DisplayStatsDAO() {
}
public String getLoggedInUserName(String username) {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
String userLoggedIn = authentication.getName();
return userLoggedIn;
}
#Transactional
public ArrayList<Object> showMyStats() {
#SuppressWarnings("rawtypes")
ArrayList result = new ArrayList();
try {
/*
* SessionFactory factory = (SessionFactory) new
* org.hibernate.cfg.Configuration
* ().configure().buildSessionFactory(); Session sesh =
* factory.openSession(); sesh.beginTransaction();
*/
Session session = sessionFactory.getCurrentSession();
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
String userLoggedIn = authentication.getName();
System.out.println(userLoggedIn);
session.beginTransaction();
Criteria criteria = session.createCriteria(UserBean.class);
criteria.add(Restrictions.like("username", userLoggedIn));
List<UserBean> user = (List<UserBean>) criteria.list();
// session.getTransaction().commit();
for (UserBean userDetails : user) {
System.out.println("SHOW LOGGED-IN USER");
System.out.println("Username: " + userDetails.getUsername());
result.add(userDetails.getUsername());
System.out.println("Name: " + userDetails.getForename() + ""
+ userDetails.getSurname());
result.add(userDetails.getForename());
result.add(userDetails.getSurname());
System.out.println("Homeclub: " + userDetails.getHomeclub());
result.add(userDetails.getHomeclub());
System.out.println("GIR: " + userDetails.getGir());
result.add(userDetails.getGir());
System.out
.println("Fairways: " + userDetails.getFairways_hit());
result.add(userDetails.getFairways_hit());
System.out.println("Putts: " + userDetails.getPutts());
result.add(userDetails.getPutts());
System.out.println("Score average: "
+ userDetails.getScore_avg());
result.add(userDetails.getScore_avg());
System.out
.println("Sand saves: " + userDetails.getSand_saves());
result.add(userDetails.getSand_saves());
System.out.println();
System.out.println(result.get(0).toString());
System.out.println(result.get(3).toString());
return result;
}
} catch (HibernateException e) {
e.printStackTrace();
}
return result;
}
}
My jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%>
<%# taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%#page import="com.sga.app.dao.DisplayStatsDAO" %>
<%#page import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link href="${pageContext.request.contextPath}/static/css/main.css"
rel="stylesheet" type="text/css">
<title>SGA-user stats</title>
</head>
<body>
<!-- Logout option -->
<div id="logoutOptionDiv" align="right">
<a id="logoutOption" style="color: blue;"
href='<c:url value="/j_spring_security_logout"></c:url>'>Logout</a>
</div>
<br />
<!-- Page nav -->
<div>
<a style="font-weight: bold;"
href="${pageContext.request.contextPath}/menu">Main menu</a> <a
style="font-weight: bold; margin-left: 15px;"
href="${pageContext.request.contextPath}/roundanalysis">Round
analysis</a>
</div>
<br />
<br />
<h2 class="displayStatsLeaderboardHeader">Your stats</h2>
<table class="displayStatsTable" border="1">
<tr>
<td>Username</td>
<td>Forename</td>
<td>Surname</td>
<td>Average Score</td>
<td>GIR (%)</td>
<td>Fairways hit (%)</td>
<td>Sand saves (%)</td>
<td>Putts per round</td>
</tr>
<%DisplayStatsDAO stats = new DisplayStatsDAO();%>
<tr>
<td class="displayStatsTableData"><%stats.showMyStats().get(0).
toString();%>
</td>
<td class="displayStatsTableData">${row.surname}</td>
<td class="displayStatsTableData">${row.average_score}</td>
<td class="displayStatsTableData">${row.gir}</td>
<td class="displayStatsTableData">${row.fairways_hit}</td>
<td class="displayStatsTableData">${row.sand_saves}</td>
<td class="displayStatsTableData">${row.putts}</td>
</tr>
</table>
</body>
</html>
When you write new DisplayStatsDAO() in your jsp, it is initialized outside of the Spring container's context. Spring has no way of injecting Session into the DAO.

How to display error message in my JSP page using spring security 2.0

Hi I am now using spring security. It works fine. But if login failed, no error message display. I am wondering how can I display error message?
I have configured the ResourceBundleMessageSource in my applicationContext.xml
<!-- Spring security error message config -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
</bean>
And my security-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:David="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.xsd">
<David:http auto-config="true" access-denied-page="/accessDenied.html">
<!-- Don`t set any role restriction on login.jsp -->
<David:intercept-url pattern="/login.jsp"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<!-- Restrict access to All other pages -->
<David:intercept-url pattern="/admin.jsp"
access="ROLE_ADMIN" />
<!-- Set the login page and what to do if login fails -->
<David:form-login login-page="/login.jsp"
default-target-url="/"/>
<David:logout logout-success-url="/" />
</David:http>
<!-- Specify login examnination strategy -->
<David:authentication-provider>
<David:password-encoder hash="md5" />
<David:jdbc-user-service
data-source-ref="dataSource"
users-by-username-query="select username, password, status as enabled from user where username=?"
authorities-by-username-query="select u.username,r.name as authority
from user u
join user_role ur
on u.id=ur.user_id
join role r
on r.id=ur.role_id
where u.username=?" />
</David:authentication-provider>
</beans>
My jsp page:
<%# page contentType="text/html;charset=utf-8"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<%# page
import="org.springframework.security.ui.AbstractProcessingFilter"%>
<%# page
import="org.springframework.security.ui.webapp.AuthenticationProcessingFilter"%>
<%# page import="org.springframework.security.AuthenticationException"%>
<form id="myform" class="cmxform" method="post"
action="${pageContext.request.contextPath}/j_spring_security_check">
<fieldset>
<legend>
Please input correct username and password to login
</legend>
<p>
<label for="user">
Username:
</label>
<input id="user" name="j_username" />
</p>
<p>
<label for="pass">
Password:
</label>
<input type="password" name="j_password" id="password" />
</p>
<p>
<input type="submit" class="submit" value="Login" />
</p>
</fieldset>
</form>
Any suggestions? Any help will be appreciated.
<c:if test="${not empty param.login_error}">
<div class="error">
Your login attempt was not successful, try again.<br />
Reason: #{sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}
</div>
</c:if>
This works
<c:if test="${param.error != null}">
Error
</c:if>
Where is the jsp to actually display the error? Something like
<c:if test="${not empty param.error}">
<!-- Display error message -->
</c:if>
If you want to customize this message, you should also look at this
Maybe you can try this...put
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
for c tag on jsp page, and then put something like below for error msg display
<c:when test="${param.error == 1}">
<h3 style="font-size:20; color:#FF1C19;">Wrong id or password!</h3>
</c:when>
"param.error == 1" can get return value from Spring Security(security-config.xml) like
<beans:bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<beans:property name="exceptionMappings">
<beans:props>
<beans:prop key="org.springframework.security.core.userdetails.UsernameNotFoundException">/login.action?error=1</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
This worked for me :
<c:if test="${not empty sessionScope.SPRING_SECURITY_LAST_EXCEPTION}">
<div class="error">
Your login attempt was not successful, try again.<br />
Reason: ${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}
</div>
</c:if>
I am using spring-security v 4.0.3.RELEASE
Using the not empty did not work for me. However checking for null worked for me.
<c:if test="${ param.error ne null}">
Display error message
</c:if>

Resources