SpringSecurity[04]:前后端分离改造

1、创建Http约束类

public interface HttpStatus {
    int SUCCESS = 0;
    int NOT_LOGIN = 1001;
    int NOT_REGISTER = 1002;
    int PASSWORD_ERROR = 1003;
    int FORBIDDEN = 1004;
    int EXCEPTION = 1005;
    int AUTH_FAIL = 1006;

    String SUCCESS_MSG = "success";
    String NOT_LOGIN_MSG = "用户未登录";
    String NOT_REGISTER_MSG = "用户未注册";
    String PASSWORD_ERROR_MSG = "用户密码错误";
    String FORBIDDEN_MSG = "用户无权访问";
    String EXCEPTION_MSG = "系统异常";
    String AUTH_FAIL_MSG = "登录验证失败";
}

2、创建统一返回对象

import com.alibaba.fastjson.JSONObject;

public class AjaxResult extends JSONObject {

    public static AjaxResult success() {
        return success(HttpStatus.SUCCESS_MSG, null);
    }

    public static AjaxResult success(String msg) {
        return success(msg, null);
    }

    public static AjaxResult success(Object data) {
        return success(HttpStatus.SUCCESS_MSG, data);
    }

    public static AjaxResult success(String msg, Object data) {
        return new AjaxResult(HttpStatus.SUCCESS, msg, data);
    }

    public static AjaxResult error(int code, String msg) {
        return new AjaxResult(code, msg, null);
    }

    public static AjaxResult error(int code, String msg, Object data) {
        return new AjaxResult(code, msg, data);
    }

    private AjaxResult(int code, String msg, Object data) {
        super.put("code", code);
        super.put("msg", msg);
        if (data != null) {
            super.put("data", data);
        }
    }
}

3、自定义拒绝访问处理逻辑

import org.example.common.AjaxResult;
import org.example.common.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

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

/**
 * 自定义拒绝访问处理逻辑
 */
@Component("accessDeniedHandler")
public class UserAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        httpServletResponse.setContentType("text/json;charset=utf-8");
        httpServletResponse.getWriter().write(AjaxResult.error(HttpStatus.FORBIDDEN, HttpStatus.FORBIDDEN_MSG).toJSONString());
    }
}

4、自定义未登录的处理逻辑

import org.example.common.AjaxResult;
import org.example.common.HttpStatus;
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;

/**
 * 自定义未登录的处理逻辑
 */
@Component("authenticationEntryPoint")
public class UserAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.setContentType("text/json;charset=utf-8");
        httpServletResponse.getWriter().write(AjaxResult.error(HttpStatus.NOT_LOGIN, HttpStatus.NOT_LOGIN_MSG).toJSONString());
    }
}

5、自定义登录失败处理逻辑

import org.example.common.AjaxResult;
import org.example.common.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
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;

/**
 * 自定义登录失败处理逻辑
 */
@Component("authenticationFailureHandler")
public class UserAuthenticationFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        AjaxResult result;
        if (e instanceof UsernameNotFoundException) {
            result = AjaxResult.error(HttpStatus.NOT_REGISTER, HttpStatus.NOT_REGISTER_MSG);
        } else if (e instanceof BadCredentialsException) {
            result = AjaxResult.error(HttpStatus.PASSWORD_ERROR, HttpStatus.PASSWORD_ERROR_MSG);
        } else {
            result = AjaxResult.error(HttpStatus.AUTH_FAIL, HttpStatus.AUTH_FAIL_MSG, e.getMessage());
        }
        httpServletResponse.setContentType("text/json;charset=utf-8");
        httpServletResponse.getWriter().write(result.toJSONString());
    }
}

6、自定义登录成功处理逻辑

import org.example.common.AjaxResult;
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;

/**
 * 自定义登录成功处理逻辑
 */
@Component("authenticationSuccessHandler")
public class UserAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        //设置响应头
        httpServletResponse.setContentType("text/json;charset=utf-8");
        httpServletResponse.getWriter().write(AjaxResult.success().toJSONString());
    }
}

