Spring Security修炼手册(四)————Security默认表达式的权限控制

Stella981
• 阅读 498

        前三章主要讲的是Security对于认证的处理,那么本节,会为大家介绍基于Security默认表达式的权限控制(较为简单,无法满足复杂权限控制及多变的权限规则,后面会介绍基于自定义表达式的权限访问控制,可满足99%的业务场景的需求)。

一、介绍及使用

 直接进入主题,基于默认的表达式权限控制,需要在SecurityConfig中配置,代码如下:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    
    @Autowired
    private SecurityProperties securityProperties;
    @Autowired
    private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
    @Autowired
    private MyAuthenticationFailureHandler myAuthenticationFailureHandler;
    @Bean
    public PasswordEncoder passwordEncoder(){
        
        return new BCryptPasswordEncoder();
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        
        http
            .formLogin()
                .loginPage(securityProperties.getToLoginProperties().getLoginProperties().getLoginPage())//用户未认证时,转跳到认证的页面
                .loginProcessingUrl(securityProperties.getToLoginProperties().getLoginProperties().getLoginProcessingUrl())//form中action的地址,也就是处理认证请求的URL    
                .usernameParameter(securityProperties.getToLoginProperties().getLoginProperties().getUsernameParameter())//form中用户名密码的name名
                .passwordParameter(securityProperties.getToLoginProperties().getLoginProperties().getPasswordParameter())
                .defaultSuccessUrl(securityProperties.getToLoginProperties().getLoginProperties().getDefaultSuccessUrl())//认证成功后默认转跳的URL
                .successHandler(myAuthenticationSuccessHandler)
                .failureHandler(myAuthenticationFailureHandler)
        .and()
        .authorizeRequests()
            .antMatchers(securityProperties.getToLoginProperties().getLoginProperties().getLoginPage(),
                         securityProperties.getToLoginProperties().getLoginProperties().getLoginProcessingUrl()).permitAll()
            .antMatchers(HttpMethod.GET,"/vip").hasRole("admin")//默认权限表达式
            .anyRequest().authenticated()
        .and()
            .csrf().disable()
            ;
    }
    
    

}

    上面代码的含义是,“/vip”这个URL必须是GET请求,且拥有admin权限的用户才可以访问。接下来我们配置一下UserDetailServer,模拟给用户一个admin权限。

@Component
public class MyUserDetailsServer implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // TODO Auto-generated method stub
        if("admin".equals(username)){
            
            throw new RuntimeException("admin禁止登录");
        }
        return new User(username, "$2a$10$ofPkBDUezOJp6Sik63Q/0.QlU8a1itEyzldjSXqfn2nDPqXjN0Ljm", AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }

}

    AuthorityUtils是Security提供的一个工具类,我使用的这个方法的功能是将一个以“,”分割的字符串转换成UserDetail中第三个参数所需要的Collection<? extends GrantedAuthority>。

    全部配置好后我们重启项目,登录。可以看到,我是拥有admin这个权限的,按道理说我有权限访问“/vip”,我们访问一下试试。

   Spring Security修炼手册(四)————Security默认表达式的权限控制

    奇怪?我明明拥有“admin”权限,为什么访问“/vip”确是403,请求被拒绝呢?

Spring Security修炼手册(四)————Security默认表达式的权限控制

二、默认权限表达式源码解析

    第一节中,我们明明可以在Authorites看到当前用户拥有了admin权限,但是却访问被拒绝!这又是为什么呢?下面,我带着大家走一边Security的源码,看一看到底是哪里出现了问题。

    我们依旧在UserdetailsServer中打上断点。

Spring Security修炼手册(四)————Security默认表达式的权限控制

    重启项目,登陆后,访问“/vip”查看断点堆栈信息。我们只看最后一个过滤器,这里我们说过,他会读取我们的SecurityConfig的配置信息,做匹配。我们可以看到虽然我们配置的“/vip”需要的权限是admin,但是框架却自动为我们加上了“ROLE_”的前缀,所以,这就是我们为什么匹配不到,无权限访问的原因。

Spring Security修炼手册(四)————Security默认表达式的权限控制

    我们稍作修改,将UserDetailsServer中的权限加上这个前缀。

Spring Security修炼手册(四)————Security默认表达式的权限控制

我们重启项目,再次访问,可以看到已经有权限了,404是由于我没有写这个页面。

Spring Security修炼手册(四)————Security默认表达式的权限控制

三、自定义异常页面

    在前面的介绍中,无论是403还是404,我们使用的都是提供的默认页面实现,而在我们的实际业务中需要我们使用自己的异常页面,那么怎么配置呢?方法有很多种,比如404页面,我们可以写一个不完全匹配的@RequestMapping 这样由于不完全匹配的优先级是小于完全匹配的优先级的,所以当匹配不到映射的时候就会匹配我们的404了。

    但是我既然单独拿出来写一章,其实完全为了凑字数(一不小心说了实话),那肯定就是有更好的方法的,其实在Spring Boot中,只需要在默认静态资源目录下创建一个与状态码同名的页面,就会在出现异常的时候进入到你的页面中。至于Spring boot的默认资源目录是什么,怎么改,请看我的Spring boot系列博客。

