Child pages
  • Shibboleth IdP 3の高度な認証設定
Skip to end of metadata
Go to start of metadata

以下で簡便な方法を説明していますが、3.3以降であればより汎用的で複雑な挙動が実現できるMFAによる方法もご参照ください。

Shibboleth IdP 3の高度な認証設定についてのドキュメントです。本ドキュメントはSAML 2.0で認証の切り替えを行うことを目的としており、SAML1は対象外です(LevelXを用いた認証要求はできません)。

SAML1を使うことにより本設定の制約を迂回できることを避けるため、SPにおいてはshibboleth2.xmlにてSAML1の機能を無効化することをお勧めします。

本ドキュメントで使用する認証コンテクストと認証フローの関係を下記に示します。

ここでRemoteUserはパスワード認証とクライアント証明書認証の中間の強度の認証の例として挙げております。実際に運用する場合は別途用意した認証フローで置き換えてください。また、レベルとの対応付けも本ドキュメント独自のもので、例示として使用しています。

認証コンテクスト略称認証フロー
urn:mace:gakunin.jp:idprivacy:ac:classes:Level1Level1Password
urn:mace:gakunin.jp:idprivacy:ac:classes:Level2Level2RemoteUser
urn:mace:gakunin.jp:idprivacy:ac:classes:Level3Level3X509

この認証コンテクストとは別に、PasswordやX509は固有の認証コンテクストを持っていますが、ここでは使用しません。

挙動の説明で使用するSPについて下記に示します。

SP要求する認証
SPaなし
SPburn:mace:gakunin.jp:idprivacy:ac:classes:Level1
SPcurn:mace:gakunin.jp:idprivacy:ac:classes:Level2
SPdurn:mace:gakunin.jp:idprivacy:ac:classes:Level3


認証フローの階層化