7、自定义登出成功处理逻辑

import org.example.common.AjaxResult;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;

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

/**
 * 自定义登出成功处理逻辑
 */
@Component("logoutSuccessHandler")
public class UserLogoutSuccessHandler implements LogoutSuccessHandler {
    @Override
    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        httpServletResponse.setContentType("text/json;charset=utf-8");
        httpServletResponse.getWriter().write(AjaxResult.success().toJSONString());
    }
}

8、配置UserWebSecurityConfigurerAdapter类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class UserWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    //注入自定义登录成功处理类
    @Autowired
    private UserAuthenticationSuccessHandler authenticationSuccessHandler;

    //注入自定义失败处理类
    @Autowired
    private UserAuthenticationFailureHandler authenticationFailureHandler;

    //注入自定义未登录处理类
    @Autowired
    private UserAuthenticationEntryPoint authenticationEntryPoint;

    //无权访问
    @Autowired
    private UserAccessDeniedHandler accessDeniedHandler;

    //自定义认证逻辑处理
    @Autowired
    private UserAuthenticationProvider authenticationProvider;

    //自定义登出成功逻辑处理
    @Autowired
    private UserLogoutSuccessHandler logoutSuccessHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //禁用csrf
                .csrf()
                .disable()

                //用户登录
                .formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/login")//自定义登录请求路径
                .successHandler(authenticationSuccessHandler)//登录成功时的处理
                .failureHandler(authenticationFailureHandler)//登录失败时的处理

                //用户登出
                .and()
                .logout()
                .logoutSuccessHandler(logoutSuccessHandler)//登出成功时的处理

                //异常处理
                .and()
                .exceptionHandling()
                .accessDeniedHandler(accessDeniedHandler)//权限不足时的处理
                .authenticationEntryPoint(authenticationEntryPoint)//未登录时的处理

                //请求过滤
                .and()
                .authorizeRequests()
                .antMatchers("/login.html", "/login").anonymous()//登录页与登录请求,只允许匿名访问
                .anyRequest().authenticated();//除此之外,其他请求均需要登录后才可以访问
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider);
    }
}

9、重写测试接口

@PreAuthorize 可用于标识授权信息,具体使用将在下一章说明。
1)@PreAuthorize("hasAuthority('sys:test:test1')")表示用户需要拥有权限标识sys:test:test1才可以访问
2)@PreAuthorize("hasRole('admin')")表示用户需要拥有角色标识admin才可以访问

import org.example.common.AjaxResult;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping
public class TestController {

    @GetMapping("test")
    public AjaxResult test() {
        return AjaxResult.success("test success");
    }

    @PreAuthorize("hasAuthority('sys:test:test1')")
    @GetMapping("test1")
    public AjaxResult test1() {
        return AjaxResult.success("test1 success:hasAuthority('sys:test:test1')");
    }

    @PreAuthorize("hasRole('admin')")
    @GetMapping("test2")
    public AjaxResult test2() {
        return AjaxResult.success("test2 success:hasRole('admin')");
    }

}

10、启动项目并测试接口

测试1:访问http://localhost:8080/login.html,输入账号密码:user4/111111,登录成功后,成功返回JSON对象
在这里插入图片描述
测试2:访问http://localhost:8080/login.html,输入账号密码:user1/222222,登录成功后,成功返回JSON对象
在这里插入图片描述
测试3:访问http://localhost:8080/login.html,输入账号密码:user1/111111,登录成功后,成功返回JSON对象
在这里插入图片描述
测试4:访问http://localhost:8080/test,成功返回JSON对象
在这里插入图片描述
测试5:访问http://localhost:8080/test1,成功返回JSON对象
在这里插入图片描述
测试6:访问http://localhost:8080/test2,成功返回JSON对象
在这里插入图片描述
测试7:访问http://localhost:8080/logout,成功返回JSON对象
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值