spring sercurity之鉴权

本文深入探讨Spring Security的鉴权流程,包括FilterSecurityInterceptor和MethodSecurityInterceptor的使用,以及如何进行权限控制和自定义鉴权。通过示例说明了如何在配置文件中添加自定义类,实现与FilterSecurityInterceptor共存,并介绍了MethodSecurityInterceptor的启用和配置。同时,讨论了多个HttpSecurity的配置和URL匹配策略。
摘要由CSDN通过智能技术生成

github的项目源码,建议 导入项目后,运行 然后看着博客学习。
document\urp.sql 数据库 sql

能力提升

博客只是能把你领进门,有很多特性我没有讲,感兴趣的 可以看 官方 文档
spring sercurity官方文档
如果只是满足于怎么样spring sercurity博客就可以,如果想各种定制那么还是官方文档和源码吧。


在上一篇博客登录用户,我们需要对资源 url进行保护,这个就用到了鉴权。
我个人理解,spring sercurity 的鉴权的类 主要有这两个类。当然 我们也可以自定义类来完成相同的功能。

  1. FilterSecurityInterceptor 这个类和我们配置文件的authorizeRequests息息相关,例如 那个url 需要登录,哪个url 不需要登录 就可以访问。
  2. MethodSecurityInterceptor方法层面的权限控制,和注解一起使用的,例如@PreAuthorize

这两个一个是处理 认证的,也就是 你登录了没有,一个是 你看你这个用户 有没有权限能用这个。 这时候 也需要 有人会问,如果没登录 就到MethodSecurityInterceptor 会怎么样?
这里我很明确的回答一下。如果 一个url你permitAll了,在controller方法哪里 又使用了注解@PreAuthorize。那么你访问这个url 还是提示没有权限的。 因为permitAll()会默认的生成一个匿名用户,@PreAuthorize进行权限鉴权时候,是对匿名用户鉴权的。


AbstractSecurityInterceptor是FilterSecurityInterceptor 和MethodSecurityInterceptor的共同父类。重写他的beforeInvocation方法就可以实现 自定义的权限鉴权业务

鉴权流程

在这里插入图片描述
1. 查找与当前请求关联的“configuration attributes”
2. 提交 secure object(安全对象),Authentication ,configuration attributes,给AccessDecisionManager 的decide方法 进行认证。在FilterSecurityInterceptor中,decide的参数object类型为FilterInvocation,MethodSecurityInterceptor中object类型为MethodInvocation,具体类型是ReflectiveMethodInvocation
3. 可选的 ,在发生调用的 改变 Authentication
4. 假设已授予访问权限,允许继续对安全对象调用,就是可以访问这个安全对象
5. 如果配置了 AfterInvocationManager 就调用它, 如果 上面出现异常 就不会调用它。



流程 进入SecurityInterceptor后,首先走 它的doFilter方法,包装一下request ,response。调用invoke()调用beforeInvocation方法调用SecurityMetadataSource获取ConfigAttribute集合丛SecurityContext里面取出Authentication认证对象,如果取出的Authentication没有认证过,那就调用authenticationManager再认证一下调用accessDecisionManager的decide方法 进行权限鉴权。抛异常的就是不允许访问,没有异常的 就是通过的。→调用RunAsManager为当前的current secure object创建一个临时的对象。→beforeInvocation返回一个InterceptorStatusToken尝试再调用FilterChain进行过滤→调用finallyInvocation设置SecurityContext→最后调用afterInvocation,如果有afterInvocationManager 则再进行一次鉴权过称。结束

FilterSecurityInterceptor

没有什么好讲的。反正 只要知道流程了,这个类我们不能替换调用,只能替换掉这个类的内部引用。或者 在Filter Chain 哪里 加入 我们自定义的类。也就是 自定义的类和FilterSecurityInterceptor 共存。如下如所示
在这里插入图片描述
我们可以在Filter Chain 添加自定义的类 FilterSecurityInterceptor 也一直会存在 。
在配置文件里面 配置如下

package com.example.sercurity.config;

import com.example.sercurity.component.MyFilter;
import com.example.sercurity.component.RestAuthenticationEntryPoint;
import com.example.sercurity.component.RestfulAccessDeniedHandler;
import com.example.sercurity.config.sercurity.*;
import com.example.sercurity.service.PermissonService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.ObjectPostProcessor;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

/**
 * 配置token登录的
 *
 * @Author: plani
 * 创建时间: 2019/8/16 17:50
 */
@Configuration
@EnableWebSecurity
//启用 方法鉴权
//下面这个注解 ,项目只能有一个类可以使用,要注意
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
@Order(3)
public class TokenSecurityConfig extends WebSecurityConfigurerAdapter {
   
    private Logger logger = LoggerFactory.getLogger(FormSecurityConfig.class);
    @Autowired
    private PermissonService permissonService;

    @Autowired
    private RestfulAccessDeniedHandler restfulAccessDeniedHandler;
    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;

    @Autowired
    private MyAuthticationProvider myAuthticationProvider;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
   

        httpSecurity.csrf().disable()//跨域攻击去除
                .sessionManagement()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值