2

「構成なしのWIF」を試しています。ここでは、WindowsAzureのAppFabricSTSによって生成されたSAML2トークンを受け入れます。

私が行っているのは、次のように、トークン情報の現在の要求を解析してチェックすることです。

        if (Request.Form.Get(WSFederationConstants.Parameters.Result) != null)
        {
            SignInResponseMessage message = 
                WSFederationMessage.CreateFromFormPost(System.Web.HttpContext.Current.Request) as SignInResponseMessage;

            var securityTokenHandlers = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();                    

            XmlTextReader xmlReader = new XmlTextReader(
                new StringReader(message.Result));

            SecurityToken token = securityTokenHandlers.ReadToken(xmlReader);

            if (token != null)
            {
                ClaimsIdentityCollection claims = securityTokenHandlers.ValidateToken(token);
                IPrincipal principal = new ClaimsPrincipal(claims);
            }
        }

上記のコードは、SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();を使用しています。SAMLトークンを検証および処理するためのコレクション。ただし、明らかにアプリケーションが正しく構成されていないため、これは機能しません。securityTokenHandlersコレクションでXMLから次の構成をプログラムで指定するにはどうすればよいですか?

  <microsoft.identityModel>
<service>
  <audienceUris>
    <add value="http://www.someapp.net/" />
  </audienceUris>
  <federatedAuthentication>
    <wsFederation passiveRedirectEnabled="true" issuer="https://rd-test.accesscontrol.appfabriclabs.com/v2/wsfederation" realm="http://www.thisapp.net" requireHttps="false" />
    <cookieHandler requireSsl="false" />
  </federatedAuthentication>
  <applicationService>
    <claimTypeRequired>
      <claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" optional="true" />
      <claimType type="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" optional="true" />
    </claimTypeRequired>
  </applicationService>
  <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
    <trustedIssuers>
      <add thumbprint="XYZ123" name="https://somenamespace.accesscontrol.appfabriclabs.com/" />
    </trustedIssuers>
  </issuerNameRegistry>
</service>

4

3 に答える 3

3

私は同じことに苦労していて、WIF 3.5/4.0で実用的な解決策を見つけました。maartenbaのリンクが切れているように見えるので、ここに解決策を投稿したいと思いました。

要件は次のとおりです。

  • 完全にコードで構成(アプリにデフォルトのweb.configを同梱しているため)
  • 最大許容.Netバージョン4.0(したがって、WIF 3.5 / 4.0を使用しています)

私が解決策にたどり着いたもの:

