Shibboleth IdP 3.3より導入されたMultiFactor認証フローの認証設定についてのドキュメントです。本ドキュメントはSAML 2.0で認証の切り替えを行うことを目的としており、SAML1は対象外です(LevelXを用いた認証要求はできません)。 MultiFactor認証フローは、シンプルもしくは複雑な認証シーケンスを作るために複数の認証フローを組み合わせるスクリプト可能な方法を提供します。 T.B.D. (General Configuration)MultiFactor認証フローの設定は、conf/authn/mfa-authn-config.xml で行います。 また、conf/idp.properties のidp.authn.flows でMultiFactor認証フローを有効します。注意すべき点として、MultiFactor認証フローからルールやスクリプトを介して呼び出す認証フローは、意図を通りでない方法でIdPが有効とした認証フローを実行するかもしれないためidp.authn.flows で有効にすべきではない、とされています。 # Regular expression matching login flows to enable, e.g. IPAddress|Password
-idp.authn.flows= Password
+idp.authn.flows= MFA |
T.B.D. (Directly Selecting Flows)もっと簡単なルールは、最初の認証フローが成功した場合に、次に実行する認証フローを指定してます。 下記の例は、最初にPassword認証フローによる認証を行い、Password認証フローの認証が成功した場合にX509認証フローの認証が行われます。X509認証フローの認証が成功すると認証成功となります。 <util:map id="shibboleth.authn.MFA.TransitionMap">
<!-- Run authn/Passowrd first. -->
<entry key="">
<bean parent="shibboleth.authn.MFA.Transition" p:nextFlow="authn/Passowrd" />
</entry>
<!-- If that returns "proceed", run authn/X509 next. -->
<entry key="authn/Password">
<bean parent="shibboleth.authn.MFA.Transition" p:nextFlow="authn/X509" />
</entry>
<!-- An implicit final rule will return whatever the second flow returns. -->
</util:map> |
T.B.D. (Programmatically Selecting Flows) 複雑なルールは、Java, ScriptもしくはSpring Expressionを記述することで実現できます。 下記の例は、以下の認証シーケンスを実現しています。 - 最初にPassword認証フローを実行します。
- ステップ1のPassword認証フローが認証成功し認証要求を満たすのに十分であればステップ3を、そうでなければステップ5に遷移します。
- ステップ1によって識別されたユーザの属性
allowedLoginMethods を取得します。 - 属性
allowedLoginMethods が存在し、かつ属性値にPassowrdが含まれていれば、Password認証フローのみで認証成功になります。そうでなければステップ5に遷移します。
- X509認証フローを実行します。
- X509認証フローが認証成功すれば、Password認証フローとX509認証フローの認証結果が一つにマージされます。
- 両方の認証フローが認証成功であれば認証成功となり、そうでなければ認証失敗となります。
なお、conf/attribute-resolver.xml に属性 allowedLoginMethods を追加する必要があります。 <util:map id="shibboleth.authn.MFA.TransitionMap">
<!-- Run authn/Passowrd first. -->
<entry key="">
<bean parent="shibboleth.authn.MFA.Transition" p:nextFlow="authn/Passowrd" />
</entry>
<!--
Second rule runs a function if authn/Password succeeds, to determine whether an additional
factor is required.
-->
<entry key="authn/Password">
<bean parent="shibboleth.authn.MFA.Transition" p:nextFlowStrategy-ref="checkSecondFactor" />
</entry>
<!-- An implicit final rule will return whatever the second flow returns. -->
</util:map>
<!-- Example script to see if second factor is required. -->
<bean id="checkSecondFactor" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript"
p:customObject-ref="shibboleth.AttributeResolverService">
<constructor-arg>
<value>
<![CDATA[
nextFlow = "authn/X509";
// Go straight to second factor if we have to, or set up for an attribute lookup first.
authCtx = input.getSubcontext("net.shibboleth.idp.authn.context.AuthenticationContext");
mfaCtx = authCtx.getSubcontext("net.shibboleth.idp.authn.context.MultiFactorAuthenticationContext");
if (mfaCtx.isAcceptable()) {
// Attribute check is required to decide if first factor alone is enough.
resCtx = input.getSubcontext(
"net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext", true);
// Look up the username
usernameLookupStrategyClass = Java.type("net.shibboleth.idp.session.context.navigate.CanonicalUsernameLookupStrategy");
usernameLookupStrategy = new usernameLookupStrategyClass();
resCtx.setPrincipal(usernameLookupStrategy.apply(input));
// resolve the attribute to determine if a first factor is sufficient
resCtx.getRequestedIdPAttributeNames().add("allowedLoginMethods");
resCtx.resolveAttributes(custom);
// Check for an attribute value that authorizes use of first factor.
attribute = resCtx.getResolvedIdPAttributes().get("allowedLoginMethods");
valueType = Java.type("net.shibboleth.idp.attribute.StringAttributeValue");
if (attribute != null && attribute.getValues().contains(new valueType("Password"))) {
nextFlow = null;
}
input.removeSubcontext(resCtx); // cleanup
}
nextFlow; // pass control to second factor or end with the first
]]>
</value>
</constructor-arg>
</bean> |
T.B.D. (Full Control Over Transitions) 参考 |