Spring Security Custom Login bad credentials with the right password - spring

I'm new to Spring security and I'm trying to create a custom login page. My problem is the authentication always failed and I always received the Bad Credentials message eventhough the password was correct, note that I have used BCRyptPasswordEncoder when I am saving the new registered account. Without the custom login and using the default formlogin it works fine
This is my WebSecurityConfig
#EnableWebSecurity
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Bean
public UserDetailsService userDetailsService(){
return new CustomApplicantDetailsService();
}
#Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception { //login logout
http
.authorizeRequests()
.antMatchers("/resources/**")
.authenticated()
.anyRequest()
.permitAll()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/loginProcess")
.defaultSuccessUrl("/account")
.usernameParameter("email")
//.successForwardUrl("/account")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutSuccessUrl("/login?logout")
.permitAll();
}}
This is my TemplateController to hanlde the url request. Note that I have tried the GetMapping first with the same line of code as loginProcess and without loginprocessingURL in configure but I received the error method get not supported altho most tutorials works somehow.
#Controller
#RequestMapping("/")
public class TemplateController {
#GetMapping("login")
public String login(){
return "loginStudent"; // logicalname
}
#PostMapping("loginProcess")
public String loginProcess(){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication == null ||authentication instanceof AnonymousAuthenticationToken){
return "loginStudent"; // logicalname
}
return "redirect:/account.html"; // redirect to account homepage
}
And here is the form from the "loginStudent.html"
<form th:action="#{/loginProcess}" th:method="post" >
<div th:if="${param.error}">
<p class="text-danger">. [[${session.SPRING_SECURITY_LAST_EXCEPTION.message}]]</p>
</div>
<div th:if="${param.logout}">
<p class="text-warning">You have been logged out.</p>
</div>
<div class="form-group">
<label for="email">E-Mail Adresse:</label>
<input type="email" class="form-control" placeholder="Enter email" id="email" name="username " autofocus="autofocus">
</div>
<div class="form-group">
<label for="password">Passwort:</label>
<input type="password" class="form-control" placeholder="Passwort" id="password" name="password">
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox"> Remember me
</label>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>

Related

Spring tags form do not show validation errors in jsp

I am writing a page with user registration. Faced a display problem in the form of validation errors
My Controller:
#Controller
public class UIController {
private final Logger log = LoggerFactory.getLogger(getClass());
#Autowired
private UserService service;
#Autowired
private SecurityService securityService;
#Autowired
private UserValidator validator;
#PostMapping(value = "/login")
public String signIn(#ModelAttribute("userForm") UserTo userForm, BindingResult bindingResult, Model model) {
validator.validate(userForm, bindingResult);
User user = service.findByLogin(UserUtil.createNewFromTo(userForm).getLogin());
if (!userForm.getPassword().equals(user.getPassword())) {
log.info("invalid password {}", user);
return "redirect:/login";
}
log.info("signIn {}", user);
securityService.autologin(user.getLogin(), user.getPassword());
return "redirect:/welcome";
}
}
My Validator:
#Component
public class UserValidator implements Validator {
#Autowired
private UserRepositoryImpl userRepository;
#Override
public boolean supports(Class<?> aClass) {
return UserTo.class.equals(aClass);
}
#Override
public void validate(Object o, Errors errors) {
UserTo user = (UserTo) o;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "login", "NotEmpty");
if (user.getLogin().length() < 6 || user.getLogin().length() > 32) {
errors.rejectValue("login", "Size.userForm.login");
}
if (userRepository.findByLogin(user.getLogin()) != null) {
errors.rejectValue("login", "Duplicate.userForm.login");
}
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "NotEmpty");
if (user.getPassword().length() < 8 || user.getPassword().length() > 32) {
errors.rejectValue("password", "Size.userForm.password");
}
}
}
My jsp form :
<div id="wrapper">
<!--SLIDE-IN ICONS-->
<div class="user-icon"></div>
<div class="pass-icon"></div>
<!--END SLIDE-IN ICONS-->
<!--LOGIN FORM-->
<form:form name="login-form" modelAttribute="userForm" class="login-form" method="post" id="form">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<!--CONTENT-->
<div class="content">
<!--USERNAME-->
<spring:bind path="login">
<div class="form-group ${status.error ? 'has-error' : ''}">
<form:input name="login" id="login" type="text" path="login" class="input username"
placeholder="Login"></form:input>
<form:errors path="login"></form:errors>
</div>
</spring:bind>
<!--END USERNAME-->
</div>
<!--END CONTENT-->
<!--FOOTER-->
<div class="footer">
<button class="button" type="submit">Login</button>
<button class="register" type="button" name="submit" onclick=" register_url('${contextPath}/registration')">
Register
</button>
</div>
<!--END FOOTER-->
</form:form>
</div>
When debugging in chrome when sending a POST request, a 302 HTTP error appears.
Accordingly, if I set a breakpoint in the controller, then the debug is not processed.
Tell me what could be the problem?
The "form" tag in your jsp does not have "action" attribute.
You should not redirect on errors, because the redirect will erase the binding result. Instead do :
if (!userForm.getPassword().equals(user.getPassword())) {
log.info("invalid password {}", user);
return "login";
}

