Browse Source

SEC-1452: Added namespace support for custom expression handler for use with web access expressions.

pull/1/head
Luke Taylor 15 years ago
parent
commit
27caecd53f
  1. 5
      config/src/main/java/org/springframework/security/config/http/FilterInvocationSecurityMetadataSourceParser.java
  2. 8
      config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java
  3. 2
      config/src/main/resources/org/springframework/security/config/spring-security-3.1.rnc
  4. 5
      config/src/main/resources/org/springframework/security/config/spring-security-3.1.xsd
  5. 33
      config/src/test/groovy/org/springframework/security/config/http/MiscHttpConfigTests.groovy

5
config/src/main/java/org/springframework/security/config/http/FilterInvocationSecurityMetadataSourceParser.java

@ -8,6 +8,7 @@ import org.springframework.beans.factory.config.BeanDefinition; @@ -8,6 +8,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
@ -59,7 +60,7 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit @@ -59,7 +60,7 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
return mds;
}
static BeanDefinition createSecurityMetadataSource(List<Element> interceptUrls, Element elt, ParserContext pc) {
static RootBeanDefinition createSecurityMetadataSource(List<Element> interceptUrls, Element elt, ParserContext pc) {
MatcherType matcherType = MatcherType.fromElement(elt);
boolean useExpressions = isUseExpressions(elt);
@ -87,7 +88,7 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit @@ -87,7 +88,7 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
fidsBuilder.getRawBeanDefinition().setSource(pc.extractSource(elt));
return fidsBuilder.getBeanDefinition();
return (RootBeanDefinition) fidsBuilder.getBeanDefinition();
}
static String registerDefaultExpressionHandler(ParserContext pc) {

8
config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java

@ -451,15 +451,17 @@ class HttpConfigurationBuilder { @@ -451,15 +451,17 @@ class HttpConfigurationBuilder {
private void createFilterSecurityInterceptor(BeanReference authManager) {
boolean useExpressions = FilterInvocationSecurityMetadataSourceParser.isUseExpressions(httpElt);
BeanDefinition securityMds = FilterInvocationSecurityMetadataSourceParser.createSecurityMetadataSource(interceptUrls, httpElt, pc);
RootBeanDefinition securityMds = FilterInvocationSecurityMetadataSourceParser.createSecurityMetadataSource(interceptUrls, httpElt, pc);
RootBeanDefinition accessDecisionMgr;
ManagedList<BeanDefinition> voters = new ManagedList<BeanDefinition>(2);
if (useExpressions) {
BeanDefinitionBuilder expressionVoter = BeanDefinitionBuilder.rootBeanDefinition(WebExpressionVoter.class);
RuntimeBeanReference expressionHandler = new RuntimeBeanReference(
FilterInvocationSecurityMetadataSourceParser.registerDefaultExpressionHandler(pc));
// Read the expression handler from the FISMS
RuntimeBeanReference expressionHandler = (RuntimeBeanReference)
securityMds.getConstructorArgumentValues().getArgumentValue(1, RuntimeBeanReference.class).getValue();
expressionVoter.addPropertyValue("expressionHandler", expressionHandler);
voters.add(expressionVoter.getBeanDefinition());

2
config/src/main/resources/org/springframework/security/config/spring-security-3.1.rnc

@ -268,7 +268,7 @@ http-firewall = @@ -268,7 +268,7 @@ http-firewall =
http =
## Container element for HTTP security configuration. Multiple elements can now be defined, each with a specific pattern to which the enclosed security configuration applies. A pattern can also be configured to bypass Spring Security's filters completely by setting the "secured" attribute to "false".
element http {http.attlist, (intercept-url* & access-denied-handler? & form-login? & openid-login? & x509? & jee? & http-basic? & logout? & session-management & remember-me? & anonymous? & port-mappings & custom-filter* & request-cache?) }
element http {http.attlist, (intercept-url* & access-denied-handler? & form-login? & openid-login? & x509? & jee? & http-basic? & logout? & session-management & remember-me? & anonymous? & port-mappings & custom-filter* & request-cache? & expression-handler?) }
http.attlist &=
## The request URL pattern which will be mapped to the filter chain created by this <http> element. If omitted, the filter chain will match all requests.
attribute pattern {xsd:token}?

5
config/src/main/resources/org/springframework/security/config/spring-security-3.1.xsd

@ -682,6 +682,11 @@ @@ -682,6 +682,11 @@
</xs:complexType></xs:element>
<xs:element ref="security:custom-filter"/>
<xs:element ref="security:request-cache"/>
<xs:element name="expression-handler"><xs:annotation>
<xs:documentation>Defines the SecurityExpressionHandler instance which will be used if expression-based access-control is enabled. A default implementation (with no ACL support) will be used if not supplied.</xs:documentation>
</xs:annotation><xs:complexType>
<xs:attributeGroup ref="security:ref"/>
</xs:complexType></xs:element>
</xs:choice>
<xs:attributeGroup ref="security:http.attlist"/>
</xs:complexType></xs:element>

33
config/src/test/groovy/org/springframework/security/config/http/MiscHttpConfigTests.groovy

@ -50,6 +50,9 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider @@ -50,6 +50,9 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider
import org.springframework.security.access.vote.RoleVoter
import org.springframework.security.web.access.expression.WebExpressionVoter
import org.springframework.security.access.vote.AffirmativeBased
import org.springframework.security.access.PermissionEvaluator
import org.springframework.security.core.Authentication
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler
class MiscHttpConfigTests extends AbstractHttpConfigTests {
def 'Minimal configuration parses'() {
@ -497,6 +500,25 @@ class MiscHttpConfigTests extends AbstractHttpConfigTests { @@ -497,6 +500,25 @@ class MiscHttpConfigTests extends AbstractHttpConfigTests {
thrown(AccessDeniedException)
}
def expressionBasedAccessSupportsExternalExpressionHandler() {
setup:
xml.http('auto-config': 'true', 'use-expressions': 'true') {
interceptUrl('/**', "hasPermission('AnyObject','R')")
'expression-handler'(ref: 'expressionHandler')
}
bean('expressionHandler', DefaultWebSecurityExpressionHandler.class.name, [:], [permissionEvaluator: 'pe'])
bean('pe', MockPermissionEvaluator)
createAppContext()
def fis = getFilter(FilterSecurityInterceptor)
when: "Invoking allowed URL protected by hasPermission() expression succeeds"
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("joe", "", "ANY"));
fis.invoke(createFilterinvocation("/secure", null));
then:
notThrown(AccessDeniedException)
}
def protectedLoginPageReportsWarning() {
when:
xml.http('use-expressions': 'true') {
@ -647,6 +669,17 @@ class MiscHttpConfigTests extends AbstractHttpConfigTests { @@ -647,6 +669,17 @@ class MiscHttpConfigTests extends AbstractHttpConfigTests {
}
}
class MockPermissionEvaluator implements PermissionEvaluator {
boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
return true
}
boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
return true
}
}
class MockEntryPoint extends LoginUrlAuthenticationEntryPoint {
public MockEntryPoint() {
super.setLoginFormUrl("/notused");

Loading…
Cancel
Save