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();
                }
               );          
    }
}

在这里插入图片描述

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Spring Boot可以很方便地整合Spring Security,实现安全认证和授权功能。具体步骤如下: 1. 引入Spring Security依赖 在pom.xml文件添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 2. 配置Spring SecuritySpring Boot的配置文件application.properties或application.yml添加以下配置: ``` # 配置登录页面 spring.security.loginPage=/login # 配置登录成功后跳转的页面 spring.security.successHandler.defaultTargetUrl=/home # 配置登录失败后跳转的页面 spring.security.failureHandler.defaultFailureUrl=/login?error=true # 配置退出登录后跳转的页面 spring.security.logout.successUrl=/login ``` 3. 创建用户和角色 在Spring Security,用户和角色是两个重要的概念。可以通过以下方式创建用户和角色: ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasRole("USER") .anyRequest().authenticated() .and() .formLogin().loginPage("/login").permitAll() .and() .logout().logoutUrl("/logout").permitAll(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public DaoAuthenticationProvider authenticationProvider() { DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); authenticationProvider.setUserDetailsService(userDetailsService); authenticationProvider.setPasswordEncoder(passwordEncoder()); return authenticationProvider; } } ``` 4. 创建登录页面 在Spring Security,登录页面可以自定义。可以创建一个Controller来处理登录请求,返回登录页面的模板。 ``` @Controller public class LoginController { @GetMapping("/login") public String login() { return "login"; } } ``` 5. 创建授权页面 在Spring Security,授权页面也可以自定义。可以创建一个Controller来处理授权请求,返回授权页面的模板。 ``` @Controller public class AccessDeniedController { @GetMapping("/accessDenied") public String accessDenied() { return "accessDenied"; } } ``` 以上就是Spring Boot整合Spring Security的基本步骤。通过这些步骤,可以实现基本的安全认证和授权功能。 ### 回答2: Springboot是一款优秀的Java框架,它可以轻松实现Web应用的开发。而Spring Security则是处理Web应用程序安全的框架,它可以帮助你实现身份验证、授权等功能。把这两个框架整合起来,可以更加方便地为Web应用提供安全保障。 首先,我们需要在pom.xml添加Spring Security的依赖。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 然后,我们需要创建一个配置类来配置Spring Security。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasRole("USER") .antMatchers("/**").permitAll() .and() .formLogin(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("admin").password("admin").roles("ADMIN") .and() .withUser("user").password("user").roles("USER"); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 在上面的代码,我们定义了对不同URL的访问权限,并且配置了用户的身份验证信息。最后需要定义一个密码加密类。 在上述的代码,我们使用了BCrypt加密方式进行密码加密。我们可以通过调用passwordEncoder()方法来进行密码加密,该方法是一个Bean类型的方法,需要注入到Spring容器才能使用。 最后,我们需要在Controller进行安全规则的校验。可以使用@PreAuthorize注解来设置权限验证规则。 ```java @RestController public class TestController { @PreAuthorize("hasRole('ADMIN')") @RequestMapping("/admin/hello") public String helloAdmin() { return "Hello Admin"; } @PreAuthorize("hasRole('USER')") @RequestMapping("/user/hello") public String helloUser() { return "Hello User"; } @RequestMapping("/") public String hello() { return "Hello World"; } } ``` 在上面的代码,我们使用@PreAuthorize注解来设置权限验证规则,只有用户具有ADMIN角色才能访问/admin/hello路径下的API,而只有具有USER角色的用户才能访问/user/hello路径下的API。 以上就是Springboot整合Spring Security的步骤。通过这种方式,我们可以轻松地为我们的应用提供基于角色的访问控制,保证应用的安全性。 ### 回答3: Spring Boot 是一个流行的开发框架,其主要使用Spring Framework 的各种组件,为开发者提供了更加快速、简化的开发方式。Spring Security 则是 Spring 框架的安全框架,为系统的安全性提供了全面的支持。因此,将 Spring BootSpring Security 整合,能够为我们的应用程序提供全面的安全服务支持,从而保障应用程序的安全性。 Spring Boot 整合 Spring Security 需要完成以下几个步骤: 1.添加 Spring Security 相关依赖:首先需要在 Pom.xml 文件添加 Spring Security 相关依赖,以便引入所需的 Spring Security 组件。 2.配置 Spring Security:在项目配置 Spring Security,可以通过使用 Java 配置或者 XML 配置的方式来实现。其Java 配置方式更加清晰简单,便于集成其它组件。 3.配置认证和授权:在配置文件配置认证和授权相关信息,例如用户、角色、权限等。 4.实现登录页面:为用户提供可视化的登录页面,并在需要登录的页面增加登录拦截器。 5.实现注销页面:为用户提供注销页面,用户点击注销按钮后退出登录状态。 6.自定义实现:如果需要对 Spring Security 进行自定义实现,可以通过重写 Spring Security 的对应接口来实现。 除了以上的步骤外,还需要了解 Spring Security 内置的一些特性和配置项,如使用密码加密器、请求拦截器、跨站点请求伪造(CSRF)防御等。 综上所述,将 Spring BootSpring Security 整合,可以提供全面的安全服务支持,保障应用程序的安全性。所以,作为系统开发人员,需要深入学习 Spring Security 的相关知识,使其在开发过程得到合理的应用和配置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值