Spring Security中successHandler和failureHandler使用方式

 更新时间:2024年08月01日 15:13:47   作者:放肆热爱  
这篇文章主要介绍了Spring Security中successHandler和failureHandler使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

前言

successHandler和failureHandler是Spring Security中两个较为强大的用来处理登录成功和失败的回调函数,通过它们两个我们就可以自定义一些前后端数据的交互。

successHandler

该方法有三个参数

  • req:相当与HttpServletRequest
  • res:相当与HttpServletRespose
  • authentication:这里保存了我们登录后的用户信息

进行如下配置

.successHandler((req, resp, authentication) -> {
                    Object principal = authentication.getPrincipal();
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write(new ObjectMapper().writeValueAsString(principal));
                    out.flush();
                    out.close();
                })

配置类代码

package com.scexample.sc.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import java.io.PrintWriter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Bean
    PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("xiaoming")
                .password("123456").roles("admin");

    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**","/css/**","/images/**");  //这个是用来忽略一些url地址,对其不进行校验,通常用在一些静态文件中。
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/aaa.html")
                 .loginProcessingUrl("/logintest")
                .usernameParameter("name")
                .passwordParameter("passwd")
                .successHandler((req, res, authentication) -> {
                    Object principal = authentication.getPrincipal();
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write(new ObjectMapper().writeValueAsString(principal));
                    out.flush();
                    out.close();
                })
                .permitAll()
                .and()
                .csrf().disable()
        );
    }
}

再次登录后

failureHandler

该方法有三个参数

  • req:相当与HttpServletRequest
  • res:相当与HttpServletRespose
  • e:这里保存了我们登录失败的原因

异常种类:

  • LockedException 账户锁定
  • CredentialsExpiredException 密码过期
  • AccountExpiredException 账户过期
  • DisabledException 账户被禁止
  • BadCredentialsException 用户名或者密码错误
.failureHandler((req, res, e) -> {
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write(e.getMessage());
                    out.flush();
                    out.close();
                })

配置类代码:

package com.scexample.sc.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import java.io.PrintWriter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Bean
    PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("xiaoming")
                .password("123456").roles("admin");

    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**","/css/**","/images/**");  //这个是用来忽略一些url地址,对其不进行校验,通常用在一些静态文件中。
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/aaa.html")
                 .loginProcessingUrl("/logintest")
                .usernameParameter("name")
                .passwordParameter("passwd")
                .successHandler((req, res, authentication) -> {
                    Object principal = authentication.getPrincipal();
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write(new ObjectMapper().writeValueAsString(principal));
                    out.flush();
                    out.close();
                })
                .failureHandler((req, res, e) -> {
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write(e.getMessage());
                    out.flush();
                    out.close();
                })           
                .permitAll()
                .and()
                .csrf().disable()          
    }
}

未认证处理方法

spring security默认情况下,如果认证不成功,直接重定向到登录页面。

但是项目中,我们有的时候不需要这样,我们需要在前端进行判断 ,然后再决定进行其他的处理,那我们就可以用authenticationEntryPoint这个接口进行自定义了,取消它的默认重定向行为。

该方法有三个参数

  • req:相当与HttpServletRequest
  • res:相当与HttpServletRespose
  • authException:指的就是我们未认证的exception
 				.csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint((req, res, authException) -> {
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write("检测到未登录状态,请先登录");
                    out.flush();
                    out.close();
                }

配置类代码

package com.scexample.sc.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import java.io.PrintWriter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Bean
    PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("xiaoming")
                .password("123456").roles("admin");

    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**","/css/**","/images/**");  //这个是用来忽略一些url地址,对其不进行校验,通常用在一些静态文件中。
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/aaa.html")
                 .loginProcessingUrl("/logintest")
                .usernameParameter("name")
                .passwordParameter("passwd")
                .successHandler((req, res, authentication) -> {
                    Object principal = authentication.getPrincipal();
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write(new ObjectMapper().writeValueAsString(principal));
                    out.flush();
                    out.close();
                })
                .failureHandler((req, res, e) -> {
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write(e.getMessage());
                    out.flush();
                    out.close();
                })           
                .permitAll()
                .and()
                .csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint((req, res, authException) -> {
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write("检测到未登录状态,请先登录");
                    out.flush();
                    out.close();
                }
               );          
    }
}

注销登录

				   .logoutSuccessHandler((req, res, authentication) -> {
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write("注销成功");
                    out.flush();
                    out.close();
                })

配置类代码:

package com.scexample.sc.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import java.io.PrintWriter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Bean
    PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("xiaoming")
                .password("123456").roles("admin");

    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**","/css/**","/images/**");  //这个是用来忽略一些url地址,对其不进行校验,通常用在一些静态文件中。
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/aaa.html")
                 .loginProcessingUrl("/logintest")
                .usernameParameter("name")
                .passwordParameter("passwd")
                .successHandler((req, res, authentication) -> {
                    Object principal = authentication.getPrincipal();
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write(new ObjectMapper().writeValueAsString(principal));
                    out.flush();
                    out.close();
                })
                .failureHandler((req, res, e) -> {
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write(e.getMessage());
                    out.flush();
                    out.close();
                })           
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler((req, res, authentication) -> {
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write("注销成功");
                    out.flush();
                    out.close();
                })
                .permitAll()
                .and()
                .csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint((req, res, authException) -> {
                    res.setContentType("application/json;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.write("检测到未登录状态,请先登录");
                    out.flush();
                    out.close();
                }
               );          
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 一篇文章带你了解Spring AOP 的注解

    一篇文章带你了解Spring AOP 的注解

    这篇文章主要为大家介绍了vue组件通信的几种方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • 使用spring实现邮件的发送实例(含测试,源码,注释)

    使用spring实现邮件的发送实例(含测试,源码,注释)

    本篇文章主要介绍了使用spring实现邮件的发送实例,详细的介绍了使用spring配置实现邮件发送,含测试,源码,注释,有兴趣的可以下
    2017-05-05
  • 详解SpringBoot启动代码和自动装配源码分析

    详解SpringBoot启动代码和自动装配源码分析

    这篇文章主要介绍了SpringBoot启动代码和自动装配源码分析,使用SpringBoot很简单,在主类中添加一个@SpringBootApplication,以及调用SpringApplication.run()并传入主类,本文通过示例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • Springboot调整接口响应返回时长详解(解决响应超时问题)

    Springboot调整接口响应返回时长详解(解决响应超时问题)

    当后端对于数据量较大的处理或是某些耗时的操作时,需要先对请求接口的请求进行响应,下面这篇文章主要给大家介绍了关于Springboot调整接口响应返回时长(解决响应超时问题)的相关资料,需要的朋友可以参考下
    2023-01-01
  • 基于Java的电梯系统实现过程

    基于Java的电梯系统实现过程

    这篇文章主要介绍了基于Java的电梯系统实现过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • SpringBoot集成SwaggerUi以及启动时遇到的错误

    SpringBoot集成SwaggerUi以及启动时遇到的错误

    这篇文章主要介绍了SpringBoot集成SwaggerUi以及启动时遇到的错误,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • SpringBoot使用Flyway进行数据库迁移的实现示例

    SpringBoot使用Flyway进行数据库迁移的实现示例

    Flyway是一个数据库迁移工具,它提供迁移历史和回滚的功能,本文主要介绍了如何使用Flyway来管理Spring Boot应用程序中的SQL数据库架构,感兴趣的可以了解一下
    2023-08-08
  • Struts中action线程安全问题解析

    Struts中action线程安全问题解析

    这篇文章主要介绍了Struts中action线程安全问题解析,涉及实例代码,还是挺不错的,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • springboot清除字符串前后空格与防xss攻击方法

    springboot清除字符串前后空格与防xss攻击方法

    这篇文章主要介绍了springboot清除字符串前后空格与防xss攻击方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 基于XML配置Spring的自动装配过程解析

    基于XML配置Spring的自动装配过程解析

    这篇文章主要介绍了基于XML配置Spring的自动装配过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10

最新评论