前端业务系统的权限简单些,一般只区分是否登录,复杂点的还会区分 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; } }
配置,注意,授权的配置要配置在免登录就能访问的服务器的最后