[英]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.