springsecurity开启方法级的授权源码分析

Spring Security之基于方法配置权限 基于方法的权限配置的介绍,包括使用场景和设计以及其实现原理 阅读详情
1、话不多说,先说使用步骤然后分析源码:

首先使用 @EnableMethodSecurity 注解开启方法级别的权限认证


### 使用该注解开启方法级权限鉴定
@EnableMethodSecurity

使用了方法权限注解开启了方法级的权限鉴定之后,就可以使用如下注解直接在控制器上使用方法级的权限鉴定了。


### 使用方法级的权限鉴定
@PreAuthorize("hasAuthority('sys:user:update')")

具体使用如下:


@PutMapping("/updateUser")
@Operation(description = "更新用户信息")
@PreAuthorize("hasAuthority('sys:user:update')")
public R<Object> update(@RequestBody User user) {
    // 如果密码不为空,则进行加密处理
    if(StrUtil.isNotBlank(user.getPassword())){
        user.setPassword(passwordEncoder.encode(user.getPassword()));
    }
    return R.ok(userService.updateById(user));
}

@PreAuthorize("hasAuthority('sys:user:update')") 实现逻辑是aop拦截,会拦截每次请求,判断当前访问的用户权限情况,源码如下:


@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface PreAuthorize {

	/**
	 * @return 在调用受保护的方法之前要计算的Spring EL表达式
	 */
	String value();

}

至于 @PreAuthorize 注解的拦截器是如何生效的那就要靠 @EnableMethodSecurity 注解,因为该注解中导入了 @Import({MethodSecuritySelector.class}) 并接入到了IOC容器,因此只需要看 MethodSecuritySelector 类具体是怎么处理方法级的认证的即可。部分关键源码如下:


@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({MethodSecuritySelector.class})		  // 注解的作用就是向IOC容器注入该选择器类
public @interface EnableMethodSecurity {
    boolean prePostEnabled() default true;    // 注意此属性默认为true,后面的源码会用到

    boolean securedEnabled() default false;

    boolean jsr250Enabled() default false;

    boolean proxyTargetClass() default false;

    AdviceMode mode() default AdviceMode.PROXY;
}

MethodSecuritySelector 的部分关键源码如下:


final class MethodSecuritySelector implements ImportSelector {
    private final ImportSelector autoProxy = new AutoProxyRegistrarSelector();

    MethodSecuritySelector() {
    }

    public String[] selectImports(@NonNull AnnotationMetadata importMetadata) {
        if (!importMetadata.hasAnnotation(EnableMethodSecurity.class.getName())) {
            return new String[0];
        } else {
            EnableMethodSecurity annotation = (EnableMethodSecurity)importMetadata.getAnnotations().get(EnableMethodSecurity.class).synthesize();
            List<String> imports = new ArrayList(Arrays.asList(this.autoProxy.selectImports(importMetadata)));
            // 从上面可知 prePostEnabled 默认为true,其他都为false,
            // 因此PrePostMethodSecurityConfiguration会被注册,其他需要待注解中手动属性设置
            if (annotation.prePostEnabled()) {
                imports.add(PrePostMethodSecurityConfiguration.class.getName());
            }

            if (annotation.securedEnabled()) {
                imports.add(SecuredMethodSecurityConfiguration.class.getName());
            }

            if (annotation.jsr250Enabled()) {
                imports.add(Jsr250MethodSecurityConfiguration.class.getName());
            }

            return (String[])imports.toArray(new String[0]);
        }
    }
}

PrePostMethodSecurityConfiguration 部分核心源码如下:


@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
final class PrePostMethodSecurityConfiguration {

    
    // 注册了一个切面
    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    static Advisor preAuthorizeAuthorizationMethodInterceptor(ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
            ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
            ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
            ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider,
            ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
        
        // 创建了一个前置鉴权管理器,前置意为请求被controller处理前
        PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager();
        
        // 前置鉴权管理器设置了一个EL表达式处理器
        manager.setExpressionHandler(
                expressionHandlerProvider.getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, context)));
        
        // 该拦截器实际就是一个定制专门用于 preAuthorize 注解的切面
        AuthorizationManagerBeforeMethodInterceptor preAuthorize = AuthorizationManagerBeforeMethodInterceptor
                .preAuthorize(manager(manager, registryProvider));
        
        // 给拦截器设置上了当前登录用户的 SecurityContextHolder,方便获取认证对象
        strategyProvider.ifAvailable(preAuthorize::setSecurityContextHolderStrategy);
        
        // 给拦截器设置上了授权事件发布器
        eventPublisherProvider.ifAvailable(preAuthorize::setAuthorizationEventPublisher);
        return preAuthorize;
    }

    // 定义了一个EL表达式处理器
    private static MethodSecurityExpressionHandler defaultExpressionHandler(
            ObjectProvider<GrantedAuthorityDefaults> defaultsProvider, ApplicationContext context) {
        DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
        defaultsProvider.ifAvailable((d) -> handler.setDefaultRolePrefix(d.getRolePrefix()));
        handler.setApplicationContext(context);
        return handler;
    }

    // 定义了一个授权管理器
    static <T> AuthorizationManager<T> manager(AuthorizationManager<T> delegate,
            ObjectProvider<ObservationRegistry> registryProvider) {
        return new DeferringObservationAuthorizationManager<>(registryProvider, delegate);
    }

}

下面重点看上面调用的拦截器切面中的 preAuthorize 方法来构造拦截器切面的具体内容吧!

从上面可以看到这个拦截器切面是一个针对特定 PreAuthorize 注解才生效的拦截器,而这个拦截器本身实现了PointcutAdvisor 接口, 而PointcutAdvisor中包含了一个Pointcut成员变量,也就是切点,在加上继承的Advisor接口中的Advice,就形成了一个完整的切面。

因此也就可以说 AuthorizationManagerBeforeMethodInterceptor 拦截器是一个专门用于拦截标有 PreAuthorize 注解的切面。

处理 PreAuthorize 切点中表达式分析过程如下:

上面 PrePostMethodSecurityConfiguration 关键源码中,我们看到注入了一个 MethodSecurityExpressionHandler 表达式处理器,实际使用的是他的实现类DefaultMethodSecurityExpressionHandler 处理器,其中的这部分源码解释可以看出如何使用表达式的过程。

因此,过程就是,授权管理器AuthorizationManager设置了一个方法级前置授权管理器PreAuthorizeAuthorizationManager 和一个EL表达式处理器 MethodSecurityExpressionHandler

然后AuthorizationManager作为参数用于构造切面

因此该切面就拥有的一个可处理EL表达式的处理器DefaultMethodSecurityExpressionHandler

hasAuthority 方法的处理逻辑:

从上面的 hasAuthority 方法的处理过程可以看出,最终是从我们封装的认证对象中获取权限集合,然后从该权限集合中获取权限的字符串名称,将他们组装成一个Set<String>集合,最终的鉴权过程就演变成了遍历字符串集合,判断传入 @PreAuthorize("hasAuthority('sys:user:update')") 的中的字符串sys:user:update 是否被包含在 Set 字符串集合中。原来如此啊!!!是不是突然觉得有一种拨开云雾的感觉呢。

因此,我们要做的就是在登录成功时,将用户角色对应的所有权限(也可以说是菜单或按钮的操作权,例如:sys:user:insert / sys:user:update 等等)全部查出封装成对应的权限对象 GrantedAuthority ,角色和权限不可混为一谈,角色是一组权限的集合,给一个用户赋予了一个角色也就相当于给了他一组权限。

此外,基于权限点和基于角色的授权两者只在验证名称上稍有不同,基于角色的授权中EL表达式中的权限标识会被拼接上 ROLE_ 前缀,如下:

@PreAuthorize("hasRole('admin')") 如果我们这样使用,那么最后和从认证对象中权限名称对比的就是 ROLE_admin ,因此数据库设置角色权限时,名称角色名称需要加上该 ROLE_前缀,可以这样设计: ROLE_admin

