Spring-Boot 权限控制

实现权限控制

Spring-Boot 权限控制 一般基于两种方式来实现 一种是url 另一种是基于code也就是注解来实现。

SpringSecurity权限框架

用户登陆,会被AuthenticationProcessingFilter拦截(即认证管理),调用AuthenticationManager的实现,而且AuthenticationManager会调用ProviderManager来获取用户验证信息(不同的Provider调用的服务不同,因为这些信息可以是在数据库上,可以是在LDAP服务器上,可以是xml配置文件上等),
如果验证通过后会将用户的权限信息封装一个User放到spring的全局缓存SecurityContextHolder中,以备后面访问资源时使用。

访问资源(即授权管理),访问url时,会通过AbstractSecurityInterceptor拦截器拦截,
其中会调用FilterInvocationSecurityMetadataSource的方法来获取被拦截url所需的全部权限,
在调用授权管理器AccessDecisionManager,这个授权管理器会通过spring的全局缓存SecurityContextHolder获取用户的权限信息,还会获取被拦截的url和被拦截url所需的全部权限,【然后根据所配的策略】(有:一票决定,一票否定,少数服从多数等),如果权限足够,则返回,权限不够则报错并调用权限不足页面。

Interceptor拦截器

通过Spring Security 配置一个springSecurityFilterChain的Servlet过滤器,来对我们应用中所有的安全相关的事项(保护应用的所有url,验证用户名密码,表单重定向等)负责。

Spring Security原理,使用众多过滤器

UriInvocationSecurityMetadataSourceService

将用户当前角色读取到session中
请求时,通过请求的url查询对应的功能点找到相关连的角色
对比当前用户的角色是否在存在于关联角色中,有则放行,没有则告知没有权限
扩展添加权限注解,有注解的跳过权限验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.us.example.config;

import com.us.example.service.CustomUserService;
import com.us.example.service.MyFilterSecurityInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;

/**
* Created by yangyibo on 17/1/18.
*/


@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private MyFilterSecurityInterceptor myFilterSecurityInterceptor;

@Bean
UserDetailsService customUserService(){ //注册UserDetailsService 的bean
return new CustomUserService();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserService()); //user Details Service验证
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated() //任何请求,登录后可以访问
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.permitAll() //登录页面用户任意访问
.and()
.logout().permitAll(); //注销行为任意访问
http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
}
}

注解
@Autowired默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常

@Qualifier限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者,具体使用方式如下:

读取和写入分开
系统加载时根据子系统区分缓存用户角色功能

权限扩展

因为企业后台业务系统的权限和用户、组织机构这些是无法解耦的,而无论是spring security还是shiro对用户的自定义支持有限,对组织机构的支持则一点都没有