问题描述:FilterInvocationSecurityMetadataSource 下的 getAttributes(Object o)方法执行完后不走AccessDecisionManager的实现类
解决办法: getAttributes 方法返回一个 无权限,而不是返回null
Collection<ConfigAttribute> collection = new LinkedList<>();
if(collection.size() < 1){
ConfigAttribute configAttribute = new SecurityConfig("ROLE_NO_USER");
collection.add(configAttribute);
}
return collection;
附完整动态权限代码如下:
@Component
public class UrlFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
@Resource
private AuthorityMapper authorityMapper;
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
@Override
public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
String requestUrl = ((FilterInvocation) o).getRequestUrl();
List<Authority> allMenu = authorityMapper.getAllMenu();
for (Authority mwMenu : allMenu) {
if (antPathMatcher.match(mwMenu.getAuthoritySysUrl(), requestUrl) && mwMenu.getRoles().size() > 0) {
ArrayList<String> strings = new ArrayList<>();
mwMenu.getRoles().forEach(
oo -> strings.add(oo.getRoleCode())
);
List<String> collect = strings.stream().distinct().collect(Collectors.toList());
if (collect.size() == 0){
return null;
}else {
return SecurityConfig.createList(collect.toArray(new String[collect.size()]));
}
}
}
Collection<ConfigAttribute> collection = new LinkedList<>();
if(collection.size() < 1){
ConfigAttribute configAttribute = new SecurityConfig("ROLE_NO_USER");
collection.add(configAttribute);
}
return collection;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
@Override
public boolean supports(Class<?> aClass) {
return FilterInvocation.class.isAssignableFrom(aClass);
}
}
@Component
public class UrlAccessDecisionManager implements AccessDecisionManager {
@Override
public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, AuthenticationException {
for (ConfigAttribute ca : collection) {
String needRole = ca.getAttribute();
if (authentication instanceof AnonymousAuthenticationToken) {
throw new BadCredentialsException("未登录");
}
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
for (GrantedAuthority authority : authorities) {
if (authority.getAuthority().equals(needRole)) {
return;
}
}
}
throw new AccessDeniedException("权限不足!");
}
@Override
public boolean supports(ConfigAttribute configAttribute) {
return true;
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
}
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
UserLoginServiceImpl userLoginService;
@Resource
UrlFilterInvocationSecurityMetadataSource urlFilterInvocationSecurityMetadataSource;
@Resource
UrlAccessDecisionManager urlAccessDecisionManager;
@Resource
AuthenticationAccessDeniedHandler authenticationAccessDeniedHandler;
@Resource
private RedisUtils redisUtils;
private String[] SWAGGER_WHITELIST = {
"/refreshRedisDict",
"/getDictList",
"/getDictByCode",
"/userLogout",
"/userLogin",
"/getAllMenu",
"/oss/uploadFile",
"/judge/**"
};
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userLoginService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(SWAGGER_WHITELIST);;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests()
.withObjectPostProcessor(
new ObjectPostProcessor<FilterSecurityInterceptor>() {
@Override
public <O extends FilterSecurityInterceptor> O postProcess(O o) {
o.setSecurityMetadataSource(urlFilterInvocationSecurityMetadataSource);
o.setAccessDecisionManager(urlAccessDecisionManager);
return o;
}
})
.and().formLogin().loginPage("/login/warning").usernameParameter("username").passwordParameter("password").permitAll()
.and().addFilter(new JWTAuthenticationFilter(authenticationManager(),userLoginService,redisUtils))
.logout().permitAll()
.and().cors()
.and().csrf().disable().exceptionHandling().accessDeniedHandler(authenticationAccessDeniedHandler);
}
}
|