Basic form login SpringBoot with Thymeleaf doesn't work?

I am a newbie in spring boot. I'm using basic thymeleaf form login. But when I login it returns "localhost:8080/login?error=true". I don't know why. My username and password in the database are correct. Maybe I must add a new controller with post method? please help me
And here, this is my security config class
protected void configure(HttpSecurity http) throws Exception {
logger.info("-----configure(HttpSecurity http)");
http.authorizeRequests()
.antMatchers("/**").permitAll()
.antMatchers("/user/**").hasAnyRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.permitAll()
.and()
.logout()
.permitAll()
.and().csrf().disable();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
logger.info("-----configureGlobal(AuthenticationManagerBuilder auth)");
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
login form page
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h2>Stacked form</h2>
<form th:action="#{/login}" method="post">
<div class="form-group">
<input type="text" name="username" id="username" class="form-control input-lg"
placeholder="UserName" required="true" autofocus="true"/>
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control input-lg"
placeholder="Password" required="true"/>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" name="remember"> Remember me
</label>
</div>
<a class="btn btn-success" th:href="#{'/register'}" role="button">Register</a>
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
</body>
</html>
My controller
#GetMapping("/login")
public String login() {
return "/login";
}
The entity
#Entity(name = "dbo_user")
public class User {
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
#Id
private int id;
private String email;
private String password;
private String username;
}
First of all, User class has to implement UserDetails interface like this:
// userdetails methods
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.roles.stream().map(SimpleGrantedAuthority::new).collect(toList());
}
#Override
public String getUsername() {
return this.getEmail();
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
#Transient
private List<String> roles = Arrays.asList("ROLE_USER");
public List<String> getRoles() {
return roles;
}
2nd you need a class that implements UserDetailsService like this:
#Service("customCustomerDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private CredentialRepository users;
#Override
public UserDetails loadUserByUsername(String email) {
return this.users.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("Username: " + email + " not found"));
}
}
Then you autowire that class into your security config class
#Autowired
CustomUserDetailsService customCustomerDetailsService;
You need to implement DAO DaoAuthenticationProvider in your security config class like this:
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(encoder());
return authProvider;
I'm quite sure this question would have been answered on this platform.
Are you using thymeleaf security extras? If so, then you need to have dependency included with maven/gradle and thymeleaf namespaces on the login page.
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
and
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5" lang="en">

Custom log in box with Spring security and Ajax

