一般控制权限有2种业务情况:
前台系统
特点:给用户使用的系统,一般只区分用户登录和未登录状态下能访问的接口。或者区分vip用户和普通用户的简单情况,关于权限的规则是长期稳定的,不会经常改变。
1、区分登录和未登录的情况
在之前已经写过了。
.authorizeRequests()//请求授权
.antMatchers("/authentication/requrie",
securityProperties.getBrowser().getLoginPage(),
"/code/*",securityProperties.getBrowser().getSiginUpUrl(),
"/user/regist","/session/invalid","/index.html",
"/fuiou-logOut.html","/signOut")
.permitAll()//该url不需要身份认证
.anyRequest() //任何请求
.authenticated()//身份认证
2、区分简单的角色
.authorizeRequests()//请求授权
.antMatchers("/authentication/requrie",
securityProperties.getBrowser().getLoginPage(),
"/code/*",securityProperties.getBrowser().getSiginUpUrl(),
"/user/regist","/session/invalid","/index.html",
"/fuiou-logOut.html","/signOut")
.permitAll()//该url不需要身份认证
.antMatchers(HttpMethod.GET, "/user/*").hasRole("ADMIN")
.anyRequest() //任何请求
.authenticated()//身份认证
.antMatchers(HttpMethod.GET, "/user/").hasRole("ADMIN")这行代码就表示/user/匹配到的get请求,只有ADMIN的角色才能访问
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
String password=passwordEncoder.encode("12345");
return new User(username, password,true,true,true,true,AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN,ROLE_USER"));
}
所以loadUserByUsername创建UserDetails的时候要给相应的角色并且要有ROLE_前缀
Spring Security权限表达式
Spring Security权限表达式.png多个权限表达式联合使用
比如角色必须是admin而且ip地址必须是127.0.0.1才能访问
.antMatchers(HttpMethod.GET, "/user/*").access("hasRole('admin') and hasIpAddress('127.0.0.1')")
自定义规则,并且用权限表达式来表示
http.authorizeRequests().anyRequest().access("@类在容器中的名称.方法名(参数)");
将配置的url剥离出去
.authorizeRequests()//请求授权
.antMatchers("/authentication/requrie",
securityProperties.getBrowser().getLoginPage(),
"/code/*",securityProperties.getBrowser().getSiginUpUrl(),
"/user/regist","/session/invalid","/index.html",
"/fuiou-logOut.html","/signOut")
.permitAll()//该url不需要身份认证
.antMatchers(HttpMethod.GET, "/user/*").hasRole("ADMIN")
.anyRequest() //任何请求
.authenticated()//身份认证
现在是直接在安全框架内限制了那些url需要认证,那些url不需要认证。但是这些其实都是引用安全框架的那个项目才能知道的。
实现思路.pngcore项目
public interface AuthorizeConfigProvider {
public void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config);
}
@Component
public class FuiouAuthorizeConfigProvider implements AuthorizeConfigProvider {
@Autowired
private SecurityProperties securityProperties;
@Override
public void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
config.antMatchers("/authentication/requrie",
securityProperties.getBrowser().getLoginPage(),
"/code/*",securityProperties.getBrowser().getSiginUpUrl())
.permitAll();
}
}
public interface AuthorizeConfigManager {
public void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config);
}
@Component
public class FuiouAuthorizeConfigManager implements AuthorizeConfigManager {
@Autowired
private Set<AuthorizeConfigProvider> authorizeConfigProviders;
@Override
public void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
for (AuthorizeConfigProvider authorizeConfigProvider : authorizeConfigProviders) {
authorizeConfigProvider.config(config);
}
config.anyRequest().authenticated();
}
}
browser项目
@Autowired
private AuthorizeConfigManager configManager;
configManager.config(http.authorizeRequests());
总结:通过实现AuthorizeConfigProvider类,重写config方法来配置url的权限。并注入到spring容器中。
AuthorizeConfigManager 会把spring容器中所有的AuthorizeConfigProvider类拿到并调用config方法。
这样引入安全框架的项目只需要实现AuthorizeConfigProvider类,重写config方法来配置url的权限。并注入到spring容器中。来配置它独有的权限了。
管理系统
特点:角色众多,权限复杂,权限规则会不断变化。
通用RBAC数据模型
RBAC数据模型.png
网友评论