Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display error messages in Spring login

I am using Spring security for authenticating users. I created a custom authentication provider and now I am wondering how I can get error messages from the provider into my form. This is the authenticate() method in my custom authentication provider:

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    UserProfile profile = userProfileService.findByEmail(authentication.getPrincipal().toString());

    if(profile == null){
        throw new UsernameNotFoundException(String.format("Invalid credentials", authentication.getPrincipal()));
    }

    String suppliedPasswordHash = DigestUtils.shaHex(authentication.getCredentials().toString());

    if(!profile.getPasswordHash().equals(suppliedPasswordHash)){
        throw new BadCredentialsException("Invalid credentials");
    }

    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(profile, null, profile.getAuthorities());

    return token;
}

This is my form:

<form name='f' action="<c:url value='j_spring_security_check' />" method='POST'>
<div id="data-entry-form">

    <div class="form-entry">
        <label><spring:message code="login.form.label.email"/></label>
        <input type='text' name='j_username' value=''>
    </div>
    <div class="form-entry">
        <label><spring:message code="login.form.label.password"/></label>
        <input type='password' name='j_password'/>
    </div>
    <div class="form-entry">
        <input type="submit" value="Verzenden"/>
    </div>
</div>

How would I get error messages into my form? From the moment I press the login button, Spring takes over, so the only method I could generate error messages in would be the authenticate() method...

like image 442
Julius Avatar asked Nov 07 '12 00:11

Julius


1 Answers

3 Steps of the safest way (we don't rely on the LAST_EXCEPTION):

  1. Specify error page (for example "login-error") in configuration for your custom authentication provider

    httpSecurity
    .authorizeRequests()
    .antMatchers("/css/**", "/js/**", "/img/**").permitAll()
    .anyRequest().fullyAuthenticated()
    .and()
    .formLogin().loginPage("/login").permitAll()
    .failureUrl("/login-error")
    .and()
    .logout().permitAll()
    
  2. Create controller for url /login-error that returns view of your custom login page (for example "login") with the next code:

    @Controller
    public class LoginController {
    
        @GetMapping("/login-error")
        public String login(HttpServletRequest request, Model model) {
            HttpSession session = request.getSession(false);
            String errorMessage = null;
            if (session != null) {
                AuthenticationException ex = (AuthenticationException) session
                        .getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
                if (ex != null) {
                    errorMessage = ex.getMessage();
                }
            }
            model.addAttribute("errorMessage", errorMessage);
            return "login";
        }
    }
    
  3. Get the error message into your page finally (ThymeLeaf tags for example):

    <!--/*@thymesVar id="errorMessage" type="java.lang.String"*/-->
    <div class="alert" th:if="${errorMessage}" th:text="${errorMessage}"></div>
    
like image 141
Yan Pak Avatar answered Sep 28 '22 02:09

Yan Pak