Spring boot安全性从错误页面重定向到登录页面如果身份验证失败

时间:2017-03-02 19:03:43

标签: spring spring-boot spring-security

我为我的Web应用程序配置了spring security,实现了自定义身份验证处理程序来验证用户详细信息。

当身份验证成功时,当身份验证无法调用自定义身份验证失败处理程序重定向错误页面(在我的情况下是带有错误消息的登录页面)之后,它按预期工作,之后它再次重定向到登录页面(没有消息)

以下是我的配置(请告诉我这里的错误)

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter  {

    @Autowired
    private CustomAuthenticationProvider authProvider;

    @Autowired
    private AuthSuccessHandler authHandler;
    @Autowired
    private AuthFailureHandler authFailureHandler;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
         http.authorizeRequests()
             .antMatchers("/resources/**","/rest/**")
             .permitAll().anyRequest().authenticated()
             .and()
             .formLogin()
             .loginPage("/login")
             .successHandler(authHandler)
             .failureHandler(authFailureHandler)
             .usernameParameter("username").passwordParameter("password")
             .permitAll()
             .and().csrf().disable();
    }

    @Autowired
    protected void configureGlobal(AuthenticationManagerBuilder auth)  {

        auth.authenticationProvider(authProvider);
    }
}

Success Handler

@Component
public class AuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
    @Override
    protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        redirectStrategy.sendRedirect(request, response, "/home");
    }
}


Failure Handler

@Component
public class AuthFailureHandler extends SimpleUrlAuthenticationFailureHandler{

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
            throws IOException, ServletException {
        System.out.println("AuthFailureHandler.onAuthenticationFailure()");
        redirectStrategy.sendRedirect(request, response, "/login?msg=Bad Credentials");
    }
}


Custom Authentication Provider 

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider
{
    public Authentication authenticate(Authentication authentication) throws AuthenticationException    {

        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
        String username = (String)token.getPrincipal();
        String password = (String) token.getCredentials(); // retrieve the password 
        System.out.println("username="+username+" password="+password);
        flag = //autheticate logic 
        if(flag) {
                List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
                authorities.add(new SimpleGrantedAuthority("ROLE_ONE"));
                authorities.add(new SimpleGrantedAuthority("ROLE_TWO"));
                return new UsernamePasswordAuthenticationToken(username, password, authorities);
           }
        else
        throw new BadCredentialsException("401");
    }

    public boolean supports(Class<?> object) {
        return object.equals(UsernamePasswordAuthenticationToken.class);
    }
}

Controller :
Below is the controller configuration

    @RequestMapping(value = "/login", method = RequestMethod.GET)
        public ModelAndView login(@RequestParam(name="msg",required=false) String message)
     {
            System.out.println("HomeController.login()"+message);
            return new ModelAndView("login","message",message);
    }

的login.jsp

<form id='loginForm'  method='GET' action='./login'>
   <div class="login">
      <div id='errorMsg' class="hide alert alert-danger" role="alert"><strong><i class='fa fa-warning'></i>
         <span id='errorTitle'></span></strong><span id='errorText'></span>
      </div>
      <div class="form-group">
         <label for='txtUserName' class="UsernamePassword">Username:</label>
         <input name="username" type="email" class="form-control" value="" id="txtUserName" maxlength="100" />
      </div>
      <div class="form-group">
         <label for='txtPassword' class="UsernamePassword">Password:</label>
         <input value='' name="password" class="form-control" type="password" id="txtPassword" maxlength="100" />
      </div>
      <div class="form-group">                      
         <label>
         <input checked type="checkbox" name="RememberMe" id="checkboxRememberMe"/> Remember My Information
         </label>
      </div>
      <c:if test="${param.error != null}">
         <div class="alert alert-danger">
            <p>Invalid username and password.</p>
         </div>
      </c:if>
      <c:if test="${param.logout != null}">
         <div class="alert alert-success">
            <p>You have been logged out successfully.</p>
         </div>
      </c:if>
      <div>
         <p>${message}</p>
      </div>
      <div>
         <button id="btnLogin" class="btnBlue" style='width:100% !important' type='submit'>Login</button>
      </div>
      <div class="usernamePassword">
         <a href="#" onclick='forgotPassword()'>I forgot my username/password</a>
      </div>
   </div>
</form>

2 个答案:

答案 0 :(得分:0)

将“/ login?msg = Bad Credentials”添加到authorizeRequests()部分非常重要,否则控制器将不会选择错误参数。

    @Override
    protected void configure(HttpSecurity http) throws Exception {
         http.authorizeRequests()
             .antMatchers("/resources/**","/rest/**,/login*").permitAll()
             .anyRequest().authenticated()
             .and()
             .formLogin()
             .loginPage("/login")
             .successHandler(authHandler)
             .failureHandler(authFailureHandler)
             .usernameParameter("username").passwordParameter("password")
             .permitAll()
             .and().csrf().disable();
    }

答案 1 :(得分:0)

试试这个配置:

.formLogin()
.loginPage("/login")
.failureUrl("/login?error")