玩转SpringSecurity之四授权规则配置

文章目录

    • 1.授权资源规则匹配器
      • antMatchers
      • regexMatchers
      • antMatchers
    • 2.内置访问方法
    • 3.角色权限判断
      • 3.1权限判断
        • 3.1.1 hasAuthority具有权限
        • 3.1.2 hasAnyAuthority具有任意权限
      • 3.2 角色判断
        • 3.2.1hasRole拥有角色
        • 3.2.2 hasAnyRoles拥有任意角色
        • 3.3ip判断
    • 4.自定义403拒绝访问响应
    • 5.基于表达式的访问控制
      • 5.1 access()方法
      • 5.2自定义access方法

1.授权资源规则匹配器

授权呢就是分配访问权限,可使用的方法,我们可通过点击进入传的参数对象进行查看。

antMatchers

antMatcher表示的是匹配放行,而antMatchers则是放行匹配到的多个资源的意思,是通过传入可变参实现的。
玩转SpringSecurity之四授权规则配置_第1张图片
玩转SpringSecurity之四授权规则配置_第2张图片
通常我们都需要放行一些通过的路径,如登录错误等,还有一个就是静态的资源。
玩转SpringSecurity之四授权规则配置_第3张图片

放入图片,测试:
在这里插入图片描述
玩转SpringSecurity之四授权规则配置_第4张图片
加入b.jpg和c.png,分别访问:

玩转SpringSecurity之四授权规则配置_第5张图片
在这里插入图片描述
值得注意的是b.jpg有可能被拦截,最后重启项目以及刷新几次maven,而访问c.png则会被拦截,跳转到登录页面,登录后就可以查看到c.png了
玩转SpringSecurity之四授权规则配置_第6张图片

regexMatchers

使用正则表达式放行
玩转SpringSecurity之四授权规则配置_第7张图片
玩转SpringSecurity之四授权规则配置_第8张图片
访问jpg会被拦截,而c.png会直接放行。

使用正则匹配http请求:
玩转SpringSecurity之四授权规则配置_第9张图片
玩转SpringSecurity之四授权规则配置_第10张图片
使用get请求被拦截了,我们使用postman发送post请求试试:
玩转SpringSecurity之四授权规则配置_第11张图片
ok没问题

antMatchers

使用mvc匹配器:注意需要匹配前缀使用,在配置文件中配置
玩转SpringSecurity之四授权规则配置_第12张图片

玩转SpringSecurity之四授权规则配置_第13张图片
玩转SpringSecurity之四授权规则配置_第14张图片
使用postman发post请求访问http://localhost:8686/mvc/hello
玩转SpringSecurity之四授权规则配置_第15张图片
重载其他方法

.mvcMatchers(HttpMethod.POST,"/hello").permitAll()

玩转SpringSecurity之四授权规则配置_第16张图片
当然以上方法都可以使用antMatchers完成请求:
玩转SpringSecurity之四授权规则配置_第17张图片
加个hello world试试
玩转SpringSecurity之四授权规则配置_第18张图片

玩转SpringSecurity之四授权规则配置_第19张图片
以上就是资源匹配的使用以及配置

2.内置访问方法

其实内置访问方法我们一直都有使用:permitAll方法和authenticated方法,看看源码吧:
玩转SpringSecurity之四授权规则配置_第20张图片
表达式网址授权配置器:ExpressionUrlAuthorizationConfigurer
可以看到,里面有可以看到有6种属性,每种属性都对应一个方法,permitAll是允许所有,denyAll是拒绝所有,anonymous是允许匿名的,authenticated是需要认证,fullyAuthenticated是需要完整的认证,rememberMe是记住我,比如7天免登录这种。这6个方法无法单独使用,需要配合antMatchers等方法一起使用。

使用方法permitAll就是案例就不累述了,自己尝试即可。

3.角色权限判断

除了内置权限控制。Spring Security中还支持很多其他权限控制。这些方法一般都用于用户已经被认证后,判断用户是否具有特定的要求。例如我们使用视频网站一些看有vip权限才能看的视频,这时候就需要根据角色权限判断了。当然还有更细粒度的直接就是权限对比。

3.1权限判断

3.1.1 hasAuthority具有权限