I have a login box which is a popup on my site, I am having some issues with configuring spring security and the AJAX call to login and authenticate. I am unsure if I've set it up correctly, I'm currently getting a 401() error and reaching Critical Error of the login.js, which is unauthorized access as it stands and the /user/login method not being called.... ! Just a basic idea of how an AJAX login and authentication process should be handled in spring security would be great, including the security config.
THE HTML
<form onSubmit="login()" id="notifyMe" method="POST" role="form">
div class="form-group">
<div class="controls">
<!-- Field -->
<input type="text" id="username" name="username" placeholder="Enter your username" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Click here to write your username'" class="form-control email srequiredField" />
<input type="password" id="password" name="password" placeholder="Enter your password" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Click here to write your password'" class="form-control email srequiredField" />
<!-- Spinner top left during the submission -->
<i class="fa fa-spinner opacity-0"></i>
<!-- Button -->
<button id="login-btw" class="btn btn-lg submit">LOG IN</button>
<div class="clear"></div>
</div>
</div>
</form>
THE AJAX
function login() {
console.info("Attempting to authenticate");
$.ajax({
type: 'POST',
url: '/user/login',
data: $('#notifyMe').serialize(),
cache: false,
dataType: "json",
contentType: "application/json;charset=utf-8",
beforeSend:function(xhr) {
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
},
crossDomain: false,
success: function (data) {
var response = jQuery.parseJSON(data);
if (response == true) {
$(".message").html('<p class="notify-valid">Logging in...</p>').fadeIn();
window.location.reload();
console.info("Authentication Success!");
}
else {
console.error("Unable to login");
console.log(response);
$(".message").html('<p class="notify-valid">Your log in details are incorrect. Please try again.</p>').fadeIn();
}
},
error: function (data) {
console.error("Critical error");
console.log(data);
}
});
SPRING SECURITY CONFIG
#Configuration
#EnableWebSecurity
public class SpringSecurityConfigurer extends WebSecurityConfigurerAdapter{
//Used in context with custom log in form (no /j_spring_security_check)
#Autowired
private CustomAuthenticationProvider cap;
#Autowired
private AjaxAuthenticationSuccessHandler successHandler;
#Autowired
private AjaxAuthenticationFailureHandler failureHandler;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(cap);
}
#Bean(name = "requestCache")
public RequestCache getRequestCache() {
return new HttpSessionRequestCache();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
//CSS FILES AND IMAGES
.antMatchers("/fonts/**", "/css/**", "/img/**", "/js/**", "/admin/css/**", "/admin/img/**", "/admin/js/**" ).permitAll()
//PAGES FOR ALL PEOPLE
.antMatchers("/user/login", "/", "/user/**", "/register/**").permitAll()
//PAGES FOR ADMIN
.antMatchers("/admin/").access("hasAuthority('ROLE_ADMIN')")
.antMatchers("/admin/**").access("hasAuthority('ROLE_ADMIN')")
//PAGES FOR USERS
.antMatchers("/event/**").access("hasAuthority('ROLE_USER')")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/")
.loginProcessingUrl("/user/login")
.failureHandler(failureHandler)
.successHandler(successHandler)
.and()
.csrf().disable()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/user/logout"))
.logoutSuccessUrl("/")
.and().exceptionHandling().accessDeniedPage("/")
//.authenticationEntryPoint(ajaxEntryPoint);
;
}
}
Response header
pragma: no-cache
date: Sun, 05 Nov 2017 11:08:12 GMT
x-content-type-options: nosniff
x-frame-options: DENY
content-type: application/json;charset=UTF-8
cache-control: no-cache, no-store, max-age=0, must-revalidate
transfer-encoding: chunked
x-xss-protection: 1; mode=block
expires: 0
js console image

Bad Credentials response when using Spring Security in memory authentication