編集2016/09/02:David Ebboの例のように、個別の「アプリケーション前開始コード」クラスを追加する代わりに、WIF関連のHTTPモジュールを`HttpApplication'クラスの静的コンストラクターに登録することもできます。私はこのややクリーンなソリューションにコードを適合させました。

私のソリューションはweb.configに何も必要ありません。コードの大部分はglobal.asax.csにあります。このサンプルでは、​​構成がハードコーディングされています。

using System;
using System.IdentityModel.Selectors;
using System.Security.Cryptography.X509Certificates;
using System.Web;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Web;

namespace TestADFS
{
  public class SessionAuthenticationModule : Microsoft.IdentityModel.Web.SessionAuthenticationModule
  {
    protected override void InitializePropertiesFromConfiguration(string serviceName)
    {
    }
  }
  public class WSFederationAuthenticationModule : Microsoft.IdentityModel.Web.WSFederationAuthenticationModule
  {
    protected override void InitializePropertiesFromConfiguration(string serviceName)
    {
      ServiceConfiguration = FederatedAuthentication.ServiceConfiguration;
      PassiveRedirectEnabled = true;
      RequireHttps = true;
      Issuer = "https://nl-joinadfstest.joinadfstest.local/adfs/ls/";
      Realm = "https://67px95j.decos.com/testadfs";
    }
  }

  public class Global : HttpApplication
  {
    static Global()
    {
      Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(SessionAuthenticationModule));
      Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(WSFederationAuthenticationModule));
    }

    protected void Application_Start(object sender, EventArgs e)
    {
      FederatedAuthentication.ServiceConfigurationCreated += FederatedAuthentication_ServiceConfigurationCreated;
    }

    internal void FederatedAuthentication_ServiceConfigurationCreated(object sender, Microsoft.IdentityModel.Web.Configuration.ServiceConfigurationCreatedEventArgs e)
    {
      X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
      store.Open(OpenFlags.ReadOnly);
      X509Certificate2Collection coll = store.Certificates.Find(X509FindType.FindByThumbprint, "245537E9BB2C086D3C880982FA86267FBD66B9A3", false);
      if (coll.Count > 0)
        e.ServiceConfiguration.ServiceCertificate = coll[0];
      store.Close();
      AudienceRestriction ar = new AudienceRestriction(AudienceUriMode.Always);
      ar.AllowedAudienceUris.Add(new Uri("https://67px95j.decos.com/testadfs"));
      e.ServiceConfiguration.AudienceRestriction = ar;
      ConfigurationBasedIssuerNameRegistry inr = new ConfigurationBasedIssuerNameRegistry();
      inr.AddTrustedIssuer("6C9B96D90257B65B6F181C2478D869473DC359EA", "http://NL-JOINADFSTEST.joinadfstest.local/adfs/services/trust");
      e.ServiceConfiguration.IssuerNameRegistry = inr;
      e.ServiceConfiguration.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
    }

    protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {
      FederatedAuthentication.WSFederationAuthenticationModule.ServiceConfiguration = FederatedAuthentication.ServiceConfiguration;
    }
  }
}

使用法

私のアプリはasp.netWebFormsで、クラシックパイプラインモードで実行され、フォーム認証とADFSログインをサポートしています。そのため、認証はすべての.aspxページで共有される共通の基本クラスで処理されます。

    protected override void OnInit(EventArgs e)
    {
      if (NeedsAuthentication && !User.Identity.IsAuthenticated)
      {
        SignInRequestMessage sirm = new SignInRequestMessage(
          new Uri("https://nl-joinadfstest.joinadfstest.local/adfs/ls/"),
          ApplicationRootUrl)
        {
          Context = ApplicationRootUrl,
          HomeRealm = ApplicationRootUrl
        };
        Response.Redirect(sirm.WriteQueryString());
      }
      base.OnInit(e);
    }

このコードでApplicationRootUrlは、は「/」で終わるアプリケーションパスです(「/」はクラシックパイプラインモードで重要です)。

混合モードでのログアウトの安定した実装はそれほど簡単ではなかったので、そのためのコードも示したいと思います。技術的には機能しますが、ADFSアカウントからログアウトした直後にIEが再度ログインするという問題があります。

      if (User.Identity.IsAuthenticated)
      {
        if (User.Identity.AuthenticationType == "Forms")
        {
          FormsAuthentication.SignOut();
          Session.Clear();
          Session.Abandon();
          ResetCookie(FormsAuthentication.FormsCookieName);
          ResetCookie("ASP.NET_SessionId");
          Response.Redirect(ApplicationRootUrl + "Default.aspx");
          HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
        else
        {
          FederatedAuthentication.SessionAuthenticationModule.SignOut();
          FederatedAuthentication.SessionAuthenticationModule.DeleteSessionTokenCookie();
          Uri uri = new Uri(ApplicationRootUrl + "Default.aspx");
          WSFederationAuthenticationModule.FederatedSignOut(
            new Uri("https://nl-joinadfstest.joinadfstest.local/adfs/ls/"),
            uri); // 1st url is single logout service binding from adfs metadata
        }
      }

ResetCookie応答Cookieをクリアし、過去の有効期限を設定するヘルパー関数です)

于 2016-09-01T09:48:45.027 に答える
0

考えてみれば、これが機能するかどうかはわかりません。実際のXML(この場合は空です)を取得し、Microsoft.IdentityModel.Configurationのクラスを使用して実行時に変更する方法はありませんか?

または、 SignInRequestMessageを変更することにより、RedirectingToIdentityProviderイベントで、サインイン要求が送信されるときに変更できるXMLの一部を変更できます。

于 2011-02-07T06:25:23.760 に答える
0

参考:解決策を見つけて、ここで説明(およびリンク)されたモジュールに実装しました:http://blog.maartenballiauw.be/post/2011/02/14/Authenticate-Orchard-users-with-AppFabric-Access-Control- Service.aspx

于 2011-02-17T09:06:32.400 に答える