接下来就分别演示使用角色以及权限来完成登录后访问特定资源
首先把此前使用mvc前缀的配置注释掉:

玩转SpringSecurity之四授权规则配置_第21张图片

玩转SpringSecurity之四授权规则配置_第22张图片
玩转SpringSecurity之四授权规则配置_第23张图片

在配置里,我们拥有这个定义的admin和calmtho,所以我们现在登录上的账户是满足在授权匹配要求的的地方代码要求的。

然后我们修改一下前端界面加个子界面
玩转SpringSecurity之四授权规则配置_第24张图片
玩转SpringSecurity之四授权规则配置_第25张图片
ok现在就登录验证一下,重启应用直接访问localhost:8686/main.html
被拦截,回到登录页
玩转SpringSecurity之四授权规则配置_第26张图片

登录看看
玩转SpringSecurity之四授权规则配置_第27张图片
玩转SpringSecurity之四授权规则配置_第28张图片

现在把授权要求需要有的权限改了,改成aaa试试,当然为了避免一些其他因素的干扰,我们把页面进行调整,把error.html移到静态页面下,认证失败的自定义页面也先关闭
玩转SpringSecurity之四授权规则配置_第29张图片
玩转SpringSecurity之四授权规则配置_第30张图片登录后访问的页面响应为一个异常页面,类型为禁止访问,状态码为403

3.1.2 hasAnyAuthority具有任意权限

测试下一个api调用多个权限中有一个即可的方法:

.antMatchers("/main1.html").hasAnyAuthority("aaa","admin")

玩转SpringSecurity之四授权规则配置_第31张图片

3.2 角色判断

看一下源码
玩转SpringSecurity之四授权规则配置_第32张图片
匹配的时候会拼写一个以ROLE_开头的字符串,所以说明我们UserDetails里那的权限也需要,否则将不匹配。

3.2.1hasRole拥有角色

同样的成功,使用admin角色试试
玩转SpringSecurity之四授权规则配置_第33张图片
玩转SpringSecurity之四授权规则配置_第34张图片
我们把角色要求变一下,变vip才可以。
玩转SpringSecurity之四授权规则配置_第35张图片
不匹配所以不行值得注意的是匹配规则是区分大小写的,所以需要注意一下,我们可以尝试变Admin要求是不行的,同时测试hasAnyRoles

3.2.2 hasAnyRoles拥有任意角色

玩转SpringSecurity之四授权规则配置_第36张图片
我们用户有的还是ROLE_admin权限,反正此前干扰结果,我们多刷新几次maven以及重启项目:
玩转SpringSecurity之四授权规则配置_第37张图片
403没毛病。
这时候我们再加上admin也可以看看!
在这里插入图片描述

玩转SpringSecurity之四授权规则配置_第38张图片
在权限与角色的粒度中,角色的权限较粗,而权限方面的粒度则会细一点,我们可以把权限和资源关联起来,例如挂载在菜单上,作为菜单按钮,然后菜单按钮附上权限,比如有这个权限的即可,然后让角色和菜单管理,什么角色配上什么菜单,当突然加了一个角色,我们只需要给这个角色配置相应的菜单即按钮权限,然后用户再管理这个角色即可,进一步解耦。这样直接和用户的耦合就会变小,更易维护。

3.3ip判断

玩转SpringSecurity之四授权规则配置_第39张图片
测试,我们使用localhost和127.0.0.1分别测试,确实有不同的效果
玩转SpringSecurity之四授权规则配置_第40张图片

4.自定义403拒绝访问响应

如果我们想使用自定义403就必须实现拒绝访问处理器接口:
玩转SpringSecurity之四授权规则配置_第41张图片
玩转SpringSecurity之四授权规则配置_第42张图片

我们把权限匹配请求要求的匹配要求换一下,换成一个没有的角色,登陆后访问main1.html
玩转SpringSecurity之四授权规则配置_第43张图片

玩转SpringSecurity之四授权规则配置_第44张图片

5.基于表达式的访问控制

5.1 access()方法

玩转SpringSecurity之四授权规则配置_第45张图片
玩转SpringSecurity之四授权规则配置_第46张图片
可见我们此前调用的方法都是走的access()表达,那我们完全可以直接调用access()方法实现和此前一样的效果。

以下为常见的内置表达式:

