谨记:Url表只储存受保护的资源,不在表里的资源说明不受保护,任何人都可以访问
1、MyFilterInvocationSecurityMetadataSource 类判断该访问路径是否被保护
@Component//用于设置受保护资源的权限信息的数据源publicclassMyFilterInvocationSecurityMetadataSourceimplementsFilterInvocationSecurityMetadataSource{@Beanpublic AntPathMatchergetAntPathMatcher(){returnnewAntPathMatcher();}@Autowired//获取数据库中的保存的url Url表只储存受保护的资源,不在表里的资源说明不受保护,任何人都可以访问private RightsMapper rightsMapper;@Autowiredprivate AntPathMatcher antPathMatcher;@Override/*
* @param 被调用的保护资源
* @return 返回能够访问该保护资源的角色集合,如果没有,则应返回空集合。
*/public Collection<ConfigAttribute>getAttributes(Object object)throws IllegalArgumentException{
FilterInvocation fi=(FilterInvocation) object;//获取用户请求的Url
String url= fi.getRequestUrl();//先到数据库获取受权限控制的Url
List<Rights> us= rightsMapper.queryAll();//用于储存用户请求的Url能够访问的角色
Collection<ConfigAttribute> rs=newArrayList<ConfigAttribute>();for(Rights u:us){if(u.getUrl()!= null){//逐一判断用户请求的Url是否和数据库中受权限控制的Url有匹配的if(antPathMatcher.match(u.getUrl(), url)){//如果有则将可以访问该Url的角色储存到Collection<ConfigAttribute>
rs.add(rightsMapper.queryById(u.getId()));}}}if(rs.size()>0){return rs;}//没有匹配到,就说明此资源没有被控制,所有人都可以访问,返回null即可,返回null则不会进入之后的decide方法return null;}@Overridepublic Collection<ConfigAttribute>getAllConfigAttributes(){// TODO 自动生成的方法存根return null;}@Overridepublicbooleansupports(Class<?> clazz){// TODO 自动生成的方法存根return FilterInvocation.class.isAssignableFrom(clazz);}}
rights表中的部分内容:
表结构内容:
2、MyAccessDecisionManager 类判断该用户是否有权限访问
@Component//用于设置判断当前用户是否可以访问被保护资源的逻辑publicclassMyAccessDecisionManagerimplementsAccessDecisionManager{@Override/*
* @param 请求该保护资源的用户对象
* @param 被调用的保护资源
* @param 有权限调用该资源的集合
*/publicvoiddecide(Authentication authentication, Object object,
Collection<ConfigAttribute> configAttributes)throws AccessDeniedException, InsufficientAuthenticationException{
Iterator<ConfigAttribute> ite= configAttributes.iterator();//遍历configAttributes,查看当前用户是否有对应的权限访问该保护资源while(ite.hasNext()){
ConfigAttribute ca= ite.next();
String needRole= ca.getAttribute();for(GrantedAuthority ga: authentication.getAuthorities()){if(ga.getAuthority().equals(needRole)){// 匹配到有对应角色,则允许通过return;}}}// 该url有配置权限,但是当前登录用户没有匹配到对应权限,则禁止访问thrownewAccessDeniedException("not allow");}@Overridepublicbooleansupports(ConfigAttribute attribute){returntrue;}@Overridepublicbooleansupports(Class<?> clazz){returntrue;}}
3、在SecurityConfig 类中配置说明
@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled=true)publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{@Autowired
MyUserDetailsService myUserDetailsService;@Autowiredprivate SendSmsSecurityConfig sendSmsSecurityConfig;@Autowiredprivate MyAccessDecisionManager myAccessDecisionManager;@Autowiredprivate MyFilterInvocationSecurityMetadataSource myFilterInvocationSecurityMetadataSource;//加密机制@Beanpublic PasswordEncoderpasswordEncoder(){return NoOpPasswordEncoder.getInstance();// 不加密}//认证@Overrideprotectedvoidconfigure(AuthenticationManagerBuilder auth)throws Exception{
auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder());}@Overrideprotectedvoidconfigure(HttpSecurity http)throws Exception{
http.authorizeRequests()//对请求授权.antMatchers("/**").permitAll().anyRequest()//任何请求.authenticated()//登录后访问.withObjectPostProcessor(newObjectPostProcessor<FilterSecurityInterceptor>(){@Overridepublic<OextendsFilterSecurityInterceptor> OpostProcess(
O fsi){
fsi.setSecurityMetadataSource(myFilterInvocationSecurityMetadataSource);
fsi.setAccessDecisionManager(myAccessDecisionManager);return fsi;}}).and().csrf().disable();}}
配置如下代码:至此完成所有配置!!!