は、私は自分のAccessDecisionManager
を実装することで、参加者は私の特別なインタフェースAccessDecisionStrategy
に意思決定をアクセスすることをことを達成:
public interface AccessDecisionStrategy {
void decide(Authentication authentication, MethodInvocation methodInvocation, ConfigAttribute configAttribute);
}
各アクセス決定戦略は、アクセスの決定を行う別の方法を表しています。
public class SomeStrategy implements AccessDecisionStrategy { ...
あなたが見ることができるように、私のAccessDecisionManager
は戦略のマップを持っています -
あなたは簡単に(例えばScalaのためにも、他の言語で)独自の戦略を実装することができます。マネージャが使用する戦略は注釈引数に基づいています。私は私の方法を保護したいとき
public class MethodSecurityAccessDecisionManager implements AccessDecisionManager {
private Map<String, AccessDecisionStrategy> strategyMap;
public MethodSecurityAccessDecisionManager(Map<String, AccessDecisionStrategy> strategyMap) {
this.strategyMap = strategyMap;
}
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
ConfigAttribute configAttribute = getSingleConfigAttribute(configAttributes);
AccessDecisionStrategy accessDecisionStrategy = strategyMap.get(configAttribute.getAttribute());
if (accessDecisionStrategy == null) {
throw new IllegalStateException("AccessDecisionStrategy with name "
+ configAttribute.getAttribute() + " was not found!");
}
try {
accessDecisionStrategy.decide(authentication, (MethodInvocation) object, configAttribute);
} catch (ClassCastException e) {
throw new IllegalStateException();
}
}
private ConfigAttribute getSingleConfigAttribute(Collection<ConfigAttribute> configAttributes) {
if (configAttributes == null || configAttributes.size() != 1) {
throw new IllegalStateException("Invalid config attribute configuration");
}
return configAttributes.iterator().next();
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return clazz.equals(MethodInvocation.class);
}
}
は、今私は、戦略の名前を引数にして@Secured
注釈を入れて:
@Secured("GetByOwner")
FlightSpotting getFlightSpotting(Long id);
を使用すると、必要な数の戦略を実施して設定することができます。
<bean id="methodSecurityAccessDecisionManager"
class="some.package.MethodSecurityAccessDecisionManager">
<constructor-arg>
<map>
<entry key="GetByOwner">
<bean class="some.package.GetByOwnerStrategy"/>
</entry>
<entry key="SomeOther">
<bean class="some.package.SomeOtherStrategy"/>
</entry>
</map>
</constructor-arg>
</bean>
アクセス判定マネージャを挿入するには、次のように入力します。
<sec:global-method-security secured-annotations="enabled"
access-decision-manager-ref="methodSecurityAccessDecisionManager">
</sec:global-method-security>
私も
MethodInvocation
引数を扱うヘルパークラスに実装
:今、あなたは簡単に意思決定を行うための戦略のコードで興味深いの引数を抽出することができます
import org.aopalliance.intercept.MethodInvocation;
public class MethodInvocationExtractor<ArgumentType> {
private MethodInvocation methodInvocation;
public MethodInvocationExtractor(MethodInvocation methodInvocation) {
this.methodInvocation = methodInvocation;
}
public ArgumentType getArg(int num) {
try {
Object[] arguments = methodInvocation.getArguments();
return (ArgumentType) arguments[num];
} catch (ClassCastException | ArrayIndexOutOfBoundsException e) {
throw new IllegalStateException();
}
}
}
を:
のは、私は引数の数を取得したいとしましょう
MethodInvocationExtractor<Long> extractor = new MethodInvocationExtractor<>(methodInvocation);
Long id = extractor.getArg(0);
+1決定にMethodInvocationにオブジェクトをキャストするポインタのために()。 Springのドキュメントには、その重要な情報が欠落しています。 –
誰かがそれを必要とする場合は、Java Config(このプロジェクトではSpring-Bootを使用しています)を使用してこれを実装する方法を追加しました(http:// stackoverflow。 com/q/24983046/2796922)。私の答えを見てください。 – elysch
多くのユースケースでは、独自のデシジョンマネージャを実装する必要はありません。代わりに '@ Preauthorize'から直接呼び出すメソッドを書くことができます。この回答を参照してください:http://stackoverflow.com/a/39972346/1169324 –