Spring Security-限制请求

前言

上面只是验证了用户,并且还可以基于用户赋予了不同的角色,但是对于不同的角色而言其访问的权限也是不一样的.例如,一个网站可能存在普通用户和管理员用户,管理员用户拥有的权限会比破童用户大的多,所以用户给予登录权限之外,还需要对不同的角色赋予不同的权限.在上述配置用户中,继承抽象类WebSecurityConfigurerAdapter,并覆盖configure(AuthenticationManagerBuilder)方法,除此之外,这个抽象类还提供了另外一个方法,那就是configure(httpSecurity),通过它能够实现对不同角色赋予不同权限的功能.
因为WebSecurityConfigurerAdapter已经实现了confgure(HttpSecurity)的方法,所以从他原来的方法进行探讨,起源码如下:

    //WebSecurityConfigurerAdapter默认设定访问权限和登录方式
    protected void configure(HttpSecurity http) throws Exception {
        //只要通过验证就可以访问所有的请求
        //authorizeRequests方法限定只对签名成功的用户允许方法
        //anyRequest方法限定所有请求
        //authenticated方法对所有签名成功的用户允许方法
        this.logger.debug("Using default configure(HttpSecurity). " +
                "If subclassed this will potentially " +
                "override subclass configure(HttpSecurity).");
        ((HttpSecurity)((HttpSecurity)((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)http.authorizeRequests().anyRequest()).authenticated()
                //and方法是连接词,formLogin代表是用Spring Security默认的登录页面
                .and())
                .formLogin()
                //httpBasic方法说明启用HTTP认证
                .and()).httpBasic();
    }

从代码中可以看出,只需要通过用户认证遍可以访问所有请求地址.它还通过formLogin方法配置了使用Spring Security的默认登录页面和httpBasic方法启用了浏览器的Http基础认证方式,所以在默认的情况下,只要登陆了用户,一切的请求就会畅通无阻了,但这往往不是我们真实需要的,毕竟不同的用户有着不同的角色,有时候我们需要根据角色赋予权限.因此在很多的时候需要覆盖掉这个方法,让不同的角色有着不同的权限.

1. 配置请求路径访问权限

对于Spring Security,他允许使用Ant风格或者正则表达式路径限定安全请求,代码如下
展示的是Ant风格的路径限定

    /**
     * 用来配置拦截保护的请求,比如什么请求放行,什么请求需要验证.
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //限定签名后的权限
        http
                /**
                 * 第一段
                 */
                .authorizeRequests()
                //限定"/user/welcome"请求赋予角色ROLE_USER或者ROLE_ADMIN
                .antMatchers("/user/welcome", "/user/details").hasAnyRole("ROLE","ADMIN")
                //限定"/admin/**"下所有请求赋予角色ROLE_ADMIN
                .antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")
                //其他路径允许签名后访问
                .anyRequest().permitAll()
                /**
                 * 第二段
                 */
                //and代表连接词
                .and()
                //对于没有配置权限的其他请求允许匿名访问
                .anonymous()
                /**
                 * 第三段
                 */
                //and代表连接词
                .and()
                //使用Spring Security默认的登录界面
                .formLogin()
                .and()
                //启用Http 基础认证
                .httpBasic();
    }

请注意上面分三段,下面分段论述
首先第一段,authorizeRequests方法表示设置那些需要签名的请求,并且可以将不同的请求权限赋予不同的角色.antMatcher配置的是请求的路径,这里是用的是Ant风格的配置,"/user/welcome"明确指定了请求的路径.接着是hasAnyRole方法,制定了角色"ROLE_ADMIN",“ROLE_USER”,指定了这些路径只能这些角色访问.对于"/admin/**“则是统配指定,只是分配了"ROLE_ADMIN"角色可以访问.注意,hasAnyRole方法默认会加上前缀"ROLE_”,而hasAuthority方法则不会,他们都表示对应的请求路径只有用户分配了对应的角色才能访问.然后anyRequest方法代表任意的没有限定的请求,permitAll方法则是代表没有配置过权限限定的路径允许全部访问.
再看第二段,首先是and方法,他代表连接词,重新加入新的权限验证规则.这里配置了anonymous方法,说明允许匿名访问没有配置过的请求
最后一段,formLogin表示启用Spring Security默认的登录页面,httpBasic方法则是表示启用Http的Basic请求输入用户和密码
关于权限的方法还有很多
在这里插入图片描述
表中的access方法我们后面再谈.通过上面的方法你就可以给予请求的地址一定的权限保护了.有时候需要注意的一点是,对于这里的配置,会采用配置优先的原则,因为有些时候权限会发生冲突.例如,代码中的第二端是允许匿名访问,而没有给出地址.但是因为第一段中加入了权限,所以基于先配置优先的原则,Spring Security还是会采用第一段的限制访问的.因此,在实际工作中,把具体的配置放在前面,把不具体的配置放到后面配置.
上述antMatchers方法采用的是Ant风格的路径,此外也可以采用正则式的规则,这些都是允许的.

        http.authorizeRequests()
                .regexMatchers("/user/welcome","/user/details").hasAnyRole("USER","ADMIN")
                .regexMatchers("/admin/.*").hasAuthority("ROLE_ADMIN")
                .and().formLogin()
                .and().httpBasic();

这个时候就是采用正则表达式的方式给予请求路径的限定

2. 使用Spring表达式配置访问权限