Spring Security修炼手册(四)————Security默认表达式的权限控制

我们访问试一下:

Spring Security修炼手册(四)————Security默认表达式的权限控制

点赞
收藏
评论区
推荐文章
kenx kenx
3年前
轻松上手SpringBoot+SpringSecurity+JWT实RESTfulAPI权限控制实战
前言我们知道在项目开发中,后台开发权限认证是非常重要的,springboot中常用熟悉的权限认证框架有,shiro,还有就是springboot全家桶的security当然他们各有各的好处,但是我比较喜欢springboot自带的权限认证框架xmlorg.springframework.bootspr
kenx kenx
3年前
SpringBoot 优雅配置跨域多种方式及Spring Security跨域访问配置的坑
前言最近在做项目的时候,基于前后端分离的权限管理系统,后台使用SpringSecurity作为权限控制管理,然后在前端接口访问时候涉及到跨域,但我怎么配置跨域也没有生效,这里有一个坑,在使用SpringSecurity时候单独配置,SpringBoot跨越还不行,还需要配置Security跨域才行。什么是跨域跨域是一种浏览器同源安全策略,即浏
kenx kenx
3年前
SpringBoot之SpringSecurity权限注解在方法上进行权限认证多种方式
前言SpringSecurity支持方法级别的权限控制。在此机制上,我们可以在任意层的任意方法上加入权限注解,加入注解的方法将自动被SpringSecurity保护起来,仅仅允许特定的用户访问,从而还到权限控制的目的,当然如果现有的权限注解不满足我们也可以自定义快速开始1.首先加入security依赖如下xmlorg.springframe
Stella981 Stella981
3年前
Spring Security 5 集成 Authing OIDC 单点登录指南
本文以Spring生态中用于提供认证及访问权限控制的SpringSecurity5为例,详细介绍SpringSecurity5如何接入AuthingOIDC。SpringSecurity是一个提供安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了SpringIoC
Stella981 Stella981
3年前
Spring Security入门(基于SSM环境配置)
一、前期准备配置SSM环境二、不使用数据库进行权限控制配置好SSM环境以后,配置SpringSecurity环境1.添加security依赖   <dependency     <groupIdorg.springframework.security<
Wesley13 Wesley13
3年前
PHP RBAC权限控制,基于CI框架(版本3.1.9)
2018年11月7日更新:目前功能已做到事件级别权限控制,如:后台用户的添加操作、删除操作和保存操作等具体到事件级的操作方法有权限则展示相应的操作菜单,没权限则隐藏相应菜单或提示无权限到目前算是真正做到了每一步操作都控制相应的权限,防止错误操作基于CI框架(版本3.1.9)(hmvc模式)的RBAC权限管理,目前功能为:后台菜单全动态
Stella981 Stella981
3年前
Apache Sentry实战之旅(一)—— Impala+Sentry整合
Impala默认是以impala这个超级用户运行服务,执行DML和DDL操作的,要实现不同用户之间细粒度的权限控制,需要与Sentry整合。Sentry是Apache下的一个开源项目,它基于RBAC的授权模型实现了权限控制,Impala与它整合以后,就能实现不同用户之间在应用层的权限认证,从而控制用户的DML、DDL
Wesley13 Wesley13
3年前
Hbase权限控制
Hbase权限配置、使用手册1Hbase权限控制简介Hbase的权限控制是通过AccessControllerCoprocessor协处理器框架实现的,可实现对用户的RWXCA的权限控制。2配置配置hbasesite.xmlCM主页→点击hbase(进入Hbase
Stella981 Stella981
3年前
Agile Lite默认控制器CSS扩展实现H5组件动画切换
AgileLite中提供了很多控制器和组件的交互,但是实际开发过程中还会遇到很多种场景无法满足。这里介绍一下如何使用AgileLite的默认控制器和组件的UI渲染来满足不同的场景需要默认控制器的扩展默认控制器的扩展是指通过CSS样式对控制器进行UI渲染,使得默认控制器的使用场景更丰富。扩展默认控制器的方法
sum墨 sum墨
2个月前
《优化接口设计的思路》系列:第四篇—接口的权限控制
我们在做系统的时候,只要这个系统里面存在角色和权限相关的业务需求,那么接口的权限控制肯定必不可少。但是大家一搜接口权限相关的资料,出来的就是整合Shrio、SpringSecurity等各种框架,然后下面一顿贴配置和代码,看得人云里雾里。实际上接口的权限控制是整个系统权限控制里面很小的一环,没有设计好底层数据结构,是无法做好接口的权限控制的。那么怎么做一个系统的权限控制呢?