springboot 整合 security(三) 自定义异常返回

在使用security的过程中,我们会遇到未登录,用户名密码错误等等被拦截的情况。

这时系统的返回的都是跳转到登录页面,在实际使用中,我们更多的会是自定义登录页面,遇到异常情况,会根据返回结果进行“您的登录已过期”,“用户名或密码不正确”等提示。

这次我们来自定义返回信息。

首先第一个是登录成功的handle

package com.mu.security3.security.handle;

import com.alibaba.fastjson.JSON;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 登录成功时调用
 */
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {

        Map<String, Object> responseData = new HashMap<>();
        responseData.put("status", 200);
        responseData.put("msg", "登录成功!");
        httpServletResponse.setContentType("application/json;charset=utf-8");
        httpServletResponse.setStatus(200);
        httpServletResponse.getWriter().write(JSON.toJSONString(responseData));
    }
}

登录失败时的handle

package com.mu.security3.security.handle;

import com.alibaba.fastjson.JSON;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 登录失败时调用
 */
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException exception) throws IOException, ServletException {

        Map<String, Object> responseData = new HashMap<>();
        if (exception instanceof UsernameNotFoundException) {//此异常不会抛出,会被捕捉然后抛出为BadCredentialsException
            responseData.put("status", 7001);
            responseData.put("msg", "用户不存在!");
        } else if (exception instanceof BadCredentialsException) {
            responseData.put("status", 7002);
            responseData.put("msg", "用户名或密码错误!");
        } else if (exception instanceof LockedException) {
            responseData.put("status", 7003);
            responseData.put("msg", "用户已被锁定!");
        } else if (exception instanceof DisabledException) {
            responseData.put("status", 7004);
            responseData.put("msg", "用户不可用!");
        } else if (exception instanceof AccountExpiredException) {
            responseData.put("status", 7005);
            responseData.put("msg", "账户已过期!");
        } else if (exception instanceof CredentialsExpiredException) {
            responseData.put("status", 7006);
            responseData.put("msg", "用户密码已过期!");
        } else {
            responseData.put("status", 7000);
            responseData.put("msg", "认证失败,请联系网站管理员!");
        }
        httpServletResponse.setContentType("application/json;charset=utf-8");
        httpServletResponse.setStatus(200);
        httpServletResponse.getWriter().write(JSON.toJSONString(responseData));
    }
}

未登录时的handle

package com.mu.security3.security.handle;

import com.alibaba.fastjson.JSON;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 未登录
 */
@Component
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {

        Map<String, Object> responseData = new HashMap<>();
        responseData.put("status", 6001);
        responseData.put("msg", "请登录");
        httpServletResponse.setContentType("application/json;charset=utf-8");
        httpServletResponse.setStatus(200);
        httpServletResponse.getWriter().write(JSON.toJSONString(responseData));
    }
}

配置文件

package com.mu.security3.security;

import com.mu.security3.security.handle.MyAuthenticationEntryPoint;
import com.mu.security3.security.handle.MyAuthenticationFailureHandler;
import com.mu.security3.security.handle.MyAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    MyUserDetailsService userDetailsService;
    @Autowired
    private MyAuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    MyAuthenticationFailureHandler authenticationFailureHandler;
    @Autowired
    MyAuthenticationEntryPoint authenticationEntryPoint;

    /**
     * 需要放行的URL
     */
    private static final String[] AUTH_WHITELIST = {
            "/ok/**"
    };

    // 配置 URL 访问权限
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests() // 开启 HttpSecurity 配置
                .antMatchers(AUTH_WHITELIST).permitAll().anyRequest().authenticated() // 用户访问其它URL都必须认证后访问(登录后访问)
                .and().httpBasic().authenticationEntryPoint(authenticationEntryPoint)//未登录的情况下调用
                .and().formLogin() // 开启表单登录
                    .successHandler(authenticationSuccessHandler)//登录成功handle
                    .failureHandler(authenticationFailureHandler)//登录失败handle
                    .permitAll()
                .and().csrf().disable(); // 关闭csrf
    }

    // 配置用户及其对应的角色
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    //指定密码的加密方式
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

fastjson依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.35</version>
    <scope>compile</scope>
</dependency>

测试一下,ok接口

 测试一下,需要验证的用户列表接口

 测试一下,用户名不存在登录失败的情况

 测试一下,登录成功

 

本篇记录就到此结束了,如果本篇文章对您有所帮助可以点个赞发个评论,不胜感激。如果内容有不对的地方或者有侵犯权益的地方也欢迎留言联系我。

源码地址

https://gitee.com/zhangxin2048/security

附参考博客

springboot security 自定义返回结果

https://blog.csdn.net/qq_27081015/article/details/103714367

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值