前言
今天我们重点聊聊授权方式的另外一种:基于HttpServletRequest配置权限
基于HttpServletRequest配置权限
一个典型的配置demo
http.authorizeHttpRequests(requestMatcherRegstry ->
// /admin/** 需要有AMIND角色
requestMatcherRegstry.requestMatchers("/admin/**").hasRole("ADMIN")
// /log/** 只要有AMIND、USER角色之一
.requestMatchers("/log/**").hasAnyRole("ADMIN", "USER")
// 任意请求 只要登录了即可访问
.anyRequest().authenticated()
);
从这里也可以看出,要实现基于RBAC,还是比较容易的。也比较容易使用。但是如果想要动态的增加角色,就需要我们定制AuthorizationManager。
配置原理
HttpSecurity是负责构建DefaultSecurityFilterChain的。而这个安全过滤器链,则是允许我们进行配置的。而authorizeHttpRequests
方法,正是配置AuthorizationFilter的。而我们传入的入参-lambada表达式-则是指引如何配置AuthorizationFilter的。
/**
* 这个方法是HttpSecurity的方法。
* 作用是配置AuthorizationFilter。
* 其入参authorizeHttpRequestsCustomizer正是让我们配置AuthorizationFilter的关键。
* Customizer:就是定制。原理比较容易理解,就是我把你需要配置的东西丢给你,你往里面赋值。
* AuthorizeHttpRequestsConfigurer<HttpSecurity>:这个是Configurer的实现,负责引入过滤器的。这里明显就是引入AuthorizationFilter
* AuthorizationManagerRequestMatcherRegistry:这个就是我们最终配置的东西。而这个配置的正是我们上面的RequestMatcherDelegatingAuthorizationManager。说白了就是往里面添加哪些路径对应哪些AuthorizationManager。只不过,为了方便使用,也帮我们都封装好了。不妨继续往后看看。
*/
public HttpSecurity authorizeHttpRequests(
Customizer<AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry> authorizeHttpRequestsCustomizer)
throws Exception {
ApplicationContext context = getContext();
// 这里干了三个事情:
// 1. 如果当前HttpSecurity不存在AuthorizeHttpRequestsConfigurer,则创建一个,并注册到当前的HttpSecurity对象中。
// 2. 从AuthorizeHttpRequestsConfigurer拿到他的注册器也就是AuthorizationManagerRequestMatcherRegistry
// 3. 调用传入的参数的customize。如此,我们传入的lambda表达式就被调用了。
authorizeHttpRequestsCustomizer
.customize(getOrApply(new AuthorizeHttpRequestsConfigurer<>(context)).getRegistry());
return HttpSecurity.this;
}
public final class AuthorizationManagerRequestMatcherRegistry
extends AbstractRequestMatcherRegistry<AuthorizedUrl> {
/**
* 这是父类的方法
* C代表的是AuthorizedUrl
*/
public C requestMatchers(String... patterns)