有时候需要更加强大的验证功能,而上述功能只是使用方法进行配置,为了更加灵活,我们还可使用Spring EL进行配置.这里就需要使用access方法,他的参数就是一个SPring表达式,如果这个表达式返回true,就允许访问,否则就不允许.初次之外,Spring Security还提供了一些有用的表达式语言来增强原有的功能,我们这届学习他

    /**
     * 用来配置拦截保护的请求,比如什么请求放行,什么请求需要验证.
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //限定签名后的权限
        http
                /**
                 * 第一段
                 */
                .authorizeRequests()
                //限定"/user/welcome"请求赋予角色ROLE_USER或者ROLE_ADMIN
                .antMatchers("/user/welcome", "/user/details").access("hasRole('USER') or hasRole('ADMIN')")
                //限定"/admin/welcome"下所有请求赋予角色ROLE_ADMIN,要求完整登录,非记住我登录
                .antMatchers("/admin/welcome1").access("hasAuthority('ROLE_ADMIN') && isFullyAuthenticated()")
                //限定"/admin/weclome2"请求赋予角色ROLE_ADMIN,允许不完整登录
                .antMatchers("/admin/welcome2").access("hasAuthority('ROLE_ADMIN')")
                //使用记住我功能
                .and().rememberMe()
                /**
                 * 第三段
                 */
                //and代表连接词
                .and()
                //使用Spring Security默认的登录界面
                .formLogin()
                .and()
                //启用Http 基础认证
                .httpBasic();

上述代码使用了三个Spring表达式,借助他们来实现配置访问权限的功能.其中第一个表达式使用hasRole方法,通过他的参数限定角色"ROLE_USERE"或者"ROLE_ADMIN"角色采拥有访问权,并且要求完整登录,不接受"记住我(Remember Me)"这种验证方式的访问.关于Remember Me,后面会在进行讨论;第三个表达式是允许"ROLE_ADMIN"角色进行访问,最后加粗的remenberMe方法是启用记住我功能
除了上面代码延时的记住我方法之外,SPring Security还提供了一下的方法
在这里插入图片描述

3. 强制使用HTTPS

在一些实际的工作环境中,如银行,商品购物等,对于银行密码,账户,身份信息等往往都是十分敏感的,对于这些信息,需要更加谨慎的保护.通过Http协议采用证书进行加密,对于那些敏感信息就可以加密进行保护了.对于需要加密的页面,在Spring中可以强制使用HTTPS请求.代码如下

                //使用安全渠道,限定为https请求
        http.requiresChannel().antMatchers("/admin/**").requiresSecure()
                .and()
                //不使用https请求
                .requiresChannel().antMatchers("/user/**").requiresInsecure()
                

这里的requiresChannel方法说明使用通道,然后antMatchers是一个限定请求,最后使用recquiresSecure表示使用HTTPS请求.这样对于Ant风格下的地址"/admin/**"就只能使用HTTPS协议进行请求了,而对于requiresInsecure请求则是取消安全请求的机制,这样就可以使用普通的HTTP请求了.

4. 防止跨站点请求伪造

跨站点请求伪造(Cross-Site Request Forgery)是一种常见的攻击手段,我们先来了解一下什么是CSRF.
如图所示,首先是浏览器请求安全网站,于是可以进行登录,在登录之后,浏览器会记住一些信息,以Cookie的形式保存,然后在不关闭浏览器的情况下,用户可能访问一个危险网站,危险网站通过获取Cookie信息来伪造用户的请求,进而请求安全网站,这样就会给网站带来很大的危险
在这里插入图片描述

为了克服这个危险,Spring Security提供了方案来处理CSRF过滤器.在默认的情况下,他会启动这个过滤器来防止CSRF攻击.当然我们也可以关闭这个功能.例如,使用代码

        http.csrf().disable().authorizeRequests();

就可以关闭CSRF过滤器的验证了,只是这样就会给网站带来一定被攻击的风险,因此大部分情况下,都不建议关闭这个功能.
那么对于不关闭CSRF的Spring Security,每次HTTP请求的表单(FORM)就要求存在CSRF参数.当访问表单时,Spring Security就会生成CSRF参数,放进表单中,这样当提交表单到服务器时,就要求连同CSRF表单一起提交服务器.SPring Security就会对CSRF参数进行判断,判断是否与其生成的保持一致.如果一致(和验证码差不多啊),他就不会人为该请求来自CSRF攻击;如果CSRF参数为空或者与服务器的不一致,他就人为这是一个来自CSRF的攻击而拒绝请求.因为这个参数不再cookie中,所以第三方网站是无法伪造的(重点不再Cookie中),这样就可以避免CSRF攻击
假设已经设置好路径"/csrf/form",请求映射为"/security/csrf_form.html",下面需要给这个表单添加参数token的信息,如代码所示

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" http-equiv="Content-Type" content="text/html">
    <title>CSRF_FORM</title>
</head>
<body>
    <form action="./commit" method="post">
        <input id="name" type="text" value="">
        <input type="hidden" id="${_csrf.parameterName}" name="${_csrf.parameterName}" value="${_csrf.token}">
    </form>
</body>
</html>

注意JSTL表达式,其中_csrf对象是Spring提供的.当启用CSRF攻击的安全认证功能之后,SPring Security机制就会生成对应的CSRF参数,他的属性parameterName代表的是名称,属性token代表的是token值,这些都会放到表单的隐藏域中,所以在提交的时候会提交到服务器后端.这时Spring Security的CSRF过滤器就回去验证这个token参数是否有效,进而避免CSRF攻击

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值