持續努力,現在進入第三篇了!!,第三篇我們先以完成為目標,所以小弟先不在這邊講Code的內容了,這部份未來再補上。
TenantDbContext.cs的內容為:
using System; using System.Data.Entity; namespace WebApplication2.Models { public class TenantDbContext : DbContext { public TenantDbContext() : base("DefaultConnection") { } public DbSet<IssuingAuthorityKey> IssuingAuthorityKeys { get; set; } public DbSet<Tenant> Tenants { get; set; } } }
TenantRegistrationModels.cs的內容為:
using System; using System.Collections.Generic; using System.Linq; namespace WebApplication2.Models { public class IssuingAuthorityKey { public string Id { get; set; } } public class Tenant { public string Id { get; set; } } }
接著,我們要建立一個Utils的目錄,然後建立一個DatabaseIssuerNameRegistry.cs檔案。
DatabaseIssuerNameRegistry.cs的內容為:
using System; using System.Collections.Generic; using System.IdentityModel.Tokens; using System.Linq; using System.Runtime.CompilerServices; using System.Web; using System.Web.Hosting; using System.Xml.Linq; using WebApplication2.Models; namespace WebApplication2.Utils { public class DatabaseIssuerNameRegistry : ValidatingIssuerNameRegistry { public static bool ContainsTenant(string tenantId) { using (TenantDbContext context = new TenantDbContext()) { return context.Tenants .Where(tenant => tenant.Id == tenantId) .Any(); } } public static bool ContainsKey(string thumbprint) { using (TenantDbContext context = new TenantDbContext()) { return context.IssuingAuthorityKeys .Where(key => key.Id == thumbprint) .Any(); } } public static void RefreshKeys(string metadataLocation) { IssuingAuthority issuingAuthority = ValidatingIssuerNameRegistry.GetIssuingAuthority(metadataLocation); bool newKeys = false; bool refreshTenant = false; foreach (string thumbprint in issuingAuthority.Thumbprints) { if (!ContainsKey(thumbprint)) { newKeys = true; refreshTenant = true; break; } } foreach (string issuer in issuingAuthority.Issuers) { if (!ContainsTenant(GetIssuerId(issuer))) { refreshTenant = true; break; } } if (newKeys || refreshTenant) { using (TenantDbContext context = new TenantDbContext()) { if (newKeys) { context.IssuingAuthorityKeys.RemoveRange(context.IssuingAuthorityKeys); foreach (string thumbprint in issuingAuthority.Thumbprints) { context.IssuingAuthorityKeys.Add(new IssuingAuthorityKey { Id = thumbprint }); } } if (refreshTenant) { foreach (string issuer in issuingAuthority.Issuers) { string issuerId = GetIssuerId(issuer); if (!ContainsTenant(issuerId)) { context.Tenants.Add(new Tenant { Id = issuerId }); } } } context.SaveChanges(); } } } private static string GetIssuerId(string issuer) { return issuer.TrimEnd('/').Split('/').Last(); } protected override bool IsThumbprintValid(string thumbprint, string issuer) { return ContainsTenant(GetIssuerId(issuer)) && ContainsKey(thumbprint); } } }
接下來,我們要在App_Start底下新增IdentityConfig.cs檔案。
IdentityConfig.cs的內容為:
using System; using System.Collections.Generic; using System.Configuration; using System.IdentityModel.Claims; using System.IdentityModel.Services; using System.Linq; using System.Web.Helpers; using WebApplication2.Utils; namespace WebApplication2 { // 如需 ASP.NET Identity 的詳細資訊,請造訪 http://go.microsoft.com/fwlink/?LinkId=301863 public static class IdentityConfig { public static string AudienceUri { get; private set; } public static string Realm { get; private set; } public static void ConfigureIdentity() { RefreshValidationSettings(); // 設定應用程式領域 Realm = ConfigurationManager.AppSettings["ida:realm"]; // 設定應用程式 audienceUri AudienceUri = ConfigurationManager.AppSettings["ida:AudienceUri"]; if (!String.IsNullOrEmpty(AudienceUri)) { UpdateAudienceUri(); } AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name; } public static void RefreshValidationSettings() { string metadataLocation = ConfigurationManager.AppSettings["ida:FederationMetadataLocation"]; DatabaseIssuerNameRegistry.RefreshKeys(metadataLocation); } public static void UpdateAudienceUri() { int count = FederatedAuthentication.FederationConfiguration.IdentityConfiguration .AudienceRestriction.AllowedAudienceUris.Count( uri => String.Equals(uri.OriginalString, AudienceUri, StringComparison.OrdinalIgnoreCase)); if (count == 0) { FederatedAuthentication.FederationConfiguration.IdentityConfiguration .AudienceRestriction.AllowedAudienceUris.Add(new Uri(IdentityConfig.AudienceUri)); } } } } 接下來,我們要在Global.asax裡面加入註冊使用上面的IdentityConfig。
加入IdentityConfig.ConfigureIdentity();
void Application_Start(object sender, EventArgs e) { // 應用程式啟動時執行的程式碼 AreaRegistration.RegisterAllAreas(); IdentityConfig.ConfigureIdentity(); GlobalConfiguration.Configure(WebApiConfig.Register); RouteConfig.RegisterRoutes(RouteTable.Routes); }
最後,我們有用到DB,所以還是要補一下連線字串;這邊小弟我是使用LocalDB,大家也可以建立自己想要的DB位置。
<connectionStrings> <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WebApplication1-20140901114034.mdf;Initial Catalog=aspnet-WebApplication1-20140901114034;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>
完成之後,你會發現,使用HTTPS時,就會要求先使用Azure來登入帳號了~~
以上!!