拦截URL的时候使用自定义权限判断
1:配置文件指定自定义投票器
<!-- 页面拦截规则 -->
<http use-expressions="false" access-decision-manager-ref="accessDecisionManager">
<!-- 下述页面拥有ROLE_USER角色 -->
<intercept-url pattern="/index.jsp" access="ROLE_USER" />
<intercept-url pattern="/frame/index.do" access="ROLE_USER" />
<intercept-url pattern="/frame/loadMenu.do" access="ROLE_USER" />
<intercept-url pattern="/system/welcome.do" access="ROLE_USER" />
<intercept-url pattern="/**" access="URL_PERMISSION" />
<form-login login-page="/login/login.jsp"
authentication-failure-url="/login/login.jsp?error=true"
login-processing-url="/login.do"
default-target-url="/index.jsp"
authentication-details-source-ref="authenticationDetailsSource"
/>
<logout logout-url="/logout.do" logout-success-url="/login/login.jsp"/>
<csrf disabled="true"/>
<headers>
<frame-options policy="SAMEORIGIN"/>
</headers>
</http>
<!-- 使用自定义投票器 -->
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
<beans:constructor-arg name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter" />
<beans:bean class="common.spring.security.GlobalAccessDecisionVoter" />
<beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
2:自定义投票器实现类
import java.util.Collection;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import cfca.org.slf4j.Logger;
import cfca.org.slf4j.LoggerFactory;
public class GlobalAccessDecisionVoter implements AccessDecisionVoter<Object> {
private static Logger logger = LoggerFactory.getLogger(GlobalAccessDecisionVoter.class);
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
@Override
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
FilterInvocation fi = (FilterInvocation) object;
String url = fi.getRequestUrl();
logger.info("interceptor url:" + url);
if (authentication == null) {
return ACCESS_DENIED;
}
int result = ACCESS_ABSTAIN;
Collection<? extends GrantedAuthority> authorities = extractAuthorities(authentication);
for (ConfigAttribute attribute : attributes) {
if (attribute.getAttribute() == null) {
continue;
}
if (this.supports(attribute)) {
result = ACCESS_DENIED;
// Attempt to find a matching granted authority
for (GrantedAuthority authority : authorities) {
if (authority instanceof GlobalGrantedAuthority) {
GlobalGrantedAuthority globalGrantedAuthority = (GlobalGrantedAuthority) authority;
GlobalPermission permission = globalGrantedAuthority.getPermission();
if (permission != null && url.trim().equals("/"+permission.getUrl())) {
return ACCESS_GRANTED;
}
} else if (attribute.getAttribute().equals(authority.getAuthority())) {
return ACCESS_GRANTED;
}
}
}
}
return result;
}
Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) {
return authentication.getAuthorities();
}
}
说明
1:我目前登录用户都赋予了USER_ROLE角色,因此只要用户登录,具有USER_ROLE角色的URL都会请求通过。
2:其他的URL都拥有URL_PERMISSION角色,登录用户不具备此角色,因此只能判断用户的自定义权限是否可以匹配到。