Spring Security中successHandler和failureHandler使用方式
前言
successHandler和failureHandler是Spring Security中两个较为强大的用来处理登录成功和失败的回调函数,通过它们两个我们就可以自定义一些前后端数据的交互。
successHandler
该方法有三个参数
req:相当与HttpServletRequestres:相当与HttpServletResposeauthentication:这里保存了我们登录后的用户信息
进行如下配置
.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:相当与HttpServletRequestres:相当与HttpServletResposee:这里保存了我们登录失败的原因
异常种类:
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:相当与HttpServletRequestres:相当与HttpServletResposeauthException:指的就是我们未认证的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();
}
);
}
}

总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
Springboot调整接口响应返回时长详解(解决响应超时问题)
当后端对于数据量较大的处理或是某些耗时的操作时,需要先对请求接口的请求进行响应,下面这篇文章主要给大家介绍了关于Springboot调整接口响应返回时长(解决响应超时问题)的相关资料,需要的朋友可以参考下2023-01-01
SpringBoot集成SwaggerUi以及启动时遇到的错误
这篇文章主要介绍了SpringBoot集成SwaggerUi以及启动时遇到的错误,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-06-06
SpringBoot使用Flyway进行数据库迁移的实现示例
Flyway是一个数据库迁移工具,它提供迁移历史和回滚的功能,本文主要介绍了如何使用Flyway来管理Spring Boot应用程序中的SQL数据库架构,感兴趣的可以了解一下2023-08-08


最新评论