发布时间:2022-12-29 11:00
............
class="org.springframework.security.providers.ProviderManager">
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
value="classpath:org/springframework/security/messages_zh_CN" />
class="org.springframework.security.vote.AffirmativeBased">
value="false" />
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
ref="secureResourceFilterInvocationDefinitionSource" />
class="com.javaeye.sample.security.interceptor.SecureResourceFilterInvocationDefinitionSource" />
....
if ((grant == deny) && (grant != 0)) {
if (this.allowIfEqualGrantedDeniedDecisions) {
return;
} else {
throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied",
"Access is denied"));
}
}
.....
public ConfigAttributeDefinition getAttributes(Object filter) throws IllegalArgumentException {
FilterInvocation filterInvocation = (FilterInvocation) filter;
String requestURI = filterInvocation.getRequestUrl();
Map urlAuthorities = this.getUrlAuthorities(filterInvocation);
String grantedAuthorities = null;
for(Iterator> iter = urlAuthorities.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = iter.next();
//url表示从资源表取出的值,在这里代表的是相应的URL
String url = entry.getKey();
//这段代码表示数据库内的需要验证的资源URL与当前请求的URL相匹配时进行验证
if(urlMatcher.pathMatchesUrl(url, requestURI)) {
//grantedAuthorities表示每个资源对应的角色,如果有多个角色,则以','隔开
grantedAuthorities = entry.getValue();
break;
}
}
if(grantedAuthorities != null) {
ConfigAttributeEditor configAttrEditor = new ConfigAttributeEditor();
configAttrEditor.setAsText(grantedAuthorities);
return (ConfigAttributeDefinition) configAttrEditor.getValue();
}
return null;
}
....
public void invoke(FilterInvocation fi) throws IOException, ServletException {
if ((fi.getRequest() != null) && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
&& observeOncePerRequest) {
// filter already applied to this request and user wants us to observce
// once-per-request handling, so don't re-do security checking
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} else {
// first time this request being called, so perform security checking
if (fi.getRequest() != null) {
fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);
}
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}
}
/***
Indicates whether once-per-request handling will be observed. By default this is true
,meaning the FilterSecurityInterceptor
will only execute once-per-request. Sometimes users may wishit to execute more than once per request, such as when JSP forwards are being used and filter security is desired on each included fragment of the HTTP request.
*/
protected InterceptorStatusToken beforeInvocation(Object object) {
Assert.notNull(object, "Object was null");
if (!getSecureObjectClass().isAssignableFrom(object.getClass())) {
throw new IllegalArgumentException("Security invocation attempted for object "
+ object.getClass().getName()
+ " but AbstractSecurityInterceptor only configured to support secure objects of type: "
+ getSecureObjectClass());
}
ConfigAttributeDefinition attr = this.obtainObjectDefinitionSource().getAttributes(object);
if (attr == null) {
if (rejectPublicInvocations) {
throw new IllegalArgumentException(
"No public invocations are allowed via this AbstractSecurityInterceptor. "
+ "This indicates a configuration error because the "
+ "AbstractSecurityInterceptor.rejectPublicInvocations property is set to 'true'");
}
if (logger.isDebugEnabled()) {
logger.debug("Public object - authentication not attempted");
}
publishEvent(new PublicInvocationEvent(object));
return null; // no further work post-invocation
}
if (logger.isDebugEnabled()) {
logger.debug("Secure object: " + object + "; ConfigAttributes: " + attr);
}
if (SecurityContextHolder.getContext().getAuthentication() == null) {
credentialsNotFound(messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound",
"An Authentication object was not found in the SecurityContext"), object, attr);
}
Authentication authenticated = authenticateIfRequired();
// Attempt authorization
try {
this.accessDecisionManager.decide(authenticated, object, attr);
}
catch (AccessDeniedException accessDeniedException) {
AuthorizationFailureEvent event = new AuthorizationFailureEvent(object, attr, authenticated,
accessDeniedException);
publishEvent(event);
throw accessDeniedException;
}
if (logger.isDebugEnabled()) {
logger.debug("Authorization successful");
}
AuthorizedEvent event = new AuthorizedEvent(object, attr, authenticated);
publishEvent(event);
// Attempt to run as a different user
Authentication runAs = this.runAsManager.buildRunAs(authenticated, object, attr);
if (runAs == null) {
if (logger.isDebugEnabled()) {
logger.debug("RunAsManager did not change Authentication object");
}
// no further work post-invocation
return new InterceptorStatusToken(authenticated, false, attr, object);
} else {
if (logger.isDebugEnabled()) {
logger.debug("Switching to RunAs Authentication: " + runAs);
}
SecurityContextHolder.getContext().setAuthentication(runAs);
// revert to token.Authenticated post-invocation
return new InterceptorStatusToken(authenticated, true, attr, object);
}
}
/**
* Checks the current authentication token and passes it to the AuthenticationManager if
* {@link org.springframework.security.Authentication#isAuthenticated()} returns false or the property
* alwaysReauthenticate has been set to true.
*
* @return an authenticated Authentication object.
*/
private Authentication authenticateIfRequired() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication.isAuthenticated() && !alwaysReauthenticate) {
if (logger.isDebugEnabled()) {
logger.debug("Previously Authenticated: " + authentication);
}
return authentication;
}
ConfigAttributeDefinition attr = this.obtainObjectDefinitionSource().getAttributes(object);
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
(User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
this.accessDecisionManager.decide(authenticated, object, attr);
public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config)
throws AccessDeniedException {
Iterator iter = this.getDecisionVoters().iterator();
int deny = 0;
while (iter.hasNext()) {
AccessDecisionVoter voter = (AccessDecisionVoter) iter.next();
int result = voter.vote(authentication, object, config);
switch (result) {
case AccessDecisionVoter.ACCESS_GRANTED:
return;
case AccessDecisionVoter.ACCESS_DENIED:
deny++;
break;
default:
break;
}
}
if (deny > 0) {
throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied",
"Access is denied"));
}
// To get this far, every AccessDecisionVoter abstained
checkAllowIfAllAbstainDecisions();
}
//到这步时,所有的投票者都弃权了
// To get this far, every AccessDecisionVoter abstained
checkAllowIfAllAbstainDecisions();
public class RoleVoter implements AccessDecisionVoter {
//~ Instance fields ================================================================================================
private String rolePrefix = "ROLE_";
//~ Methods ========================================================================================================
public String getRolePrefix() {
return rolePrefix;
}
/**
* Allows the default role prefix of ROLE_
to be overridden.
* May be set to an empty value, although this is usually not desirable.
*
* @param rolePrefix the new prefix
*/
public void setRolePrefix(String rolePrefix) {
this.rolePrefix = rolePrefix;
}
public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null) && attribute.getAttribute().startsWith(getRolePrefix())) {
return true;
}
else {
return false;
}
}
/**
* This implementation supports any type of class, because it does not query
* the presented secure object.
*
* @param clazz the secure object
*
* @return always true
*/
public boolean supports(Class clazz) {
return true;
}
public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) {
int result = ACCESS_ABSTAIN;
Iterator iter = config.getConfigAttributes().iterator();
GrantedAuthority[] authorities = extractAuthorities(authentication);
while (iter.hasNext()) {
ConfigAttribute attribute = (ConfigAttribute) iter.next();
if (this.supports(attribute)) {
result = ACCESS_DENIED;
// Attempt to find a matching granted authority
for (int i = 0; i < authorities.length; i++) {
if (attribute.getAttribute().equals(authorities[i].getAuthority())) {
return ACCESS_GRANTED;
}
}
}
}
return result;
}
GrantedAuthority[] extractAuthorities(Authentication authentication) {
return authentication.getAuthorities();
}
}
if (attribute.getAttribute().equals(authorities[i].getAuthority())) {
return ACCESS_GRANTED;
}
public class AuthenticatedVoter implements AccessDecisionVoter {
//~ Static fields/initializers =====================================================================================
public static final String IS_AUTHENTICATED_FULLY = "IS_AUTHENTICATED_FULLY";
public static final String IS_AUTHENTICATED_REMEMBERED = "IS_AUTHENTICATED_REMEMBERED";
public static final String IS_AUTHENTICATED_ANONYMOUSLY = "IS_AUTHENTICATED_ANONYMOUSLY";
//~ Instance fields ================================================================================================
private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
//~ Methods ========================================================================================================
private boolean isFullyAuthenticated(Authentication authentication) {
return (!authenticationTrustResolver.isAnonymous(authentication)
&& !authenticationTrustResolver.isRememberMe(authentication));
}
public void setAuthenticationTrustResolver(AuthenticationTrustResolver authenticationTrustResolver) {
Assert.notNull(authenticationTrustResolver, "AuthenticationTrustResolver cannot be set to null");
this.authenticationTrustResolver = authenticationTrustResolver;
}
public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null)
&& (IS_AUTHENTICATED_FULLY.equals(attribute.getAttribute())
|| IS_AUTHENTICATED_REMEMBERED.equals(attribute.getAttribute())
|| IS_AUTHENTICATED_ANONYMOUSLY.equals(attribute.getAttribute()))) {
return true;
} else {
return false;
}
}
/**
* This implementation supports any type of class, because it does not query the presented secure object.
*
* @param clazz the secure object
*
* @return always true
*/
public boolean supports(Class clazz) {
return true;
}
public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) {
int result = ACCESS_ABSTAIN;
Iterator iter = config.getConfigAttributes().iterator();
while (iter.hasNext()) {
ConfigAttribute attribute = (ConfigAttribute) iter.next();
if (this.supports(attribute)) {
result = ACCESS_DENIED;
if (IS_AUTHENTICATED_FULLY.equals(attribute.getAttribute())) {
if (isFullyAuthenticated(authentication)) {
return ACCESS_GRANTED;
}
}
if (IS_AUTHENTICATED_REMEMBERED.equals(attribute.getAttribute())) {
if (authenticationTrustResolver.isRememberMe(authentication)
|| isFullyAuthenticated(authentication)) {
return ACCESS_GRANTED;
}
}
if (IS_AUTHENTICATED_ANONYMOUSLY.equals(attribute.getAttribute())) {
if (authenticationTrustResolver.isAnonymous(authentication) || isFullyAuthenticated(authentication)
|| authenticationTrustResolver.isRememberMe(authentication)) {
return ACCESS_GRANTED;
}
}
}
}
return result;
}
}