Identity Server WebAPI
DAL
安裝所需套件
install-package AutoMapper
新增 Models目錄 新增 ApplicationUser.cs
using Microsoft.AspNetCore.Identity; public class ApplicationUser :IdentityUser { ...新增所需要之欄位 }新增 Models目錄 新增 ApplicationRole.cs
using Microsoft.AspNetCore.Identity; public class ApplicationRole :IdentityRole { ...新增所需要之欄位 }專案目錄下 新增 ApplicationDbContext.cs
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; public class ApplicationDbContext :IdentityDbContext<ApplicationUser,ApplicationRole,string> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); } }新增 專案名稱 IdentityWebAPI 並選擇 API
將DAL 專案加入參考
安裝所需套件
install-package AutoMapper install-package IdentityServer4 install-package IdentityServer4.AccessTokenValidation install-package IdentityServer4.AspNetIdentity install-package Swashbuckle.AspNetCore install-package Serilog.Extensions.Logging.File install-package Microsoft.VisualStudio.Web.CodeGeneration.Design -Version 2.1.0修改 appsettings.json,新增資料庫連結字串
"ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyDbWebApi;Trusted_Connection=True;MultipleActiveResultSets=true" }
加入 Swagger 參考頁面:使用 Swagger 的 ASP.NET Core Web API 說明頁面
開啟 Startup.cs 新增下列 code using Swashbuckle.AspNetCore.Swagger; public void ConfigureServices(IServiceCollection services) { ... services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" }); }); ... } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { ... app.UseSwagger(); // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // specifying the Swagger JSON endpoint. app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); c.RoutePrefix = "swagger"; //在 LocalHost:????/Swagger 顯示 }); ... }CTRL+F5 出現下列畫面
配置 Serial.log
參照 https://github.com/serilog/serilog/wiki/Getting-Started 參照 https://itnext.io/loggly-in-asp-net-core-using-serilog-dc0e2c7d52eb 參照 https://github.com/serilog/serilog-aspnetcore/tree/dev/samples/SimpleWebSample 參照 https://github.com/serilog/serilog/wiki/Configuration-Basics 我們已經準備好實施Serilog。我們將從Program.cs文件開始。 using Serilog; using Serilog.Events; using Serilog.Sinks.SystemConsole.Themes; public class Program { public static void Main(string[] args) { var webHost = BuildWebHost(args); webHost.Run(); } public static IWebHost BuildWebHost(string[] args) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) .MinimumLevel.Override("System", LogEventLevel.Warning) .MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information) .Enrich.FromLogContext() .WriteTo.File(@"identityserver4_log.txt") .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate) .CreateLogger(); return WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .ConfigureLogging(builder => { builder.ClearProviders(); builder.AddSerilog(); }) .Build(); }
加入 AutoMapper
開啟 Startup.cs 新增下列 code Using AddAutoMapper; services.AddAutoMapper(); services.AddMvc(); Now, you just have to create your Mapping profiles. Here is an example of mine: using AutoMapper; public class MappingProfile : Profile { public MappingProfile() { CreateMap() .ForMember(a => a.ModelId, b=> b.MapFrom(c=> c.ModelName)); } }
Identity 配置
using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Identity; services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), b => b.MigrationsAssembly("Your Project Name")));
資料庫建成
add-migration init0708 update-database
using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Identity; // SQLServer & Identity. services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), b => b.MigrationsAssembly("Your Project Name"))); services.AddIdentity<ApplicationUser, ApplicationRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); // Identity options. services.Configure<IdentityOptions>(options => { // Password settings. options.Password.RequireDigit = true; options.Password.RequiredLength = 8; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = true; options.Password.RequireLowercase = false; // Lockout settings. options.Lockout.AllowedForNewUsers = true; options.Lockout.MaxFailedAccessAttempts = 3; options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromDays(1); });參照 https://github.com/robisim74/AngularSPAWebAPI/blob/master/EXPLANATION.md
修改 Satraup.cs 添加相關的服務,SQLite&Identity 放在所有ID4最上層
Seed Data
Data 目錄下新增 DbInitializer.cs public class DbInitializer : IDbInitializer { private readonly UserManagerIdentity Server 4 配置_userManager; private readonly RoleManager _roleManager; public DbInitializer( UserManager<ApplicationUser> userManager, RoleManager<ApplicationRole> roleManager ) { this._userManager = userManager; this._roleManager = roleManager; } public async Task Initialize(ApplicationDbContext context) { context.Database.EnsureCreated(); if (context.Users.Any()) { return; // Db has been seeded. } // Creates Roles. // await _roleManager.CreateAsync(new IdentityRole("administrator")); // await _roleManager.CreateAsync(new IdentityRole("user")); var role = new ApplicationRole { Name = "administrator", Description= "管理者" }; await _roleManager.CreateAsync( role ); var role1 = new ApplicationRole { Name = "user", Description = "使用者" }; await _roleManager.CreateAsync(role1); // Seeds an admin user. var user = new ApplicationUser { GivenName = "Admin", FamilyName = "Admin", AccessFailedCount = 0, Email = "admin@gmail.com", EmailConfirmed = false, LockoutEnabled = true, NormalizedEmail = "ADMIN@GMAIL.COM", NormalizedUserName = "ADMIN@GMAIL.COM", TwoFactorEnabled = false, UserName = "admin@gmail.com" }; var result = await _userManager.CreateAsync(user, "Admin01*"); if (result.Succeeded) { var adminUser = await _userManager.FindByNameAsync(user.UserName); // Assigns the administrator role. await _userManager.AddToRoleAsync(adminUser, "administrator"); // Assigns claims. var claims = new List<Claim> { new Claim(type: JwtClaimTypes.GivenName, value: user.GivenName), new Claim(type: JwtClaimTypes.FamilyName, value: user.FamilyName), }; await _userManager.AddClaimsAsync(adminUser, claims); } } } 創建 Services 目錄 ,新增 IDbInitializer.cs public interface IDbInitializer { Task Initialize(ApplicationDbContext context); } Startup.cs // Adds application services. services.AddTransient (); services.AddTransient ();
根目錄下新增 config.cs 配置 identity4 內容 (尚未完整) using IdentityServer4; using IdentityServer4.Models; // Clients want to access resources. public static IEnumerableGetClients() { // Clients credentials. return new List { // http://docs.identityserver.io/en/release/topics/clients.html // http://docs.identityserver.io/en/release/quickstarts/1_client_credentials.html# new Client { ClientId = "AngularSPA", AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, // Resource Owner Password Credential grant. AllowAccessTokensViaBrowser = true, RequireClientSecret = false, // This client does not need a secret to request tokens from the token endpoint. AccessTokenLifetime = 900, // Lifetime of access token in seconds. AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, // For UserInfo endpoint. IdentityServerConstants.StandardScopes.Profile, "roles", "WebAPI" }, AllowOfflineAccess = true, // For refresh token. RefreshTokenUsage = TokenUsage.OneTimeOnly, AbsoluteRefreshTokenLifetime = 7200, SlidingRefreshTokenLifetime = 900, RefreshTokenExpiration = TokenExpiration.Sliding, AllowedCorsOrigins = new List { "http://localhost:4200" } // Only for development. } }; } 正如你所看到的,你可以用自己的配置添加其他客戶端。我們的Angular應用程序被確定為AngularSPA: 使用ROPC ; 不使用秘密密鑰:在客戶端應用程序將是無用的,因為可見的; 有一個訪問令牌 15分鐘,然後需要刷新令牌; 可以訪問範圍:在這種情況下我們的Web API,稱為WebAPI和用戶角色; 具有用於刷新令牌的OfflineAccess ; 刷新令牌的滑動壽命為15分鐘,最長壽命為2小時:刷新令牌的壽命等於或大於訪問令牌,以允許用戶保持身份驗證狀態,但最多2小時。 以下是資源: // Identity resources (used by UserInfo endpoint). public static IEnumerable GetIdentityResources() { return new List { new IdentityResources.OpenId(), new IdentityResources.Profile(), new IdentityResource("roles", new List { "role" }) }; } // Api resources. public static IEnumerable GetApiResources() { return new List { new ApiResource("WebAPI" ) { UserClaims = { "role" } } }; } 我們在Startup.cs文件的ConfigureServices方法中添加IdentityServer : //添加IdentityServer。 services.AddIdentityServer() // AddDeveloperSigningCredential擴展創建用於簽署令牌的臨時密鑰材料。 //這可能對開始有用,但需要由生產場景的一些持久性密鑰材料替換。 //有關更多信息,請參閱http://docs.identityserver.io/en/release/topics/crypto.html#refcrypto。 .AddDeveloperSigningCredential() .AddInMemoryPersistedGrants() //要將IdentityServer配置為使用EntityFramework(EF)作為配置數據的存儲機制(而不是使用內存中的實現), //請參閱https://identityserver4.readthedocs.io/en/release/quickstarts/8_entity_framework.html .AddInMemoryIdentityResources(Config.GetIdentityResources()) .AddInMemoryApiResources(Config.GetApiResources()) .AddInMemoryClients(Config.GetClients()) .AddAspNetIdentity<ApplicationUser>(); // IdentityServer4.AspNetIdentity.
留言
張貼留言