Shibboleth IdP 3.3より導入されたMultiFactor認証フローの認証設定についてのドキュメントです。本ドキュメントはSAML 2.0で認証の切り替えを行うことを目的としており、SAML1は対象外です(LevelXを用いた認証要求はできません)。 MultiFactor認証フローは、シンプルもしくは複雑な認証シーケンスを作るために複数の認証フローを組み合わせるスクリプト可能な方法を提供します。 MultiFactor認証フローの設定は、 また、 もっと簡単なルールは、最初の認証フローが成功した場合に、次に実行する認証フローを指定してます。 下記の例は、最初にPassword認証フローによる認証を行い、Password認証フローの認証が成功した場合にX509認証フローの認証が行われます。X509認証フローの認証が成功すると認証成功となります。 複雑なルールは、Java, ScriptもしくはSpring Expressionを記述することで実現できます。 下記の例は、以下の認証シーケンスを実現しています。 なお、 Shibboleth IdP ver.2において、NIIと金沢大学で共同開発したGUARDプラグインと同様な認証シーケンスを実現します。GUARDプラグインについては、2015年2月に金沢大学の松平様が発表された『大学統合認証基盤における多要素認証について』の12ページをご参照ください。kaa以下の例で下記の例での認証コンテクストと認証フローの関係を下記に示します。 (機関内) パスワード OR RemoteUser OR X509 (機関外) RemoteUser OR X509 conf/authn/mfa-authn-config.xmlで各Levelに応じた認証設定を行います。Level2, Level3で異なる認証フローを使用したい場合は16行目から23行目、および31行目を変更します。 T.B.D. (General Configuration)
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)
<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)
allowedLoginMethods
を取得します。allowedLoginMethods
が存在し、かつ属性値にPassowrdが含まれていれば、Password認証フローのみで認証成功になります。そうでなければステップ5に遷移します。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)
認証コンテクスト 略称 認証フロー urn:mace:gakunin.jp:idprivacy:ac:classes:Level1
Level1
パスワード urn:mace:gakunin.jp:idprivacy:ac:classes:Level2
Level2
urn:mace:gakunin.jp:idprivacy:ac:classes:Level3
Level3
RemoteUser AND X509 制限事項
設定
<util:map id="shibboleth.authn.MFA.TransitionMap">
<!-- First rule calls a flow to display a view to select a method to run. -->
<entry key="">
<bean parent="shibboleth.authn.MFA.Transition" p:nextFlow="custom/methodChooser" />
</entry>
<!-- Second rule decides what to call based on event signaled by the view. -->
<entry key="custom/methodChooser">
<bean parent="shibboleth.authn.MFA.Transition">
<property name="nextFlowStrategyMap">
<map>
<!-- Maps event to a flow -->
<!-- Level1 -->
<entry key="ChooseLevel1" value="authn/Level1" />
<!-- Level2 -->
<entry key="ChoosePassword" value="authn/Password" />
<entry key="ChooseRemoteUser" value="authn/RemoteUser" />
<entry key="ChooseX509" value="authn/X509" />
<!-- Level3 -->
<entry key="ChooseLevel3" value="authn/RemoteUser4Level3" />
</map>
</property>
</bean>
</entry>
<!-- Level3 -->
<entry key="authn/RemoteUser4Level3">
<bean parent="shibboleth.authn.MFA.Transition" p:nextFlow="authn/X509" />
</entry>
<!-- An implicit final rule will return whatever the final flow returns. -->
</util:map>
参考