I have configured my Java Spring backend to use in memory authentication but when I do a POST request through my angular2 frontend entering the right username/password in a login form, I always get the following errors:
x POST http://localhost:8080/authenticate 401 () zone.js:1382
x EXCEPTION: Response with status: 401 OK for URL: http://localhost:8080/authenticate core.umd.js:3370
x Uncaught Response {_body: "{"code":401,"message":"Authentication failed","err…reason":"authError","message":"Bad credentials"}}", status: 401, ok: false, statusText: "OK", headers: Headers…} Subscriber.ts:241
I have tried so many different security configurations but nothing seems to work. I may be doing something wrong... here's my code:
SecurityConfiguration.java
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
public static final String REMEMBER_ME_KEY = "rememberme_key";
public SecurityConfig() {
super();
logger.info("loading SecurityConfig ................................................ ");
}
#Autowired
private RestUnauthorizedEntryPoint restAuthenticationEntryPoint;
#Autowired
private AccessDeniedHandler restAccessDeniedHandler;
#Autowired
private AuthenticationSuccessHandler restAuthenticationSuccessHandler;
#Autowired
private AuthenticationFailureHandler restAuthenticationFailureHandler;
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/","/client/**","/systemjs.config.js","/index.html");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("test").password("test").authorities("ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().disable()
.csrf().disable()
.authorizeRequests()
.antMatchers("/failure").permitAll()
.antMatchers("/api/**").permitAll()
.antMatchers("/users").hasAnyAuthority("ADMIN")
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.accessDeniedHandler(restAccessDeniedHandler)
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/authenticate")
.successHandler(restAuthenticationSuccessHandler)
.failureHandler(restAuthenticationFailureHandler)
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
.deleteCookies("JSESSIONID")
.permitAll()
.and();
}
}
login.service.ts
#Injectable()
export class LoginService {
constructor(private http: Http) {
console.log('Login service initialized...')
}
loginUser(data) {
var headers = new Headers();
headers.append('Content-type', 'application/json');
return this.http.post('/authenticate', JSON.stringify(data), { headers: headers })
.map(res => res.json());
}
login.component.ts
export class LoginComponent {
username:String;
password:String;
data:any
constructor(private LoginService: LoginService) {
}
loginUser(event) {
this.data = {
username: this.username,
password: this.password
};
this.LoginService.loginUser(this.data).subscribe(data => {
this.username = '';
this.password = '';
});
}
login.html
<form class="container col-md-8" (ngSubmit)="loginUser()" style="margin:15px 15px">
<div class="row">
<div class="form group col-md-2 parent ">
<button type="submit" class="btn btn-warning centerV_element">Log In</button>
</div>
<div class="form group col-md-3 parent" style="margin:3px 3px">
<input type="text" [(ngModel)]="username" name="username" class="form control" placeholder="username">
</div>
<div class="form group col-md-3 parent" style="margin:3px 3px">
<input type="text" [(ngModel)]="password" name="password" class="form control" placeholder="password">
</div>
</div>
</form>

HDIV + Spring tag library (form) = Error, possible bug?

I'm finding troubles using HDIV with the tag Spring element: "< form:form >".
First, I'm going to explain the architecture of my application:
I'm using Spring framework 4.1.6, Spring Security 4.0.0 and HDIV 2.1.10.
So far I'm not having errors during the development, nevertheless now I 've found one in a jsp file, when I'm using the form tag from Spring:
<form:form
action="${pageContext.servletContext.contextPath}/newUser"
method="POST" class="form-horizontal" commandName="user">
I obtained this error in the line 34: "< form:form "
java.lang.NullPointerException at
org.hdiv.web.servlet.support.HdivRequestDataValueProcessor.processAction(HdivRequestDataValueProcessor.java:122)
at
org.springframework.web.servlet.tags.form.FormTag.processAction(FormTag.java:479)
at
org.springframework.web.servlet.tags.form.FormTag.resolveAction(FormTag.java:433)
at
org.springframework.web.servlet.tags.form.FormTag.writeTagContent(FormTag.java:349)
at
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
at
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
at
org.apache.jsp.WEB_002dINF.jsp.newUser_jsp._jspx_meth_form_005fform_005f0(newUser_jsp.java:197)
at
org.apache.jsp.WEB_002dINF.jsp.newUser_jsp._jspService(newUser_jsp.java:137)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
and more at.....(if it's necessary, I can provide it)
When I try the same code, but exchanging the tag "< form:form >" for the tag "< form >" It works.
When I examined in detail the code from HDIV:
HdivRequestDataValueProcessor.class
public class HdivRequestDataValueProcessor implements RequestDataValueProcessor
protected LinkUrlProcessor linkUrlProcessor;
protected FormUrlProcessor formUrlProcessor;
if (this.innerRequestDataValueProcessor != null) {
String processedAction = this.innerRequestDataValueProcessor.processAction(request, action, method);
if (processedAction != action) {
action = processedAction;
}
}
String result = this.formUrlProcessor.processUrl(request, action, method);//line 122
return result;
}
I wondered that maybe due to the fact that 'form:form' has a different structure than 'form', HDIV cannot find some parameters such as 'action', 'method'...But I'm not sure.
Also I attached my config files to provide more useful information (Java-based Config):
WebApplicationInit.class
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import org.hdiv.filter.ValidatorFilter;
import org.hdiv.listener.InitListener;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebApplicationInit extends
AbstractAnnotationConfigDispatcherServletInitializer {
// http://www.robinhowlett.com/blog/2013/02/13/spring-app-migration-from-xml-to-java-based-config/
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootConfig.class, DatabaseConfig.class,
SecurityConfig.class, HdivSecurityConfig.class };
// , HdivSecurityConfig.class
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { MvcConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
//web.xml filter
#Override
protected Filter[] getServletFilters(){
return new Filter[] { new ValidatorFilter()};
}
// web.xml listener
#Override
protected void registerDispatcherServlet(ServletContext servletContext) {
super.registerDispatcherServlet(servletContext);
servletContext.addListener(InitListener.class);
}
}
HdivSecurityConfig.class
#Configuration
#EnableHdivWebSecurity
public class HdivSecurityConfig extends HdivWebSecurityConfigurerAdapter {
#Override
public void addExclusions(ExclusionRegistry registry) {
registry.addUrlExclusions("/login").method("GET");
registry.addUrlExclusions("/newUser").method("GET");
registry.addUrlExclusions("/newUser").method("POST");
registry.addUrlExclusions("/about").method("GET");
registry.addUrlExclusions("/resources/.*").method("GET");
registry.addUrlExclusions("/bst-lib/.*").method("GET");
registry.addUrlExclusions("/images/.*").method("GET");
}
#Override
public void configure(SecurityConfigBuilder builder) {
//the session has expired, go to login again
builder.sessionExpired().homePage("/").loginPage("/login");
//Execution strategy
builder.strategy(Strategy.CIPHER);
//error page
builder.errorPage("/error");
}
}
SecurityConfig.class
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DriverManagerDataSource myWebAppDataSource;
#Autowired
private MyWebAppSimpleAuthenticationProvider myWebAppAuthenticationProvider;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.authenticationProvider(myWebAppAuthenticationProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resources/**", "/bst-lib/**", "/images/**",
"/about", "/newUser").permitAll().anyRequest()
.authenticated().and().formLogin().loginPage("/login")
.permitAll();
}
}
SecurityWebApplicationInit.class
public class SecurityWebApplicationInit extends
AbstractSecurityWebApplicationInitializer {}
Thank you in advance!!
Best Regards,
Alberto
----EDIT---
Following the given example, This is now my code:
WebApplicationInit.class
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebApplicationInit extends
AbstractAnnotationConfigDispatcherServletInitializer {
// http://www.robinhowlett.com/blog/2013/02/13/spring-app-migration-from-xml-to-java-based-config/
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootConfig.class, DatabaseConfig.class,
SecurityConfig.class, HdivSecurityConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { MvcConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected String getServletName(){
return "myDispatcher";
}
}
HDIVSecurityConfig.class
import org.hdiv.config.Strategy;
import org.hdiv.config.annotation.EnableHdivWebSecurity;
import org.hdiv.config.annotation.ExclusionRegistry;
import org.hdiv.config.annotation.RuleRegistry;
import org.hdiv.config.annotation.ValidationConfigurer;
import org.hdiv.config.annotation.builders.SecurityConfigBuilder;
import org.hdiv.config.annotation.configuration.HdivWebSecurityConfigurerAdapter;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableHdivWebSecurity
public class HdivSecurityConfig extends HdivWebSecurityConfigurerAdapter {
#Override
public void addExclusions(ExclusionRegistry registry) {
registry.addUrlExclusions("/login").method("GET");
registry.addUrlExclusions("/newUser").method("GET");
registry.addUrlExclusions("/newUser").method("POST");
registry.addUrlExclusions("/about").method("GET");
registry.addUrlExclusions("/resources/.*").method("GET");
registry.addUrlExclusions("/bst-lib/.*").method("GET");
registry.addUrlExclusions("/images/.*").method("GET");
registry.addParamExclusions("_csrf");
}
#Override
public void configure(SecurityConfigBuilder builder) {
// the session has expired, go to login again
builder.sessionExpired().homePage("/").loginPage("/login");
// Execution strategy
builder.strategy(Strategy.MEMORY);
builder.maxPagesPerSession(5);
// error page
builder.errorPage("/error");
}
#Override
public void addRules(RuleRegistry registry) {
//registry.addRule("safeText").acceptedPattern("^[a-zA-Z0-9#.\\-_]*$");
}
#Override
public void configureEditableValidation(
ValidationConfigurer validationConfigurer) {
validationConfigurer.addValidation("/.*");
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>myWebApp</display-name>
<listener>
<listener-class>org.hdiv.listener.InitListener</listener-class>
</listener>
<!-- HDIV Validator Filter -->
<filter>
<filter-name>ValidatorFilter</filter-name>
<filter-class>org.hdiv.filter.ValidatorFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ValidatorFilter</filter-name>
<servlet-name>myDispatcher</servlet-name>
</filter-mapping>
<jsp-config>
<taglib>
<taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/tlds/hdiv-c.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
newUser.jsp
<form:form
action="${pageContext.servletContext.contextPath}/newUser"
method="POST" class="form-horizontal" commandName="user">
<div class="form-group">
<label for="inputName"
class="col-sm-offset-2 col-sm-2 control-label">Name:</label>
<div class="col-sm-6">
<form:input class="form-control" id="inputName"
placeholder="Name" path="name" />
</div>
</div>
<div class="form-group">
<label for="inputSurname"
class="col-sm-offset-2 col-sm-2 control-label">Surname:</label>
<div class="col-sm-6">
<form:input class="form-control" id="inputSurname"
placeholder="Surname" path="surname" />
</div>
</div>
<div class="form-group">
<label for="inputOrganisation"
class="col-sm-offset-2 col-sm-2 control-label">Organization:</label>
<div class="col-sm-6">
<form:input class="form-control" id="inputOrganisation"
placeholder="Organization" path="organization" />
</div>
</div>
<div class="form-group">
<label for="inputEmail"
class="col-sm-offset-2 col-sm-2 control-label">Email:</label>
<div class="col-sm-6">
<form:input type="email" class="form-control" id="inputEmail"
placeholder="Email" path="email" />
</div>
</div>
<div class="form-group">
<label for="inputPassword"
class="col-sm-offset-2 col-sm-2 control-label">Password:</label>
<div class="col-sm-6">
<form:password class="form-control" id="inputPassword"
placeholder="Password" path="password" />
</div>
</div>
<div class="form-group">
<label for="inputRPassword"
class="col-sm-offset-2 col-sm-2 control-label">Repeat
Password:</label>
<div class="col-sm-6">
<form:password class="form-control" id="inputRPassword"
placeholder="Repeat Password" path="rPassword" />
</div>
</div>
<div class="col-sm-offset-4 col-sm-8">
<button type="submit" class="btn btn-default login-button">Sing
in</button>
<button type="button" class="btn btn-default login-button"
onclick="clearAll()">Clear All</button>
<button type="button" class="btn btn-default login-button"
onclick="comeBack()">Come Back</button>
</div>
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form:form>
MvcConfig.class
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.ec.myWebApp" })
public class MvcConfig extends WebMvcConfigurerAdapter {
#Autowired
/*
* If I use this commented line, The application fails due to the fact that the bean "hdivEditableValidator" can't be found...If I don't use the tag "Qualifier" it does not fail
*/
// #Qualifier("hdivEditableValidator")
private Validator hdivEditableValidator;
// View Name -> View
#Bean
public InternalResourceViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
// static resources
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations(
"/public-resources/");
registry.addResourceHandler("/bst-lib/**").addResourceLocations(
"/public-resources/lib/bootstrap-3.3.2-dist/");
registry.addResourceHandler("/images/**").addResourceLocations(
"/public-resources/images/");
}
#Bean
public MultipartResolver multipartResolver() {
HdivCommonsMultipartResolver resolver = new HdivCommonsMultipartResolver();
resolver.setMaxUploadSize(100000);
return resolver;
}
#Override
public Validator getValidator() {
return hdivEditableValidator;
}
}
I changed the way to add the HDIV to my Web Application, adding it in the xml file, instead of doing that in using java-based configuration. Additionally, I added the Qualifier tag (MvcConfig.class), using the example, but it does not work when I use it...(It can not find the bean...).
The null error hasn't disappeared...
The problem has been solved changing this line:
#ComponentScan(basePackages = { "com.ec.myWebApp" })
in the class: MvcConfing, for this:
#ComponentScan(basePackages = { "com.ec.myWebApp.controllers",
"com.ec.myWebApp.dao", "com.ec.myWebApp.services" })
My original line scanned twice the HDIV config class, first during the context creation and the second one by the "#ComponentScan". This gave place to an incorrect initialization. So, the config package was used twice, instead of once.
Thank you.

Resources