表达式 描述
hasRole([role]) 如果当前主体具有指定角色,则返回true。默认情况下,如果提供的角色不以"ROLE_"开头,则会添加该角色。这可以通过修改DefaultWebSecurityExpressionHandler上的defaultRolePrefix来进行自定义。
hasAnyRole([role1,role2]) 如果当前主体具有任何提供的角色(以逗号分隔的字符串列表给出),则会返回true。默认情况下,如果提供的角色不以"ROLE_"开头,则会添加该角色。这可以通过修改DefaultWebSecurityExpressionHandler上的defaultRolePrefix来进行自定义。
hasAuthority([authority]) 如果当前主体具有指定的权限,则返回true
hasAnyAuthority([authority1,authority2]) 如果当前主体具有任何提供的权限(以逗号分隔的字符串列表给出),则返回true
principal 允许直接访问代表当前用户的主体对象
authentication 允许直接访问从SecurityContext获取的当前Authentication对象
permitAll 始终评估为true
denyAll 始终评估为false
isAnonymous() 如果当前主体是匿名用户,则返回true
isRememberMe() 如果当前主体是remember-me用户,则返回true
isAuthenticated() 如果不是匿名用户,则返回true
isFullyAuthenticated() 如果不是匿名用户或记住我用户,则返回true
hasPermission(Object target,Object permission) 如果用户有权访问给定权限的提供目标,则返回true。例如,hasPermission(domainObject,‘read’)
hasPermission(Object targetId,String targetType,Object permission) 如果用户有权访问给定权限的提供目标,则返回true。例如,hasPermission(1,‘com.example.domain.Message’,‘read’)

试一试:

在这里插入图片描述
玩转SpringSecurity之四授权规则配置_第47张图片

试试角色判断:
玩转SpringSecurity之四授权规则配置_第48张图片
玩转SpringSecurity之四授权规则配置_第49张图片
main1.html被拦截了,需要登录认证。

玩转SpringSecurity之四授权规则配置_第50张图片
ok其他的也一样由于篇幅问题,就不再测试,可以自行测试

5.2自定义access方法

在实际项目中很有可能出现需要自己自定义逻辑的情况。比如判断登录用户是否具有访问当前URL权限。

代码如下:
首先自定义接口:

import org.springframework.security.core.Authentication;
import javax.servlet.http.HttpServletRequest;
public interface MyService {
     

    /**判断是否有权限*/
    boolean hasPermission(HttpServletRequest request, 
          Authentication authentication);
}

实现类

@Component
public class MyServiceImpl implements MyService {
     
    @Override
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
     
        // 获取当前主体
        Object obj = authentication.getPrincipal();
        // 如果属于UserDetails
        if (obj instanceof UserDetails) {
     
            // 下转型
            UserDetails userDetails = (UserDetails) obj;
            // 获取主体的所有权限
            Collection<? extends GrantedAuthority> authorities = userDetails
                    .getAuthorities();
            SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(
                                      request.getRequestURI());
            boolean res = authorities.contains(simpleGrantedAuthority);
            return res;
        }
        return false;
    }
}

玩转SpringSecurity之四授权规则配置_第51张图片
玩转SpringSecurity之四授权规则配置_第52张图片

首先说明我们没有直接放行/main这个路径,只是赋予了user对象的权限里有带有url请求。意思是这个登录后有权访问main页面.没登陆会被拦截。认证后即可成功跳转,main页面,但是/main1.html是无权访问的,会响应无权限。

接下来就是使用postman测试:
即先登录:
玩转SpringSecurity之四授权规则配置_第53张图片
成功访问到main页面
玩转SpringSecurity之四授权规则配置_第54张图片
点解访问main1.html
玩转SpringSecurity之四授权规则配置_第55张图片玩转SpringSecurity之四授权规则配置_第56张图片
测试此前编写的post请求的hello方法也一样,说明成功了。

到此我们已经把写在config方法里的可用授权这方面的api都玩了一遍。写的仓促,里面有些多余的东西,例如上面的图片一开始阅读源码有点误会,在方法里new了一个集合,后面忘记删了,还有一个就是子页面的标题忘记改了,还是叫主页面。在这里说明一下,避免产生疑虑

你可能感兴趣的:(权限安全)