我的 Spring Security 参考配置如下:

@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthenticationFilter;
    private final UserDetailService userDetailService;
    private final SmsService tencentSmsService;

    // 访问白名单,可以设计成读取数据库或缓存
    String[] whitelist = {"/sms/**","/auth/**"};

    @Bean
    @SneakyThrows
    public SecurityFilterChain securityFilterChain(HttpSecurity http) {
        // 全局请求策略配置
        http
                .csrf().disable()       // 禁用csrf跨站请求伪造
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers(whitelist).permitAll()     // 白名单全部放行
                        .requestMatchers(HttpMethod.OPTIONS).permitAll()        // options请求放行
                        .anyRequest().authenticated()       // 其他请求需要认证
                )
                // 禁用session,改用JWT的方式
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                // 添加自定义认证过滤器,按照默认的security所有过滤器顺序
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
                // 设置自定义认证、鉴权异常处理
                .exceptionHandling()
                // 自定义认证异常处理
                .authenticationEntryPoint(blogAuthenticationEntryPoint())
                // 自定义鉴权异常处理
                .accessDeniedHandler(blogAccessDeniedHandler());

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        List<AuthenticationProvider> providers = new ArrayList<>(3);
        // 可以设置多个认证处理器
        AuthenticationProvider usernameAuthenticationProvider = new DaoAuthenticationProvider();
        MobileAuthenticationProvider mobileAuthenticationProvider = new MobileAuthenticationProvider(userDetailService,tencentSmsService);
        providers.add(usernameAuthenticationProvider);
        providers.add(mobileAuthenticationProvider);
        return new ProviderManager(providers);
    }


    private BlogAuthenticationEntryPoint blogAuthenticationEntryPoint() {
        return new BlogAuthenticationEntryPoint();
    }

    private BlogAccessDeniedHandler blogAccessDeniedHandler() {
        return new BlogAccessDeniedHandler();
    }


    // 笔记1: 凡是在springsecurity的认证和授权过程中抛出的异常,不论是我们认为抛出的异常还是走源码过程抛出的异常都会被springsecurity过滤器链中的ExceptionTranslationFilter异常处理的过滤器捕获
    // 并调用相应的接口方法进行异常处理,所以会导致这些异常的响应结果和我们自定义的响应结果不一致的情况,为了保证给前端的响应结果的一致性,我们有必要对相应的接口
    // 进行自定义的实现,以此来保证响应结果的统一性。同时在完成自定义处理之后,我们必须将实现注册成Bean,并将他们加入到springsecurity过滤环节的对应节点,
    // 也就是在HttpSecurity对象的对应节点进行配置,以此确保自定义实现的组件能够生效。相应接口有:认证失败处理AuthenticationEntryPoint、鉴权失败处理AccessDeniedHandler

    // 笔记2:  自从springsecurity-5.7.X版本开始,官方将废弃WebSecurityConfigurerAdapter这个springsecurity的适配器类,转而推荐使用向容器注入SecurityFilterChain
    // 安全过滤器链的方法配置springsecurity

    // 笔记3:  spring官方推荐使用构造函数的方式完成依赖注入,相应的我们可以使用lombok的相应注解完成,在开发过程中应当减少使用像@Autowired、@Resource的注解

    // 笔记4: 在我们对springsecurity进行配置时,如果我们不对HttpSecurity对象配置formLogin属性的话,则在过滤器链中将不会存在UsernamePasswordAuthenticationFilter过滤器
    // 原因是在springsecurity的默认配置中为HttpSecurity对象配置了formLogin属性,在该属性中配置了一个默认的登陆页面,同时new了一个UsernamePasswordAuthenticationFilter放了容器
    // 但如果我们自定义配置springsecurity时没有配置formLogin属性则不会走UsernamePasswordAuthenticationFilter这一套的过滤器逻辑。所以,对于认证和授权的实现方案,我们可以总结为两套,
    // 一套是,走我们自定义的过滤器并没有配置formLogin属性的认证方案;另一套是,走springsecurity默认的通过走UsernamePasswordAuthenticationFilter的这一套方案,走这套方案需要我们
    // 在对springsecurity进行自定配置是为HttpSecurity对象配置formLogin属性,此外,我们还可以对这套方案中的一些流程处理进行自定义实现,比如自定义实现AuthenticationSuccessHandler
    // AuthenticationFailureHandler等一些关键性流程的自我定制化实现,以此来更好的完成我们的认证授权。此外、如果我们也想对登出操作进行自定义的话,我们同理可以对HttpSecurity对象配置logout属性
    // 然后自定义实现LogoutSuccessHandler

    // SecurityContextHolderFilter、AuthorizationFilter
    // 如果我们不是用默认的formLogin的方式,则需要自定义认证过滤器,然后在其中使用 AuthenticationManager 来认证登录信息
}

