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 UserManager _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();
Identity Server 4 配置
根目錄下新增 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.




留言
張貼留言