設定
  1. conf/idp.propertiesidp.authn.flowsに有効にする認証フローを設定します。

    conf/idp.properties
     # Regular expression matching login flows to enable, e.g. IPAddress|Password
    -idp.authn.flows= Password
    +idp.authn.flows= Password|RemoteUser|X509
  2. 既に認証済みの認証フローを優先するために、conf/idp.propertiesidp.authn.favorSSOをアンコメントしtrueに設定します。

    conf/idp.properties
     # Whether to prioritize "active" results when an SP requests more than
     # one possible matching login method (V2 behavior was to favor them)
    -#idp.authn.favorSSO = false
    +idp.authn.favorSSO = true


  3. conf/authn/general-authn.xmlshibboleth.AvailableAuthenticationFlows内の認証フローを弱い認証フローから強い認証フローの順に並べ替えます。また、各認証フローのsupportedPrincipalsプロパティに下記を追加します。

    認証フローsupportedPrincipalsプロパティ
    Password継承元のshibboleth.AuthenticationFlowで定義されているsupportedPrincipals, Level1
    RemoteUserLevel2, Level1
    X509Level3, Level2, Level1
    conf/authn/general-authn.xml
         <util:list id="shibboleth.AvailableAuthenticationFlows">
     
             <bean id="authn/IPAddress" parent="shibboleth.AuthenticationFlow"
                     p:passiveAuthenticationSupported="true"
                     p:lifetime="PT60S" p:inactivityTimeout="PT60S">
                 <property name="supportedPrincipals">
                     <list>
                         <bean parent="shibboleth.SAML2AuthnContextClassRef"
                             c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocol" />
                     </list>
                 </property>
             </bean>
     
             <bean id="authn/SPNEGO" parent="shibboleth.AuthenticationFlow"
                     p:nonBrowserSupported="false">
                 <property name="supportedPrincipals">
                     <list>
                         <bean parent="shibboleth.SAML2AuthnContextClassRef"
                             c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos" />
                         <bean parent="shibboleth.SAML1AuthenticationMethod"
                             c:method="urn:ietf:rfc:1510" />
                     </list>
                 </property>
             </bean>
     
             <bean id="authn/External" parent="shibboleth.AuthenticationFlow"
                 p:nonBrowserSupported="false" />
     
    +        <bean id="authn/Password" parent="shibboleth.AuthenticationFlow"
    +                p:passiveAuthenticationSupported="true"
    +                p:forcedAuthenticationSupported="true">
    +            <property name="supportedPrincipals">
    +                <util:list>
    +                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +                        c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" />
    +                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +                        c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:Password" />
    +                    <bean parent="shibboleth.SAML1AuthenticationMethod"
    +                        c:method="urn:oasis:names:tc:SAML:1.0:am:password" />
    +                    <!-- -->
    +                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +                        c:classRef="urn:mace:gakunin.jp:idprivacy:ac:classes:Level1" />
    +                </util:list>
    +            </property>
    +        </bean>
    +
             <bean id="authn/RemoteUser" parent="shibboleth.AuthenticationFlow"
    -            p:nonBrowserSupported="false" />
    +            p:nonBrowserSupported="false">
    +            <property name="supportedPrincipals">
    +                <util:list>
    +                    <!-- -->
    +                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +                        c:classRef="urn:mace:gakunin.jp:idprivacy:ac:classes:Level2" />
    +                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +                        c:classRef="urn:mace:gakunin.jp:idprivacy:ac:classes:Level1" />
    +                </util:list>
    +            </property>
    +        </bean>
     
             <bean id="authn/RemoteUserInternal" parent="shibboleth.AuthenticationFlow" />
     
             <bean id="authn/X509" parent="shibboleth.AuthenticationFlow"
                     p:nonBrowserSupported="false">
                 <property name="supportedPrincipals">
                     <list>
                         <bean parent="shibboleth.SAML2AuthnContextClassRef"
                             c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:X509" />
                         <bean parent="shibboleth.SAML2AuthnContextClassRef"
                             c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient" />
                         <bean parent="shibboleth.SAML1AuthenticationMethod"
                             c:method="urn:ietf:rfc:2246" />
    +                    <!-- -->
    +                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +                        c:classRef="urn:mace:gakunin.jp:idprivacy:ac:classes:Level3" />
    +                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +                        c:classRef="urn:mace:gakunin.jp:idprivacy:ac:classes:Level2" />
    +                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +                        c:classRef="urn:mace:gakunin.jp:idprivacy:ac:classes:Level1" />
                     </list>
                 </property>
             </bean>
     
             <bean id="authn/X509Internal" parent="shibboleth.AuthenticationFlow">
                 <property name="supportedPrincipals">
                     <list>
                         <bean parent="shibboleth.SAML2AuthnContextClassRef"
                             c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:X509" />
                         <bean parent="shibboleth.SAML2AuthnContextClassRef"
                             c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient" />
                         <bean parent="shibboleth.SAML1AuthenticationMethod"
                             c:method="urn:ietf:rfc:2246" />
                     </list>
                 </property>
             </bean>
     
    -        <bean id="authn/Password" parent="shibboleth.AuthenticationFlow"
    -                p:passiveAuthenticationSupported="true"
    -                p:forcedAuthenticationSupported="true" />
    -
         </util:list>
  4. conf/relying-party.xmlshibboleth.DefaultRelyingParty内のSAML2.SSOdefaultAuthenticationMethodsプロパティを設定します。

    conf/relying-party.xml
         <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
             <property name="profileConfigurations">
                 <list>
                     <bean parent="Shibboleth.SSO" p:postAuthenticationFlows="attribute-release" />
                     <ref bean="SAML1.AttributeQuery" />
                     <ref bean="SAML1.ArtifactResolution" />
    -                <bean parent="SAML2.SSO" p:postAuthenticationFlows="attribute-release" />
    +                <bean parent="SAML2.SSO" p:postAuthenticationFlows="attribute-release">
    +                    <property name="defaultAuthenticationMethods">
    +                        <list>
    +                            <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +                                c:classRef="urn:mace:gakunin.jp:idprivacy:ac:classes:Level1" />
    +                        </list>
    +                    </property>
    +                </bean>
                     <ref bean="SAML2.ECP" />
                     <ref bean="SAML2.Logout" />
                     <ref bean="SAML2.AttributeQuery" />
                     <ref bean="SAML2.ArtifactResolution" />
                     <ref bean="Liberty.SSOS" />
                 </list>
             </property>
         </bean>

    必要であればRelyingPartyOverridesのほうのSAML2.SSOにも同様の設定を追加してください。

