当前位置: 代码网 > it编程>编程语言>Java > Spring Security中successHandler和failureHandler使用方式

Spring Security中successHandler和failureHandler使用方式

2024年08月01日 Java 我要评论
前言successhandler和failurehandler是spring security中两个较为强大的用来处理登录成功和失败的回调函数,通过它们两个我们就可以自定义一些前后端数据的交互。suc

前言

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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com