SpringBoot - @EnableGlobalMethodSecurity注解详解 使用@EnableGlobalMethodSecurity注解,用于开启Spring环境的方法级安全,如果实现该方案需要在添加了@Configuration注解的类上再添加@EnableGlobalMethodSecurity注解即可,通常是继承WebSecurityConfigurerAdapter基类,使用自定义的处理器或者过滤器,实现符合业务场景的访问控制。...... 阅读详情

相关推荐

SpringBoot之SpringSecurity权限注解在方法上进行权限认证多种方式

前言 Spring Security支持方法级别的权限控制。在此机制上,我们可以在任意层的任意方法上加入权限注解,加入注解的方法将自动被Spring Security保护起来,仅仅允许特定的用户访问,从而还到权限控制的目的, 当然如果现有的权限注解不满足我们也可以自定义 快速开始 首先加入security依赖如下 <dependency> <groupId>org.springframework.boot</groupId> <artifactI

daTou 1万+

SpringSecurity系列——访问控制之基于方法的控制day6-3(源于官网5.7.2版本)

SpringSecurity的@PreAuthorize、@PostAuthorize、@PreFilter和@PostFilter提供了丰富的基于表达式的支持。如果您需要自定义处理表达式的方式,您可以公开一个自定义MethodSecurityExpressionHandler,就像这样}}方法授权是方法前授权和方法后授权的组合。方法前授权是在调用方法之前执行的。}}}...

qq_51553982的博客 947

SpringSecurity的核心过滤器-CsrfFilter

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

10年老JAVA大数据技术人的专栏 1503

SpringSecurity中文文档(Servlet Method Security)

除了在请求级别进行建模授权之外,Spring Security 还支持在方法级别进行建模。然后,您可以立即使用@PreAuthorize、@PostAuthorize、@PreFilter 和@PostFilter 对任何 Spring 管理的类或方法进行注释,以授权方法调用,包括输入参数和返回值。SpringBootStarterSecurity 默认情况下不激活方法级授权。Method Security 还支持许多其他用例,包括 AspectJ 支持、自定义注释和几个配置点。

znjy111的博客 1716

Spring Security认证授权流程

在以上代码的for循环中,第一次拿到的 provider 是一个 Anonymous Authentication Provider。Spring Security会监听这个事件,接收到这个Authentication对象,进而调用 SecurityContextHolder.getContext().setAuthentication(...)方法,将 Authentication Manager返回的 Authentication对象,存储在当前的 Security Context 对象中。

2303_78503642的博客 3908

SpringSecurityOAuth2登录后无法跳转获取授权码地址,直接跳转根路径原因详解

这篇文章需要结合这篇文章来看, 当完成前面的铺垫问题后,先确保httpBasic登录认证没问题! 配置摘要 至于UserDetailsService、TokenConfig、ResourceServerConfig 令牌配置、AuthorityServerConfig、Controller请自行到本文开头提到的那篇文章中查看 SpringSecurity ResourceServerConfig 其中上面WebSecurityConfig这里重写configure方法可以不重写,因为这里是为了好做权限