挙動
未認証の場合
  1. SPaもしくはSPbからIdPにリダイレクトされると、Level1のPassword認証フローのログインページが表示されます。
  2. SPcからIdPにリダイレクトされると、Level2のRemoteUser認証フローのためのログインページやダイアログが表示されます。
  3. SPdからIdPにリダイレクトされると、Level3のX509認証フローのログインページが表示されます。
Level1が認証済みの場合
  1. SPaもしくはSPbからIdPにリダイレクトされると、Level1のPassword認証フローが認証済みのためユーザ同意画面もしくは認証後のSPの画面が表示されます。
  2. SPcからIdPにリダイレクトされると、Level2のRemoteUser認証フローのためのログインページやダイアログが表示されます。
  3. SPdからIdPにリダイレクトされると、Level3のX509認証フローのログインページが表示されます。
Level2が認証済みの場合
  1. SPaもしくはSPbからIdPにリダイレクトされると、Level2のRemoteUser認証フローが認証済みのためユーザ同意画面もしくは認証後のSPの画面が表示されます。
  2. SPcからIdPにリダイレクトされると、Level2のRemoteUser認証フローが認証済みのためユーザ同意画面もしくはSPの画面が表示されます。
  3. SPdからIdPにリダイレクトされると、Level3のX509認証フローのログインページが表示されます。
Level3が認証済みの場合
  1. SPaもしくはSPbからIdPにリダイレクトされると、Level3のX509認証フローが認証済みのためユーザ同意画面もしくは認証後のSPの画面が表示されます。
  2. SPcからIdPにリダイレクトされると、Level3のX509認証フローが認証済みのためユーザ同意画面もしくは認証後のSPの画面が表示されます。
  3. SPdからIdPにリダイレクトされると、Level3のX509認証フローが認証済みのためユーザ同意画面もしくは認証後のSPの画面が表示されます。

Password認証フローのExtendedフロー

