安全分为 认证和授权,前边讲的都是认证,现在说授权。
前端业务系统的权限简单些,一般只区分是否登录,复杂点的还会区分 VIP用户等简单的角色,权限规则基本不变。
后台系统比较复杂,角色众多,权限随着业务不断变化。
1,用代码控制简单的权限
直接在配置类 BrowserSecurityConfig extends WebSecurityConfigurerAdapter 的configure方法里
http //--------------授权相关的配置 ---------------------
.authorizeRequests()
// /authentication/require:处理登录,securityProperties.getBrowser().getLoginPage():用户配置的登录页
.antMatchers(SecurityConstants.DEFAULT_UNAUTHENTICATION_URL,
securityProperties.getBrowser().getLoginPage(),//放过登录页不过滤,否则报错
SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_MOBILE,
SecurityConstants.SESSION_INVALID_PAGE,
SecurityConstants.DEFAULT_VALIDATE_CODE_URL_PREFIX+"/*")//验证码
.permitAll() //-------上边的不用授权也允许访问------
//~=========简单的权限控制,只区分是否登录的情况可以配置在这里=======
// /user 的post请求需要ADMIN权限
.antMatchers("/user/*").hasRole("ADMIN")
.anyRequest() //任何请求
.authenticated() //都需要身份认证
一行红色部分配置就可以了,意思是 /user/* 的所有请求需要有ADMIN 权限,如果是Rest风格的服务,只需要配置成 antMatchers(HttpMethod.POST,"/user/*").hasRole("ADMIN") 格式即可。
这个权限在UserDetailsService 的loadUserByUsername方法返回的user的权限集合里定义。格式是ROLE_ADMIN( ROLE_权限名称,ADMIN和匹配器里一致)(这个格式具体在ExpressionUrlAuthorizationConfigurer里)
private SocialUserDetails buildUser(String userId) {
String password = passwordEncoder.encode("123456");
System.err.println("加密后密码: "+password);
//参数:用户名|密码|是否启用|账户是否过期|密码是否过期|账户是否锁定|权限集合
return new SocialUser(userId,password,true,true,true,true,
//工具类 将字符串转换为权限集合,ROLE_角色 是spring要求的权限格式
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN"));
}
再说一个过滤器,AnonymousAuthenticationFilter,这个过滤器就是判断前边的过滤器是否认证成功,如果没有认证成功,就创建一个默认的用户创建一个Authentication 做登录。具体代码看其源码。
SpringSecurity 授权相关类
==============================================================================================================================
控制复杂权限:基于rbac
自定义查询权限的类根据用户名查询用户的权限
package com.imooc.security.rbac; import java.util.HashSet;
import java.util.Set; import javax.servlet.http.HttpServletRequest; import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher; @Component("rbacService")
public class RbacServiceImpl implements RbacService { private AntPathMatcher antPathMatcher = new AntPathMatcher(); @Override
public boolean hasPermission(HttpServletRequest request, Authentication authentication) { Object principal = authentication.getPrincipal(); boolean hasPermission = false; if(principal instanceof UserDetails){ String username = ((UserDetails)principal).getUsername(); //读取用户所有权限的url,需要查询数据库
Set<String> urls = new HashSet<>();
urls.add("/user/*"); for(String url : urls){
if(antPathMatcher.match(url, request.getRequestURI())){
hasPermission = true ;
break ;
}
}
}
return hasPermission;
} }
配置,注意,授权的配置要配置在免登录就能访问的服务器的最后