程序员劝退师的博客 1万+

SpringSecurity基础及源码分析

SpringSecurity原理及源码分析

oPeiJie1的博客 628

模型参考自适应控制(MRAC):让PID参数动态优化

本文深入解析模型参考自适应控制(MRAC)技术,它通过实时调整PID参数,使控制系统能自动适应系统特性变化和外部干扰。文章详细介绍了MRAC的工作原理、数学基础,并提供了用C语言实现的实战代码示例,帮助工程师解决传统PID控制在非线性、时变系统中参数整定繁琐的难题。

tequila的博客 902

【记录】一文带你搞懂Spring Security认证授权流程!

一文带你搞懂Spring Security认证授权流程!

qq_28952543的博客 1万+

SRAM vs RRAM:存算一体芯片选型指南(含最新技术对比)

本文深入对比了SRAM与RRAM在存算一体芯片设计中的核心差异,为硬件工程师和架构师提供实战选型指南。文章从技术本质、性能、功耗、成本及设计风险等多维度剖析,指出SRAM基于成熟CMOS工艺,适合高精度、低延迟场景;而RRAM凭借非易失性和高密度潜力,在超低功耗、固定模型应用中优势明显。决策需综合项目预算、上市时间及技术储备。

e4f5g6h的博客 936

保姆级教程:在Linux上用IGH EtherCAT主站搞定从站时钟同步(附sync_datagram报文详解)

本文详细介绍了在Linux系统上使用IGH EtherCAT主站实现从站时钟同步的保姆级教程,重点解析了sync_datagram报文的结构和工作原理。通过实战案例和代码示例,帮助开发者掌握微秒级同步精度的实现方法,适用于工业自动化领域的高精度设备协同控制。

weixin_30733003的博客 259

SpringSecurity5-教程3-oauth2登录源码分析

spring-security

一个技术菜鸟的博客 2292

【微服务架构】SpringSecurity核心源码剖析+jwt+OAuth(八):SpringSecurity中的核心过滤器-CsrfFilter

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

专注上位机开发、机器视觉、机器学习、嵌入式软硬件开发 4万+

lisp方格网法计算土方量_分享:两期土方工程量计算(方格网法)实例例题

最近遇到一个飞时达土方软件试用版客户,咨询怎么根据平整前的原始地形图和平整后的现状地形图来计算产生的土方工程量,也就是两期土方量,且需要用方格网法来计算,作为一个老道的工程设计人员,博主对这类的项目实例例题简直太熟悉了,用飞时达土方计算软件V13.0可以很方便的计算出来。 方格网法计算两期土方量流程 一、软件安装及注册 专业的飞时达土方计算软件FastTFT,请到飞时达软件官方网站去下载,注册完...

weixin_35131425的博客 1696

MMORPG网络游戏开发之任务系统的架构与设计

在网路游戏中做任务已经成为游戏很重要的一个核心功能和玩法,如何做好一个灵活可扩展的任务系统的架构与设计,今天来给大家分享一些我们的设计经验。接下来我把整个的任务系统分成以下6个模块:对于单机游戏而言,这6个模块都放在客户端直接处理,对于网路游戏而言,模块1~5实现在服务端,模块6实现在客户端。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习unity的零基础小白,也有一些正在从事unity开发的技术大佬,欢迎你来交流学习。...

voidinit的专栏 3047

@EnableAuthorizationServer授权服务注解源码分析

EnableAuthorizationServer用于开启授权服务器,它使用@Import注解引入了如下2个配置类:授权服务器安全配置类授权服务器端点配置类。

pscool的博客 1099

MVSNet (pytorch版) 搭建环境 运行dtu数据集重建 实操教程(图文并茂、超详细)

MVSNet (pytorch版) 代码注释版 下载 (注释非常详细,代码结构有所调整,使用起来更方便) 深度学习三维重建 MVSNet-ECCV-2018 (源码、pytorch版、原文+注释、译文+批注)Meshlab查看三维点云时 ,使用技巧总结。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 2936