設定
  1. 認証フローの階層化の設定を行ってください。

  2. conf/authn/general-authn.xmlauthn/PasswordにExtendedフローで利用するLevel2, Level3を追加します。

    conf/authn/general-authn.xml
             <bean id="authn/Password" parent="shibboleth.AuthenticationFlow"
                     p:passiveAuthenticationSupported="true"
                     p:forcedAuthenticationSupported="true">
                 <property name="supportedPrincipals">
                     <util:list>
                         <bean parent="shibboleth.SAML2AuthnContextClassRef"
                             c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" />
                         <bean parent="shibboleth.SAML2AuthnContextClassRef"
                             c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:Password" />
                         <bean parent="shibboleth.SAML1AuthenticationMethod"
                             c:method="urn:oasis:names:tc:SAML:1.0:am:password" />
                         <!-- -->
                         <bean parent="shibboleth.SAML2AuthnContextClassRef"
                             c:classRef="urn:mace:gakunin.jp:idprivacy:ac:classes:Level1" />
    +                    <!-- Extended Flows -->
    +                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +                        c:classRef="urn:mace:gakunin.jp:idprivacy:ac:classes:Level2" />
    +                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +                        c:classRef="urn:mace:gakunin.jp:idprivacy:ac:classes:Level3" />
                     </util:list>
                 </property>
             </bean>
  3. conf/authn/password-authn-config.xmlでExtendedフローのbeanをアンコメントし、下記の設定を行います。

    • shibboleth.authn.Password.ExtendedFlowsのc:_0に、ExtendedフローとするRemoteUserX509を設定します。

    • shibboleth.authn.Password.PrincipalOverrideに、Password認証フローで認証するLevel1を追加します。
    conf/authn/password-authn-config.xml
         <!--
         Configuration of "extended" login methods to offer in the password login form.
         The String bean is a regular expression identifying the flows to offer. These flows
         must also be enabled at the "top" level to be available for use.
         The ExtendedFlowParameters bean can be used to transfer custom parameters from the
         login form into the context tree for use later by other flows.
         The last bean provides the set of custom Principals to use for results produced by the
         Password flow itself. You would use this if you need the Password flow to run as a shell
         to run the "extended" login methods, but want to limit its own results more narrowly.
         -->
    -    <!--
    -    <bean id="shibboleth.authn.Password.ExtendedFlows" class="java.lang.String" c:_0="" />
    +    <bean id="shibboleth.authn.Password.ExtendedFlows" class="java.lang.String" c:_0="RemoteUser|X509" />
         <util:list id="shibboleth.authn.Password.ExtendedFlowParameters">
         </util:list>
         <util:list id="shibboleth.authn.Password.PrincipalOverride">
             <bean parent="shibboleth.SAML2AuthnContextClassRef"
                 c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" />
             <bean parent="shibboleth.SAML2AuthnContextClassRef"
                 c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:Password" />
             <bean parent="shibboleth.SAML1AuthenticationMethod"
                 c:method="urn:oasis:names:tc:SAML:1.0:am:password" />
    +        <!-- -->
    +        <bean parent="shibboleth.SAML2AuthnContextClassRef"
    +            c:classRef="urn:mace:gakunin.jp:idprivacy:ac:classes:Level1" />
         </util:list>
    -    -->
  4. Shibboleth IdP 4.0.0および4.0.1をお使いの場合および以降のバージョンでも以前のバージョンからアップデートしている場合は、login.vmにバグがあり追加のボタンが表示されませんので、以下の修正を行ってください。

    views/login.vm
                 #end
     
                 #foreach ($extFlow in $extendedAuthenticationFlows)
    -              #if ($authenticationContext.isAcceptable($extFlow) and $extFlow.apply(profileRequestContext))
    +              #if ($authenticationContext.isAcceptable($extFlow) and $extFlow.test(profileRequestContext))
                     <div class="form-element-wrapper">
                       <button class="form-element form-button" type="submit" name="_eventId_$extFlow.getId()">
                         #springMessageText("idp.login.$extFlow.getId().replace('authn/','')", $extFlow.getId().replace('authn/',''))
挙動

各SPからIdPにリダイレクトされた時に表示されるPassword認証フローのログインページを下記に示します。

  1. SPaおよびSPbからの場合
    Password認証フローのための「Username」と「Passowrd」のフォームと「Login」ボタン、およびExtendedフローであるRemoteUser認証フローとX509認証フローのためのボタン「RemoteUser」と「X509」が表示されます。

    「Login」とボタンの形状が同じで紛らわしいですが、Extendedフローを利用する場合は上部のフォーム(「Username」と「Passowrd」)の入力は不要です。


  2.  SPcからの場合
    ExtendedフローであるRemoteUser認証フローとX509認証フローのためのボタン「RemoteUser」と「X509」が表示されます。Level1のPassword認証フローは表示されません。
  3. SPdからの場合
    ExtendedフローのうちLevel3以上であるX509認証フローのためのボタン「X509」が表示されます。Level1のPassword認証フロー、およびLevel2のX509認証フローは表示されません。

参考

高度な認証フローを設定する上で、参考になるドキュメントを下記に示します。

  • No labels