07-08-自定义认证授权过滤器-自定义权限访问拒绝处理器

数据库中的数据

com.itheima.security.controller.UserController

package com.itheima.security.controller;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.security.PermitAll;

/**
 * @author by itheima
 * @Date 2022/1/22
 * @Description
 */
@RestController
public class UserController {
    @PreAuthorize("hasAnyAuthority('P1','P5')")
    @GetMapping("/hello")
    public String hello() {
        return "hello security";
    }
//{"username":"itheima","password":"123456"}
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/say")
    public String say() {
        return "say security";
    }

    @PermitAll
    @GetMapping("/register")
    public String register() {
        return "register security";
    }
}

 itcast用户可以访问/say和/hello接口,itheima用户可以访问/hello,没有权限访问/say

不携带token,也就是游客(未登录用户)访问 

 注意用Postwoman测试的时候要禁用缓存,不然会有实际访问的用户变成缓存的用户访问的情况

可以看到游客和已经登录但是对某些资源没有权限的用户访问返回的都是相同的响应,不便于用户体验,现在针对不同类型的访问,响应不同的内容,给用户相应的提示

新建com.itheima.security.handler.MyAccessDenyHandler

package com.itheima.security.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;

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;

/**
 * 用户无权限访问,访问拒绝的处理器
 */
public class MyAccessDenyHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("UTF-8");
        Map<String, String> info = new HashMap<>();
        info.put("msg", "无权限访问");
        info.put("code", "0");
        info.put("data", "");
        response.getWriter().write(new ObjectMapper().writeValueAsString(info));
    }
}

在SecurityConfig类中配置处理器

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin().and().logout().permitAll().and().csrf().disable().
                authorizeRequests();
        //将自定义过滤器加入过滤器链并在默认的过滤器的前面执行
        http.addFilterBefore(myUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
        //配置授权过滤器,为了保证资源安全,给与最高优先级,在自定义认证过滤器之前执行
        http.addFilterBefore(authenticationFilter(), MyUsernamePasswordAuthenticationFilter.class);
        //配置拒绝处理器
        http.exceptionHandling().accessDeniedHandler(new MyAccessDenyHandler());
        //http.exceptionHandling().accessDeniedHandler(new MyAccessDenyHandler()).authenticationEntryPoint(new MyAuthenticationEntryPoint());
    }

测试一下

新建匿名用户访问拒绝处理器com.itheima.security.handler.MyAuthenticationEntryPoint

package com.itheima.security.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;

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;

/**
 * 匿名用户访问拒绝的处理器
 */
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("UTF-8");
        Map<String, String> info = new HashMap<>();
        info.put("msg", "未登录访问");
        info.put("code", "0");
        info.put("data", "");
        response.getWriter().write(new ObjectMapper().writeValueAsString(info));
    }
}

 配置一下

  @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin().and().logout().permitAll().and().csrf().disable().
                authorizeRequests();
        //将自定义过滤器加入过滤器链并在默认过滤器的前面执行
        http.addFilterBefore(myUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
        //配置授权过滤器,为了保证资源安全,给与最高优先级,在自定义认证过滤器之前执行
        http.addFilterBefore(authenticationFilter(), MyUsernamePasswordAuthenticationFilter.class);
        //配置无权限访问拒绝处理器
        //http.exceptionHandling().accessDeniedHandler(new MyAccessDenyHandler());
        //配置无权限访问处理器和匿名用户访问拒绝处理器
        http.exceptionHandling().accessDeniedHandler(new MyAccessDenyHandler()).authenticationEntryPoint(new MyAuthenticationEntryPoint());
    }

测试一下

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码的翠花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值