SpringSecurity 一文彻底掌握

大致的认证流程是从 `UsernamePasswordAuthenticationFilter` 开始, UsernamePasswordAuthenticationFilter 继承了 `AbstractAuthenticationProcessingFilter` 当登录请求过来时会调用 父类 AbstractAuthenticationProcessingFilter 的 doFilter 方法,然后判断 `if (!this.requiresAuthentication(request, respo

无奈朝来寒雨晚来风 的博客 1373

CentOS-7-x86_64经典版本的含义

这个版本的ISO文件包含了所有的软件包,所以文件比较大,但在安装过程中不需要下载软件包。如果你有一个稳定的网络连接,并且希望安装时能够选择最新的软件包,或者只安装特定的软件包,那么可以选择NetInstall版本。在这里,它可能是指这个ISO文件发布于2207年2月,但是这似乎是一个错误,因为截止到现在(2022年)的时间,都没有到达2207年。另外,还有一个DVD版本,这个版本的ISO文件包含了大部分常用的软件包,安装时可能需要网络连接,但比NetInstall版本少一些。

舒一笑的博客 3531

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

SpringSecurity登录认证流程及源码分析

10.既然如此,我们只需要实现这个接口重写loadUserByUsername方法,然后从数据路根据用户名查询到用户信息,然后封装成一个loginUser对象,并且对这个用户的基本信息进行一个校验,没问题后就可以返回了,到这里根据用户名查找用户这个验证已经完成了。(配置类的代码最后会统一给)我们直接找到源头,发现这个加密方法是一个PasswordEncoder接口的抽象方法,里面主要两个方法,分别用于对前端输入的密码加密,还有把加密后的密码和用户信息中的密码进行比对。7.那么不用多说,直接进入这个方法。

m0_63624484的博客 1238

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

SpringSecurity简单使用

SpringSecurity shrio,SpringSecurity:认证,授权(VIP1,vip2…) 功能权限 访问权限 菜单权限 拦截器,过滤器:大量的原生代码,冗余 1、pom.xml <!--Thymeleaf--> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5&

qq_43430343的博客 501

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

SpringSecurity-基础入门和源码分析(二)

是一个安全管理框架小白:“spring security安全框架不那么麻烦,学习的时候可以把整体分开,各个击破,明确自己这么做的目的是什么,整个学习过程就没那么累了“

bangiao的博客 304

SpringSecurity5-教程1-用户名密码登录源码分析

spring security

一个技术菜鸟的博客 1254

分布式系统认证解决方案SpringSecurityOAuth2.0(一)认证授权

目录一、简介二、认证2.1 认证流程2.2 代码实现表结构配置类 WebSecurityConfigurerAdapter认证逻辑 UserDetailsService2.3 认证测试匿名访问使用 zs 登录使用 ls 登录三、授权3.1 授权流程3.2 代码实现表结构授权逻辑 PermissionEvaluator@EnableGlobalMethodSecurity开启注解校验@PreAuthorize("hasPermission('/r/r1','p1')")3.3 授权测试使用 zs 登录3.4

DreamsArchitects的博客 1305

SpringSecurity学习笔记(二)

SpringSecurity学习笔记 保护web应用的安全----参考的详细教程,点击这里,感谢大佬! Spring Security(一)–Architecture Overview----参考的详细教程,点击这里,感谢大佬! Spring Security(二)–Guides----参考的详细教程,点击这里,感谢大佬! Spring Security(三)–核心配置解读----参考的详细教程,点击这里,感谢大佬! Spring Security(四)–核心过滤器源码分析----参考的详细教程,点击这里,

weixin_38530160的博客 3180
上一篇: docker中nacos1.0和nacos2.0使用的区别
下一篇: Nacos目录挂载并实现持久化
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

龙茶清欢

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

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

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

打赏作者

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

抵扣说明:

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

余额充值