玩转SpringSecurity之四授权规则配置

1.授权资源规则匹配器

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

antMatchers

antMatcher表示的是匹配放行,而antMatchers则是放行匹配到的多个资源的意思,是通过传入可变参实现的。
在这里插入图片描述
在这里插入图片描述
通常我们都需要放行一些通过的路径,如登录错误等,还有一个就是静态的资源。
在这里插入图片描述

放入图片,测试:
在这里插入图片描述
在这里插入图片描述
加入b.jpg和c.png,分别访问:

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

regexMatchers

使用正则表达式放行
在这里插入图片描述
在这里插入图片描述
访问jpg会被拦截,而c.png会直接放行。

使用正则匹配http请求:
在这里插入图片描述
在这里插入图片描述
使用get请求被拦截了,我们使用postman发送post请求试试:
在这里插入图片描述
ok没问题

antMatchers

使用mvc匹配器:注意需要匹配前缀使用,在配置文件中配置
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
使用postman发post请求访问http://localhost:8686/mvc/hello
在这里插入图片描述
重载其他方法

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

在这里插入图片描述
当然以上方法都可以使用antMatchers完成请求:
在这里插入图片描述
加个hello world试试
在这里插入图片描述

在这里插入图片描述
以上就是资源匹配的使用以及配置

2.内置访问方法

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

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

3.角色权限判断

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

3.1权限判断

3.1.1 hasAuthority具有权限

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

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

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

然后我们修改一下前端界面加个子界面
在这里插入图片描述
在这里插入图片描述
ok现在就登录验证一下,重启应用直接访问localhost:8686/main.html
被拦截,回到登录页
在这里插入图片描述

登录看看
在这里插入图片描述
在这里插入图片描述

现在把授权要求需要有的权限改了,改成aaa试试,当然为了避免一些其他因素的干扰,我们把页面进行调整,把error.html移到静态页面下,认证失败的自定义页面也先关闭
在这里插入图片描述
在这里插入图片描述登录后访问的页面响应为一个异常页面,类型为禁止访问,状态码为403

3.1.2 hasAnyAuthority具有任意权限

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

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

在这里插入图片描述

3.2 角色判断

看一下源码
在这里插入图片描述
匹配的时候会拼写一个以ROLE_开头的字符串,所以说明我们UserDetails里那的权限也需要,否则将不匹配。

3.2.1hasRole拥有角色

同样的成功,使用admin角色试试
在这里插入图片描述
在这里插入图片描述
我们把角色要求变一下,变vip才可以。
在这里插入图片描述
不匹配所以不行值得注意的是匹配规则是区分大小写的,所以需要注意一下,我们可以尝试变Admin要求是不行的,同时测试hasAnyRoles

3.2.2 hasAnyRoles拥有任意角色

在这里插入图片描述
我们用户有的还是ROLE_admin权限,反正此前干扰结果,我们多刷新几次maven以及重启项目:
在这里插入图片描述
403没毛病。
这时候我们再加上admin也可以看看!
在这里插入图片描述

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

3.3ip判断

在这里插入图片描述
测试,我们使用localhost和127.0.0.1分别测试,确实有不同的效果
在这里插入图片描述

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

如果我们想使用自定义403就必须实现拒绝访问处理器接口:
在这里插入图片描述
在这里插入图片描述

我们把权限匹配请求要求的匹配要求换一下,换成一个没有的角色,登陆后访问main1.html
在这里插入图片描述

在这里插入图片描述

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

5.1 access()方法

在这里插入图片描述
在这里插入图片描述
可见我们此前调用的方法都是走的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’)

试一试:

在这里插入图片描述
在这里插入图片描述

试试角色判断:
在这里插入图片描述
在这里插入图片描述
main1.html被拦截了,需要登录认证。

在这里插入图片描述
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;
    }
}

在这里插入图片描述
在这里插入图片描述

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

接下来就是使用postman测试:
即先登录:
在这里插入图片描述
成功访问到main页面
在这里插入图片描述
点解访问main1.html
在这里插入图片描述在这里插入图片描述
测试此前编写的post请求的hello方法也一样,说明成功了。

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

Spring Security中,通过配置访问控制列表(Access Control List,ACL)来实现授权规则授权规则可以在Spring Security的XML配置文件中定义。 以下是一个示例配置文件,其中定义了两个授权规则: ``` <http auto-config="true"> <intercept-url pattern="/admin/**" access="ROLE_ADMIN" /> <intercept-url pattern="/**" access="ROLE_USER" /> <form-login /> </http> <authentication-manager> <authentication-provider> <user-service> <user name="user" password="password" authorities="ROLE_USER" /> <user name="admin" password="password" authorities="ROLE_ADMIN" /> </user-service> </authentication-provider> </authentication-manager> ``` 上述配置文件中,`<http>` 标签用于配置访问控制规则,其中 `<intercept-url>` 标签用于定义 URL 匹配模式和对应的授权规则。此处定义了两个规则:对于 `/admin/**` 的请求,要求用户拥有 `ROLE_ADMIN` 角色;对于其他所有请求,要求用户拥有 `ROLE_USER` 角色。 `<authentication-manager>` 标签用于配置身份认证的方式,此处使用了内存中的用户信息进行认证。 如果要自定义授权规则,可以实现 `AccessDecisionVoter` 接口,并将自定义的投票器配置到 `<http>` 标签中: ``` <http auto-config="true"> <intercept-url pattern="/admin/**" access="ROLE_ADMIN" /> <intercept-url pattern="/**" access="ROLE_USER" /> <form-login /> <access-decision-manager> <decision-voters> <bean class="com.example.CustomVoter" /> </decision-voters> </access-decision-manager> </http> ``` 以上配置文件中,`<access-decision-manager>` 标签用于配置访问决策管理器,其中 `<decision-voters>` 标签用于定义投票器列表。`<bean>` 标签用于定义自定义投票器的实现类。在自定义投票器中,可以编写自己的授权规则逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值