آرمان
آرمان
خواندن ۲ دقیقه·۴ سال پیش

سفارشی کردن Identity Server4

سلام در مطلب قبلی نحوه سفارشی کردن UI یا همان رابط کاربری Identity Server گفتم:

https://virgool.io/@espiar/%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%DB%8C-%DA%A9%D8%B1%D8%AF%D9%86-identityserver4-ui-vyyncneeck6b

در این مطلب می خواهم خود کلاس هاش را سفارشی کنیم. من فرض میکنم که شما یک پروژه Blazor Webassembly با Individual user account (که Authentication پیش فرض هست) ساختید.


مرحله اول: ساخت ApiAuthorizationDbContext سفارشی

اول از همه باید یک کلاس سفارشی DbContext بسازیم. من نام آن را CustomApiAuthorizationDbContext میگذارم. و کد زیر را درونش قرار میدهم:

از اونجایی که ویرگول مثل همیشه با کد ها مشکل داره و این کد بسیار طولانی هست در تگ کد قرار نمیدهم!

نکته مهمی

که وجود دارد این هست که کدی که در منبع این مطلب هست ساده ترین کد است اما کدی که اینجا نوشتم کامل ترین حالت هست که باید هر 8 کلاس سفارشی بشود.


شروع کد



using System;

using System.Collections.Generic;

using System.Text;

using System.Threading.Tasks;

using IdentityServer4.EntityFramework.Entities;

using IdentityServer4.EntityFramework.Extensions;

using IdentityServer4.EntityFramework.Interfaces;

using IdentityServer4.EntityFramework.Options;

using Microsoft.AspNetCore.Identity;

using Microsoft.AspNetCore.Identity.EntityFrameworkCore;

using Microsoft.EntityFrameworkCore;

using Microsoft.Extensions.Options;

namespace InfoFinder.Infrastructure.Data.Data

{

/// <summary>

/// Database abstraction for a combined <see cref="DbContext"/> using ASP.NET Identity and Identity Server.

/// </summary>

/// <typeparam name="TUser"></typeparam>

/// <typeparam name="TRole"></typeparam>

/// <typeparam name="TKey">Key of the IdentityUser entity</typeparam>

public class KeyApiAuthorizationDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> : IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>, IPersistedGrantDbContext

where TUser : IdentityUser<TKey>

where TRole : IdentityRole<TKey>

where TKey : IEquatable<TKey>

where TUserClaim : IdentityUserClaim<TKey>

where TUserRole : IdentityUserRole<TKey>

where TUserLogin : IdentityUserLogin<TKey>

where TRoleClaim : IdentityRoleClaim<TKey>

where TUserToken : IdentityUserToken<TKey>

{

private readonly IOptions<OperationalStoreOptions> _operationalStoreOptions;

/// <summary>

/// Initializes a new instance of <see cref="ApiAuthorizationDbContext{TUser, TRole, TKey}"/>.

/// </summary>

/// <param name="options">The <see cref="DbContextOptions"/>.</param>

/// <param name="operationalStoreOptions">The <see cref="IOptions{OperationalStoreOptions}"/>.</param>

public KeyApiAuthorizationDbContext(

DbContextOptions options,

IOptions<OperationalStoreOptions> operationalStoreOptions)

: base(options)

{

_operationalStoreOptions = operationalStoreOptions;

}

/// <summary>

/// Gets or sets the <see cref="DbSet{PersistedGrant}"/>.

/// </summary>

public DbSet<PersistedGrant> PersistedGrants { get; set; }

/// <summary>

/// Gets or sets the <see cref="DbSet{DeviceFlowCodes}"/>.

/// </summary>

public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }

Task<int> IPersistedGrantDbContext.SaveChangesAsync() => base.SaveChangesAsync();

/// <inheritdoc />

protected override void OnModelCreating(ModelBuilder builder)

{

base.OnModelCreating(builder);

builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value);

}

}

/// <summary>

/// Database abstraction for a combined <see cref="DbContext"/> using ASP.NET Identity and Identity Server.

/// </summary>

/// <typeparam name="TUser"></typeparam>

public class ApiAuthorizationDbContext<TUser> : KeyApiAuthorizationDbContext<TUser, IdentityRole, string, IdentityUserClaim<string>, IdentityUserRole<string>, IdentityUserLogin<string>, IdentityRoleClaim<string>, IdentityUserToken<string>>

where TUser : IdentityUser

{

/// <summary>

/// Initializes a new instance of <see cref="ApiAuthorizationDbContext{TUser}"/>.

/// </summary>

/// <param name="options">The <see cref="DbContextOptions"/>.</param>

/// <param name="operationalStoreOptions">The <see cref="IOptions{OperationalStoreOptions}"/>.</param>

public ApiAuthorizationDbContext(

DbContextOptions options,

IOptions<OperationalStoreOptions> operationalStoreOptions)

: base(options, operationalStoreOptions)

{

}

}

}


پایان کد



مرحله دوم ساخت کلاس های سفارشی

کلاس های زیر کلاس های سفارشی Identity معمولی می باشد:

TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken

که سفارشی کردنشو در پست پایین و منبع آمده (البته منبع کامل تر هست)

https://virgool.io/@espiar/%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%DB%8C-%DA%A9%D8%B1%D8%AF%D9%86-identity-%D8%AF%D8%B1-dotnetcore31-idbh9ahawqvh

مرحله سوم جایگزین کردن Context سفارشی که در مرحله اول ساختیم بجای Context پیشفرض

بعد باید dbContext سفارشی خودمان را جایگزین dbContext پیش فرض کنیم و 8 کلاس سفارشی هم به آن پاس بدیهم:


مرحله چهارم تغییر فایل Startup

حالا باید کلاس های سفارشی را در فایل Stratup به Identity پاس دهیم:

کلاس های ApplicationUser و ApplicationRole سفارشی من هستند که به Services.AddDefaultIdentity پاس دادم
کلاس های ApplicationUser و ApplicationRole سفارشی من هستند که به Services.AddDefaultIdentity پاس دادم


تنها خطی که فایل startup اضافه شد کد زیر هست:

.AddRoles<ApplicationRole>()

باقس کد بطور پیشفرض وجود دارد فقط باید نام کلاس سفارشی جایگزین کنید.

نکته: نام کلاس سفارشی user من ApplicationUser هست. که بطور پیشفرض این کلاس سفارشی (و البته خالی) وجود دارد.

و مرحله پنجم و آخر

ابتدا Migration ها رو پاک می کنیم و بعد اگر دیتابیس ساخته شده آن هم پاک میکنیم.

و دستورات زیر را میزنیم:

Add-Migration MigrationName
Update-Database

دستورات بالا که پرواضح و برای EntityFramework هست. این دستورات باید بدون خطا انجام شوند در غیر این صورت جاییرو مثل این مطلب پیش نرفتید.


منابع:

https://stackoverflow.com/questions/58208894/aspnet-core-identity-custom-apiauthorizationdbcontext

و

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-3.1#customize-the-model


Identity Serverسفارشی سازی
یک برنامه نویس که هرآنچه را که یاد میگیرد در دفترچه یادداشت ویرگولیش یادداشت میکرد(!) حتی یک خط ! تا درصورت نیاز به آن رجوع کند...
شاید از این پست‌ها خوشتان بیاید