Дякую ericacm , але це не працює з кількох причин:
- Властивості DefaultMethodSecurityExpressionHandler є приватними (клуби видимості відображення небажані)
- Принаймні , в моєму Eclipse, я не можу вирішити MethodSecurityEvaluationContext об'єкт
Відмінності полягають у тому, що ми викликаємо існуючий метод createEvaluationContext, а потім додаємо власний кореневий об’єкт. Нарешті, я щойно повернув тип об’єкта StandardEvaluationContext, оскільки MethodSecurityEvaluationContext не вирішить проблему в компіляторі (вони обидва з одного інтерфейсу). Це код, який я зараз маю на виробництві.
Зробіть MethodSecurityExpressionHandler використовувати наш власний корінь:
public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
// parent constructor
public CustomMethodSecurityExpressionHandler() {
super();
}
/**
* Custom override to use {@link CustomSecurityExpressionRoot}
*
* Uses a {@link MethodSecurityEvaluationContext} as the <tt>EvaluationContext</tt> implementation and
* configures it with a {@link MethodSecurityExpressionRoot} instance as the expression root object.
*/
@Override
public EvaluationContext createEvaluationContext(Authentication auth, MethodInvocation mi) {
// due to private methods, call original method, then override it's root with ours
StandardEvaluationContext ctx = (StandardEvaluationContext) super.createEvaluationContext(auth, mi);
ctx.setRootObject( new CustomSecurityExpressionRoot(auth) );
return ctx;
}
}
Це замінює root за замовчуванням, розширюючи SecurityExpressionRoot . Тут я перейменував hasRole на hasEntitlement:
public class CustomSecurityExpressionRoot extends SecurityExpressionRoot {
// parent constructor
public CustomSecurityExpressionRoot(Authentication a) {
super(a);
}
/**
* Pass through to hasRole preserving Entitlement method naming convention
* @param expression
* @return boolean
*/
public boolean hasEntitlement(String expression) {
return hasRole(expression);
}
}
Нарешті оновіть securityContext.xml (і переконайтеся, що на нього посилається ваш applcationContext.xml):
<!-- setup method level security using annotations -->
<security:global-method-security
jsr250-annotations="disabled"
secured-annotations="disabled"
pre-post-annotations="enabled">
<security:expression-handler ref="expressionHandler"/>
</security:global-method-security>
<!--<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">-->
<bean id="expressionHandler" class="com.yourSite.security.CustomMethodSecurityExpressionHandler" />
Примітка. Анотація @Secured не прийме цю заміну, оскільки вона проходить через інший обробник перевірки. Отже, у наведеному вище xml я відключив їх, щоб уникнути подальшої плутанини.