繁体   English   中英

如何使用@PathVariable解析Spring Security中的参数名称?

[英]How to use @PathVariable to resolve parameter name in Spring Security?

我想使用@PreAuthorize注释来保护Spring REST控制器中的方法,使用方法参数,例如

@RequestMapping("/something/{myParam}")
@PreAuthorize("@security.check(#myParam)")
public String getSomething(@PathVariable("myParam") Integer myParam) {
  //...
}

Spring Security需要一种在运行时发现param名称的方法。 当编译类中没有调试符号时,需要添加一个特殊的注释@P或Spring Data的@Param。 所以,该方法看起来像这样:

@RequestMapping("/something/{myParam}")
@PreAuthorize("@security.check(#myParam)")
public String getSomething(@PathVariable("myParam") @P("myParam) Integer myParam) {
  //...
}

是否有可能以某种方式暗示Spring Security使用@PathVariable而避免使用像@P这样的其他注释?

根据文档阅读,注释中的参数名称由AnnotationParameterNameDiscoverer完成,可以对其进行自定义以支持任何指定注释的value属性。 但是,我找不到有关如何自定义它的任何信息。

顺便说一句,我使用的是Java 7和Spring Security 3.2.9。

简而言之,您需要在GlobalMethodSecurityConfiguration#createExpressionHandler方法中覆盖SecurityExpressionHandler创建,以便在自定义GlobalMethodSecurityConfiguration中设置您自己的ParameterNameDiscoverer

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {

  @Autowired
  private ApplicationContext context;

  @Override
  protected MethodSecurityExpressionHandler createExpressionHandler() {
    DefaultMethodSecurityExpressionHandler result = new DefaultMethodSecurityExpressionHandler();
    result.setApplicationContext(this.context);
    result.setParameterNameDiscoverer(new AnnotationParameterNameDiscoverer(PathVariable.class.getName()));
    return result;
  }

}

示例项目中,您可以在控制台输出中看到类似这样的结果

2016-06-06 17:09:01.635  INFO 2871 --- [nio-8080-exec-4] c.s.so.q37435824.SecurityService: myParam value from PathVariable equals 1

最好的祝福

以下配置未经过测试,但基于弹簧安全性来源的研究,因此请尝试按如下方式更改Spring Security配置xml

<security:global-method-security pre-post-annotations="enabled">
    <security:expression-handler ref="expressionHandler"/>
</security:global-method-security>

<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <property name="parameterNameDiscoverer" ref="parameterNameDiscoverer"/>
</bean>

<bean id="parameterNameDiscoverer" class="org.springframework.security.core.parameters.AnnotationParameterNameDiscoverer">
    <constructor-arg>
        <list>
            <value>org.springframework.web.bind.annotation.PathVariable</value>
        </list>
    </constructor-arg>
</bean>

来自官方的Spring安全文档GlobalMethodSecurityConfiguration

有时您可能需要执行比@EnableGlobalMethodSecurity批注允许更复杂的操作。 对于这些实例,您可以扩展GlobalMethodSecurityConfiguration确保子类上存在@EnableGlobalMethodSecurity批注。 例如,如果要提供自定义MethodSecurityExpressionHandler ,可以使用以下配置:

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        // ... create and return custom MethodSecurityExpressionHandler ...
        return expressionHandler;
    }
}

如上例所示,您可以编写自定义MethodSecurityExpressionHandler或使用DefaultMethodSecurityExpressionHandler设置自定义ParameterNameDiscoverer,扩展DefaultSecurityParameterNameDiscoverer (或不)

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        expressionHandler.setParameterNameDiscoverer(new CustomParameterNameDiscoverer());
        return expressionHandler;
    }
}

另一个示例Spring Security Java Config Preview:自定义方法安全性

希望这可以帮助。

从Spring安全官方文档中可以实现所请求的用例。 但要使用你需要升级到弹簧4.1.0,我没试过看起来这是可以实现的

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM