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

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>

Related

UserDetailsService is not invoked in spring security

I am trying to use spring security with two login page and configure two different http section in my spring-security.xml I also have two authentication-manager which handles authentication using custom UserDetailsService.
Below are my code snippets
spring-security.xml
<!-- http Section for Admins -->
<http auto-config="true" use-expressions="true" authentication-manager-ref="adminAuth" pattern="/admin/**">
<intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login login-page="/adminLogin" default-target-url="/admin/home" authentication-failure-url="/views/homePages/adminHome" username-parameter="username"
password-parameter="password"
login-processing-url="/authenticateAdmin" />
<logout logout-success-url="/login?logout" />
<!-- enable csrf protection -->
<csrf disabled="true"/>
</http>
<authentication-manager id="adminAuth" alias="adminAuth">
<authentication-provider user-service-ref='adminAuthService'>
<password-encoder hash="md5" />
</authentication-provider>
</authentication-manager>
<beans:bean id="adminAuthService" class="security.AdminAuth">
</beans:bean>
<!-- http Section for Students -->
<http auto-config="true" use-expressions="true" authentication-manager-ref="studentAuth" pattern="/student/**" >
<intercept-url pattern="/**" access="hasRole('ROLE_STUDENT')" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login login-page="/studentLogin" default-target-url="/student/home" authentication-failure-url="/studentLogin" login-processing-url="/authenticateStudent" />
<logout logout-success-url="/studentLogin" />
<!-- enable csrf protection -->
<csrf disabled="true"/>
</http>
<authentication-manager id="studentAuth" alias="studentAuth">
<authentication-provider user-service-ref='studentAuthService'>
<password-encoder hash="md5" />
</authentication-provider>
</authentication-manager>
<beans:bean id="studentAuthService" class="security.StudentAuth">
</beans:bean>
UserDetailService implementor class
package security;
#Service
public class AdminAuth implements UserDetailsService {
#Autowired
AdminService adminService;
public UserDetails loadUserByUsername(String authAttribute) throws UsernameNotFoundException {
Admin admin = getAdminByUname(authAttribute);
List<SimpleGrantedAuthority> authList = new ArrayList();
authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
User user = new User(authAttribute, admin.getPassword(), authList);
return user;
}
private Admin getAdminByUname(String authAttribute) {
Admin admin = adminService.getAdminbyUname(authAttribute);
return admin;
}
}
Admin login page
<h2 class="text-center">Staff Login</h2>
<form class="login-form" action="/authenticateAdmin" method="POST">
<div class="form-group">
<label for="exampleInputEmail1" class="text-uppercase">Username</label> <input type="text" class="form-control" placeholder="Email or Mobile" id="username">
</div>
<div class="form-group">
<label for="exampleInputPassword1" class="text-uppercase">Password</label> <input type="password" class="form-control" placeholder="" id="password">
</div>
<div class="form-check">
<label class="form-check-label"> <input type="checkbox" class="form-check-input"> <small>Remember Me</small>
</label>
<button type="submit" class="btn btn-login float-right">Submit</button>
</div>
</form>
Now when I open login page enter username/password and hit login then my loadUserByUsername is not getting invoked.
What I doing wrong here.

j_spring_security_check returning 404 on Tomcat but works on Jetty

I have a basic Spring security setup with Form based login. When submitting my login action to j_spring_security_check it works on Jetty but fails with 404 code on Tomcat (7 & 8). I am using Spring 3.2.
So submitting to server:port/app/j_spring_security_check returns 404 response.
My security http setup looks like the following:
<security:http >
<security:form-login login-page="/login.jsp"
username-parameter="j_username"
password-parameter="j_password" />
<security:intercept-url pattern="/admin/**" access="ROLE_ADMIN"/>
<security:custom-filter position="PRE_AUTH_FILTER" ref="springAccessManagerAuthenticationFilter"/>
<security:intercept-url pattern="/j_spring_security_check" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:session-management></security:session-management>
<security:headers>
<security:cache-control/>
<security:xss-protection/>
<security:hsts/>
<security:frame-options/>
<security:content-type-options/>
</security:headers>
</security:http>
The login page looks like the following:
<%# include file="/WEB-INF/jsp/tags.jsp"%>
<%#page session="false" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Login</title>
</head>
<body id="login">
<form method="POST" action="<c:url value='j_spring_security_check' />"
id="loginForm" autocomplete="off">
Username : <input id="username" type="text" size="15" maxlength="60" name="j_username"><br><br>
Password : <input id="password" type="password" size="15" maxlength="60" name="j_password"><br><br>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<input value="Login" type="submit" id="submit" name="_eventId_nextpage">
</form>
</body>
</html>
My web.xml has the SpringSecurityFilterChain:
<!-- Spring Security -->
<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>
I finally figured this out as being a typo in web.xml on the default filter.
I had:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/logout</url-pattern>
<url-pattern>/j_security_check</url-pattern>
</servlet-mapping>
j_security_check should have been j_spring_security_check

Spring Logout not working and redirecting

I have the following JSF Page:
<h:form>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<b:navBar brand="TEST" brandHref="#" inverse="true">
<p:lightBox styleClass="menucolored">
<p:commandLink id="logout"
type="button"
action="/j_spring_security_logout"
value="Log Out" ajax="false"
styleClass="menucolored"/>
</p:lightBox>
</b:navBar>
</h:form>
Spring Security xml:
<http use-expressions="true" auto-config="true">
<form-login login-page="/pages/Login.xhtml"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/loginPage?error=1"
default-target-url="/pages/Home.xhtml"
always-use-default-target="true"
username-parameter="j_username"
password-parameter="j_password"/>
<!-- On logout success load the login page -->
<logout logout-success-url="/pages/Login.xhtml" />
<!-- enable csrf protection -->
<csrf />
</http>
Web.xml
<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>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
I have tried replacing the command link with
<h:outputLink value="${request.contextPath}/j_spring_security_logout">logout</h:outputLink>
or
<h:outputLink value="${pageContext.request.contextPath}/j_spring_security_logout">logout</h:outputLink>
Still no luck. When I click the button nothing happens.
If CSRF enabled, you must logout with a POST method. You need to wrap it in a standard HTML form instead:
<form action="${request.contextPath}/j_spring_security_logout" method="post">
<input type="submit" value="Log out" />
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
For using a link instead of a button, you'll need to write some javascript in order to make the link submit the form. See this post.
I fixed it:
public String doLogout() throws ServletException, IOException {
System.out.println("In doLogout()");
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
RequestDispatcher dispatcher = ((ServletRequest) context.getRequest())
.getRequestDispatcher("/logout");
dispatcher.forward((ServletRequest) context.getRequest(),
(ServletResponse) context.getResponse());
FacesContext.getCurrentInstance().responseComplete();
System.out.println("End doLogout()");
return null;
}
I had to use /logout instead of /j_spring_security_logout
You can use this javascript solution for Spring Security 4 + CSRF + JSF:
Logout
<form action="logout" id="logout" method="post">
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>

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.

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

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

Resources