一 建表
权限管理需实现5张表:用户表、角色表、用户角色对应表、权限表、权限角色对应表
用户表
CREATE TABLE platform_user
(
id
bigint(20) NOT NULL AUTO_INCREMENT,
username
varchar(50) NOT NULL,
password
varchar(100) NOT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
角色表
CREATE TABLE platform_role
(
id
int(11) NOT NULL AUTO_INCREMENT,
name
varchar(50) NOT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT=‘这只是角色表’;
用户角色对应表
CREATE TABLE platform_role_user
(
id
int(11) NOT NULL AUTO_INCREMENT,
user_id
bigint(20) NOT NULL,
role_id
int(11) NOT NULL,
PRIMARY KEY (id
),
KEY FKt6466kf26ep5v3rfcya2sxi53
(role_id
),
KEY FKfwy3bmkplk822fdp5o1btjyyv
(user_id
),
CONSTRAINT FKfwy3bmkplk822fdp5o1btjyyv
FOREIGN KEY (user_id
) REFERENCES platform_user
(id
),
CONSTRAINT FKt6466kf26ep5v3rfcya2sxi53
FOREIGN KEY (role_id
) REFERENCES platform_role
(id
)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
权限表
CREATE TABLE platform_sys_permission
(
id
int(11) NOT NULL AUTO_INCREMENT,
name
varchar(50) NOT NULL,
description
varchar(50) NOT NULL,
url
varchar(100) NOT NULL,
pid
int(11) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT=‘权限表’;
注意:如果存在子权限,一定要把最大的权限放在最后,否则在下面权限判定时,会出问题。
5. 权限角色对应表
CREATE TABLE `platform_permission_role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role_id` int(11) NOT NULL,
`permission_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `role_id` (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COMMENT='角色权限管理表';
二 实体类
User.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = “username”,nullable = false,length = 50)
private String userName;
@Column(name = “password”,nullable = false,length = 100)
private String password;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = “platform_role_user”, joinColumns = @JoinColumn(name = “user_id”, referencedColumnName = “id”), inverseJoinColumns = @JoinColumn(name = “role_id”, referencedColumnName = “id”))
private List roles;
省略 get set
Role.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
- 权限名
*/
@Column(name = “name”, nullable = false,length = 50)
private String name;
RoleUser.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "user_id")
private Long userId;
@Column(name = "role_id")
private Integer roleId;
Permission.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* 权限名
*/
@Column(name = "name",nullable = false)
private String name;
/**
* 权限描述
*/
@Column(name = "description", nullable = false)
private String description;
/**
* 权限的url
*/
@Column(name = "url", nullable = false)
private String url;
/**
* 父节点id
*/
@Column(name = "pid")
private Integer pid;
PermissionRole.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "role_id")
private Integer roleId;
@Column(name = "permission_id")
private Integer permissionId;
三 security 配置类
/**
@author: 易明星
@Modified By:
@Date: Create in 13:27 2019/6/24
@Description: 权限配置
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowired
private MyFilterSecurityInterceptor myFilterSecurityInterceptor;@Autowired
private CustomUserDetailService userDetailService;/**
- 密码加密的方式
- @return
*/
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
- 加密密码
- @param auth
- @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder());
}
/**
- security 具体的配置
- @param http
- @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() //csrf不可用
.authorizeRequests()
.antMatchers("/static/", "/css/", “/js/", "/images/”, “/lib/**”).permitAll() //访问允许静态文件
.antMatchers("/", “/login”).permitAll()//允许访问登录页
.and()
.formLogin()
.loginPage("/login")//自定义登录页
.failureUrl("/login?error")//指定登录失败页
.defaultSuccessUrl("/driver/system.html") //登录成功跳转页
.usernameParameter(“name”)//页面上使用的是 th:field 则需要写这个,否则不需要
.passwordParameter(“passWd”)
.and()
.headers().frameOptions().disable()//in a frame because it set ‘X-Frame-Options’ to ‘deny’.有这个问题则写
.and()
.logout().logoutSuccessUrl("/").permitAll(); //退出登录跳转页
http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
}
}
四 service
CustomUserDetailService.java
@Service
public class CustomUserDetailService implements UserDetailsService {
private final static Logger logger = LogManager.getLogger(CustomUserDetailService.class);
@Autowired
private UserRepository userRepository;
@Autowired
private PermissionDao permissionDao;
/**
* 根据用户名来取得用户信息,判断用户存不存在,同时取得该用户的权限
* 这里不判断密码是否正确
* @param name
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
User user = userRepository.findByUserName(name);
/**
* 权限
*/
if (null!=user){
List<Permission> permissions = permissionDao.findByAdminUserId(user.getId());
List<GrantedAuthority> grantedAuthorities = new ArrayList <>();
for (Permission permission : permissions) {
if (permission != null && permission.getName()!=null) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());
//1:此处将权限信息添加到 GrantedAuthority 对象中,在后面进行全权限验证时会使用GrantedAuthority 对象。
grantedAuthorities.add(grantedAuthority);
}
}
logger.log(Level.INFO,"name="+user.getUserName()+"\t "+"权限="+grantedAuthorities);
return new org.springframework.security.core.userdetails.User(
user.getUserName(),
user.getPassword(),
grantedAuthorities);
}else {
throw new UsernameNotFoundException("admin: " + name + " do not exist!");
}
/**
* 不管权限
*/
/*if (user==null){
logger.error("Not Found name "+ name);
throw new UsernameNotFoundException("Not Found name "+ name);
}
return new org.springframework.security.core.userdetails.User(
user.getUserName(),
user.getPassword(),
grantedAuthorities);*/
}
private static List<GrantedAuthority> getAuthorities (List<Role> roles) {
List<GrantedAuthority> authorities = new ArrayList<>();
for (Role role:roles){
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
}
MyAccessDecisionManager.java
/**
@author: 易明星
@Modified By:
@Date: Create in 11:17 2019/6/25
@Description:
*/
@Service
public class MyAccessDecisionManager implements AccessDecisionManager {/**
- decide 方法是判定是否拥有权限的决策方法,
- object 包含客户端发起的请求的requset信息,可转换为
HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
- authentication 是 CustomUserService 中循环添加到 GrantedAuthority 对象中的权限信息集合.
- configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,
- 此方法是为了判定用户请求的url是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。
- @param authentication
- @param object
- @param configAttributes
- @throws AccessDeniedException
- @throws InsufficientAuthenticationException
*/
@Override
public void decide(Authentication authentication, Object object, Collection configAttributes)
throws AccessDeniedException, InsufficientAuthenticationException {
if(null== configAttributes || configAttributes.size() <=0) {
return;
}
ConfigAttribute c;
String needRole;
for(Iterator iter = configAttributes.iterator(); iter.hasNext(); ) {
c = iter.next();
needRole = c.getAttribute();
for(GrantedAuthority ga : authentication.getAuthorities()) {//authentication CustomUserDetailService中循环添加到 GrantedAuthority 对象中的权限信息集合
if(needRole.trim().equals(ga.getAuthority())) {
return;
}
}
}
throw new AccessDeniedException(“no right”);
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}@Override
public boolean supports(Class<?> clazz) {
return true;
}
}
MyInvocationSecurityMetadataSourceService.java
/**@author: 易明星
@Modified By:
@Date: Create in 11:22 2019/6/25
@Description:
*/
@Service
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {
private final static Logger logger = LogManager.getLogger(CustomUserDetailService.class);@Autowired
private PermissionDao permissionDao;private Map<String, Collection> map =null;
/**
- 加载权限表中所有权限
*/
public void loadResourceDefine(){
map = new LinkedHashMap<>();
Collection array;
ConfigAttribute cfg;
List permissions = permissionDao.findAll();
for(Permission permission : permissions) {
array = new ArrayList<>();
cfg = new SecurityConfig(permission.getName());
//此处只添加了用户的名字,其实还可以添加更多权限的信息,例如请求方法到ConfigAttribute的集合中去。
// 此处添加的信息将会作为MyAccessDecisionManager类的decide的第三个参数。
array.add(cfg);
//用权限的getUrl() 作为map的key,用ConfigAttribute的集合作为 value,
map.put(permission.getUrl(), array);
}
}
/**
- 此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。
*/
@Override
public Collection getAttributes(Object object) throws IllegalArgumentException {
if(map ==null) loadResourceDefine();
//object 中包含用户请求的request 信息
// 想办法把map反过来
HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
AntPathRequestMatcher matcher;
String resUrl;
for(Iterator iter = map.keySet().iterator(); iter.hasNext(); ) {
resUrl = iter.next();
matcher = new AntPathRequestMatcher(resUrl);
if(matcher.matches(request)) {
return map.get(resUrl);
}
}
return null;
}
@Override
public Collection getAllConfigAttributes() {
return null;
}@Override
public boolean supports(Class<?> clazz) {
return true;
}- 加载权限表中所有权限
五 自定义security 过滤器 拦截 url请求
MyFilterSecurityInterceptor.java
/**
@author: 易明星
@Modified By:
@Date: Create in 11:20 2019/6/25
@Description: 自定义security的过滤器
*/
@Service
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {@Autowired
private FilterInvocationSecurityMetadataSource securityMetadataSource;@Autowired
public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {
super.setAccessDecisionManager(myAccessDecisionManager);
}@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}public void invoke(FilterInvocation fi) throws IOException, ServletException {
//fi里面有一个被拦截的url
//里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
//再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
//执行下一个拦截器
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}@Override
public void destroy() {}
@Override
public Class<?> getSecureObjectClass() {
return FilterInvocation.class;
一 建表
权限管理需实现5张表:用户表、角色表、用户角色对应表、权限表、权限角色对应表
用户表
CREATE TABLE platform_user
(
id
bigint(20) NOT NULL AUTO_INCREMENT,
username
varchar(50) NOT NULL,
password
varchar(100) NOT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
角色表
CREATE TABLE platform_role
(
id
int(11) NOT NULL AUTO_INCREMENT,
name
varchar(50) NOT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT=‘这只是角色表’;
用户角色对应表
CREATE TABLE platform_role_user
(
id
int(11) NOT NULL AUTO_INCREMENT,
user_id
bigint(20) NOT NULL,
role_id
int(11) NOT NULL,
PRIMARY KEY (id
),
KEY FKt6466kf26ep5v3rfcya2sxi53
(role_id
),
KEY FKfwy3bmkplk822fdp5o1btjyyv
(user_id
),
CONSTRAINT FKfwy3bmkplk822fdp5o1btjyyv
FOREIGN KEY (user_id
) REFERENCES platform_user
(id
),
CONSTRAINT FKt6466kf26ep5v3rfcya2sxi53
FOREIGN KEY (role_id
) REFERENCES platform_role
(id
)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
权限表
CREATE TABLE platform_sys_permission
(
id
int(11) NOT NULL AUTO_INCREMENT,
name
varchar(50) NOT NULL,
description
varchar(50) NOT NULL,
url
varchar(100) NOT NULL,
pid
int(11) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT=‘权限表’;
注意:如果存在子权限,一定要把最大的权限放在最后,否则在下面权限判定时,会出问题。
5. 权限角色对应表
CREATE TABLE platform_permission_role
(
id
int(11) NOT NULL AUTO_INCREMENT,
role_id
int(11) NOT NULL,
permission_id
int(11) NOT NULL,
PRIMARY KEY (id
),
KEY role_id
(role_id
)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COMMENT=‘角色权限管理表’;
二 实体类
User.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = “username”,nullable = false,length = 50)
private String userName;
@Column(name = “password”,nullable = false,length = 100)
private String password;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = “platform_role_user”, joinColumns = @JoinColumn(name = “user_id”, referencedColumnName = “id”), inverseJoinColumns = @JoinColumn(name = “role_id”, referencedColumnName = “id”))
private List roles;
省略 get set
Role.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
- 权限名
*/
@Column(name = “name”, nullable = false,length = 50)
private String name;
RoleUser.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "user_id")
private Long userId;
@Column(name = "role_id")
private Integer roleId;
Permission.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* 权限名
*/
@Column(name = "name",nullable = false)
private String name;
/**
* 权限描述
*/
@Column(name = "description", nullable = false)
private String description;
/**
* 权限的url
*/
@Column(name = "url", nullable = false)
private String url;
/**
* 父节点id
*/
@Column(name = "pid")
private Integer pid;
PermissionRole.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "role_id")
private Integer roleId;
@Column(name = "permission_id")
private Integer permissionId;
三 security 配置类
/**
@author: 易明星
@Modified By:
@Date: Create in 13:27 2019/6/24
@Description: 权限配置
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowired
private MyFilterSecurityInterceptor myFilterSecurityInterceptor;@Autowired
private CustomUserDetailService userDetailService;/**
- 密码加密的方式
- @return
*/
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
- 加密密码
- @param auth
- @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder());
}
/**
- security 具体的配置
- @param http
- @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() //csrf不可用
.authorizeRequests()
.antMatchers("/static/", "/css/", “/js/", "/images/”, “/lib/**”).permitAll() //访问允许静态文件
.antMatchers("/", “/login”).permitAll()//允许访问登录页
.and()
.formLogin()
.loginPage("/login")//自定义登录页
.failureUrl("/login?error")//指定登录失败页
.defaultSuccessUrl("/driver/system.html") //登录成功跳转页
.usernameParameter(“name”)//页面上使用的是 th:field 则需要写这个,否则不需要
.passwordParameter(“passWd”)
.and()
.headers().frameOptions().disable()//in a frame because it set ‘X-Frame-Options’ to ‘deny’.有这个问题则写
.and()
.logout().logoutSuccessUrl("/").permitAll(); //退出登录跳转页
http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
}
}
四 service
CustomUserDetailService.java
@Service
public class CustomUserDetailService implements UserDetailsService {
private final static Logger logger = LogManager.getLogger(CustomUserDetailService.class);
@Autowired
private UserRepository userRepository;
@Autowired
private PermissionDao permissionDao;
/**
* 根据用户名来取得用户信息,判断用户存不存在,同时取得该用户的权限
* 这里不判断密码是否正确
* @param name
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
User user = userRepository.findByUserName(name);
/**
* 权限
*/
if (null!=user){
List<Permission> permissions = permissionDao.findByAdminUserId(user.getId());
List<GrantedAuthority> grantedAuthorities = new ArrayList <>();
for (Permission permission : permissions) {
if (permission != null && permission.getName()!=null) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());
//1:此处将权限信息添加到 GrantedAuthority 对象中,在后面进行全权限验证时会使用GrantedAuthority 对象。
grantedAuthorities.add(grantedAuthority);
}
}
logger.log(Level.INFO,"name="+user.getUserName()+"\t "+"权限="+grantedAuthorities);
return new org.springframework.security.core.userdetails.User(
user.getUserName(),
user.getPassword(),
grantedAuthorities);
}else {
throw new UsernameNotFoundException("admin: " + name + " do not exist!");
}
/**
* 不管权限
*/
/*if (user==null){
logger.error("Not Found name "+ name);
throw new UsernameNotFoundException("Not Found name "+ name);
}
return new org.springframework.security.core.userdetails.User(
user.getUserName(),
user.getPassword(),
grantedAuthorities);*/
}
private static List<GrantedAuthority> getAuthorities (List<Role> roles) {
List<GrantedAuthority> authorities = new ArrayList<>();
for (Role role:roles){
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
}
MyAccessDecisionManager.java
/**
@author: 易明星
@Modified By:
@Date: Create in 11:17 2019/6/25
@Description:
*/
@Service
public class MyAccessDecisionManager implements AccessDecisionManager {/**
- decide 方法是判定是否拥有权限的决策方法,
- object 包含客户端发起的请求的requset信息,可转换为
HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
- authentication 是 CustomUserService 中循环添加到 GrantedAuthority 对象中的权限信息集合.
- configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,
- 此方法是为了判定用户请求的url是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。
- @param authentication
- @param object
- @param configAttributes
- @throws AccessDeniedException
- @throws InsufficientAuthenticationException
*/
@Override
public void decide(Authentication authentication, Object object, Collection configAttributes)
throws AccessDeniedException, InsufficientAuthenticationException {
if(null== configAttributes || configAttributes.size() <=0) {
return;
}
ConfigAttribute c;
String needRole;
for(Iterator iter = configAttributes.iterator(); iter.hasNext(); ) {
c = iter.next();
needRole = c.getAttribute();
for(GrantedAuthority ga : authentication.getAuthorities()) {//authentication CustomUserDetailService中循环添加到 GrantedAuthority 对象中的权限信息集合
if(needRole.trim().equals(ga.getAuthority())) {
return;
}
}
}
throw new AccessDeniedException(“no right”);
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}@Override
public boolean supports(Class<?> clazz) {
return true;
}
}
MyInvocationSecurityMetadataSourceService.java
/**@author: 易明星
@Modified By:
@Date: Create in 11:22 2019/6/25
@Description:
*/
@Service
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {
private final static Logger logger = LogManager.getLogger(CustomUserDetailService.class);@Autowired
private PermissionDao permissionDao;private Map<String, Collection> map =null;
/**
- 加载权限表中所有权限
*/
public void loadResourceDefine(){
map = new LinkedHashMap<>();
Collection array;
ConfigAttribute cfg;
List permissions = permissionDao.findAll();
for(Permission permission : permissions) {
array = new ArrayList<>();
cfg = new SecurityConfig(permission.getName());
//此处只添加了用户的名字,其实还可以添加更多权限的信息,例如请求方法到ConfigAttribute的集合中去。
// 此处添加的信息将会作为MyAccessDecisionManager类的decide的第三个参数。
array.add(cfg);
//用权限的getUrl() 作为map的key,用ConfigAttribute的集合作为 value,
map.put(permission.getUrl(), array);
}
}
/**
- 此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。
*/
@Override
public Collection getAttributes(Object object) throws IllegalArgumentException {
if(map ==null) loadResourceDefine();
//object 中包含用户请求的request 信息
// 想办法把map反过来
HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
AntPathRequestMatcher matcher;
String resUrl;
for(Iterator iter = map.keySet().iterator(); iter.hasNext(); ) {
resUrl = iter.next();
matcher = new AntPathRequestMatcher(resUrl);
if(matcher.matches(request)) {
return map.get(resUrl);
}
}
return null;
}
@Override
public Collection getAllConfigAttributes() {
return null;
}@Override
public boolean supports(Class<?> clazz) {
return true;
}- 加载权限表中所有权限
五 自定义security 过滤器 拦截 url请求
MyFilterSecurityInterceptor.java
/**
@author: 易明星
@Modified By:
@Date: Create in 11:20 2019/6/25
@Description: 自定义security的过滤器
*/
@Service
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {@Autowired
private FilterInvocationSecurityMetadataSource securityMetadataSource;@Autowired
public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {
super.setAccessDecisionManager(myAccessDecisionManager);
}@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}public void invoke(FilterInvocation fi) throws IOException, ServletException {
//fi里面有一个被拦截的url
//里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
//再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
//执行下一个拦截器
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}@Override
public void destroy() {}
@Override
public Class<?> getSecureObjectClass() {
return FilterInvocation.class;
}@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
}}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
}