ASP.NET Core에서 검색을 사용하지 않고 빈 항목에서 Identity 구현

ASP.NET Core가 필요한 건 없을 것 같아서 잠시 올려놓자Qita에도 같은 글이 있어요..

개시하다


인증 및 인증 메커니즘은 ASP입니다.NET Core의 인증을 사용하기 위해 어떤 템플릿과 스캐너는 항상 사용되고 있다고 생각하지만, 머리를 빈 항목에서 정리하기 위해 가능한 한 Identity를 가져와 보았습니다.
이 글은 시연용이어서 메일을 확인하지 않았고 비밀번호 제한도 느슨했다.
또 제가 인증·인정 전문가가 아니기 때문에 고려하지 못한 부분도 많다고 생각합니다.

빈 프로젝트 만들기


먼저 템플릿에서 ASP.NET Core(비어 있음)를 선택합니다.

운영 후 https://localhost:5001/ Hello World 액세스!나타나다

여기까지의 코드는요.
https://github.com/tatsuteb/IdentityFromEmpty/tree/v0.1
https://github.com/tatsuteb/IdentityFromEmpty/releases/tag/v0.1

MVC 가져오기 및 경로 보호


뷰 생성하기


다음https://localhost:5001/[컨트롤러 이름]/[작업 이름]에 방문할 수 있습니다.
StartUp.cs의 Configure Services에 컨트롤러 보기 서비스를 추가합니다.
StartUp.cs
services.AddControllersWithViews();
그런 다음 Configure의 UseEndpoint 내의 라우팅 설정은 다음과 같습니다.
StartUp.cs
endpoints.MapDefaultControllerRoute();
이렇게 하면 컨트롤러와 보기를 사용하여 페이지를 만들 수 있기 때문에 메인 화면과 ProtedView 화면을 만들 수 있다.
ProtedView 화면은 로그인할 때만 액세스할 수 있는 화면으로 예약됩니다.
Views/Home 폴더에 Index가 있습니다.cshtml、ProtectedView.cshtml 제작.
Views/Home/Index.cshtml
<h2>Home</h2>
Views/Home/ProtectedView.cshtml
<h2>Protected View</h2>
그리고 태그 조수를 사용할 예정이기 때문에ViewImports.cshtml 사전 수입 준비.
Views/_ViewImports.cshtml
@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers
항상 표시되는 전체 페이지의 눈썹을 레이아웃에 놓고 싶기 때문에Layout.cshtml 준비ViewStart.cs로 설정합니다.
@RenderBody()는 URL을 기준으로 뷰를 확장합니다.
Views/Shared/_Layout.cshtml
<header>
    <nav>
        <h1>AppWithIdentity</h1>
        <a asp-controller="Home" asp-action="Index">Home</a>
        <a asp-controller="Home" asp-action="ProtectedView">ProtectedView</a>
    </nav>
</header>

<main>
    @RenderBody()
</main>
Views/_ViewStart.cshtml
@{
    Layout = "_Layout";
}
Controllers 폴더에 Home Controller를 생성하여 각 뷰에 맞는 방법을 준비합니다.
Controllers/HomeController.cs
public IActionResult Index()
{
    return View();
}

public IActionResult ProtectedView()
{
    return View();
}
실행 가능 여부를 확인하고 액세스합니다.
메인 화면

ProtedView 화면

ProtedView 보호


https://localhost:5001/Home/ProtectedView에 대한 액세스를 보호해 보십시오.
Home Controller의 ProtedView에 Authorize 속성을 추가하여 동작을 관찰합니다.
Controllers/HomeController.cs
[Authorize]
public IActionResult ProtectedView()
{
    return View();
}

Authorization 서비스를 활성화하는 동안 오류가 발생하여 액세스할 수 없습니다.
여기까지의 코드는요.
https://github.com/tatsuteb/IdentityFromEmpty/tree/v0.2
https://github.com/tatsuteb/IdentityFromEmpty/releases/tag/v0.2

Identity 가져오기


방금 잘못된 정보에 따라 StartUp.cs를 사용하여 Authorization에 다시 액세스합니다.
app.UseAuthorization은 app입니다.UseRouting() 및 appUseEndpoint() 사이에 씁니다.
StartUp.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
	app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseAuthorization(); // 追加

    app.UseEndpoints(endpoints =>
    {
	endpoints.MapDefaultControllerRoute();
    });
}

인증 방법을 모르는 오류가 발생했습니다.
여기서부터 Identity를 가져옵니다.
먼저 Identity에서 사용할 DB를 준비합니다.이번에는 시연이기 때문에 번거로움을 줄이기 위해 메모리 내의 데이터베이스를 사용해야 한다.
Data 폴더에 Identity DbContext〃Identity User&를 상속하는 AppIdentity DbContext 클래스를 만듭니다.
Data/AppIdentityDbContext.cs
public class AppIdentityDbContext : IdentityDbContext<IdentityUser>
{
    public AppIdentityDbContext(DbContextOptions options) : base(options)
    {
    }
}
StartUp이 작성한 데이터베이스 컨텍스트입니다.DI는 cs의 Configure Services에서 사용됩니다.
StartUp.cs
services.AddDbContext<AppIdentityDbContext>(options =>
    options.UseInMemoryDatabase("identityDb"));
그런 다음 Identity 서비스를 추가합니다.
이번에는 시위 행진이어서 규제 완화를 설정했다.
또 로그인 경로 등이 기본 설정이며 변경하려면 Configuure Application 쿠키를 통해 변경할 수 있다.
StartUp.cs
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
    // デモ用に制約を緩めに設定
    if (_environment.IsDevelopment())
    {
	options.User.RequireUniqueEmail = true;

	options.Password.RequireDigit = false;
	options.Password.RequireLowercase = false;
	options.Password.RequireUppercase = false;
	options.Password.RequireNonAlphanumeric = false;
    }

    // その他いろいろ設定できる
    // options.SignIn.RequireConfirmedAccount = true;
    // options.SignIn.RequireConfirmedEmail = true;
    // options.SignIn.RequireConfirmedPhoneNumber = true;
})
.AddDefaultTokenProviders()
.AddEntityFrameworkStores<AppIdentityDbContext>();

// ログイン画面等のパスを変えたい場合はここで指定できる
// services.ConfigureApplicationCookie(config =>
// {
//     config.LoginPath = "/Login";
//     config.LogoutPath = "/Logout";
//     config.AccessDeniedPath = "/AccessDenied";
// });
다음은 StartUp 입니다.cs의 Configure에서 Use Authentication () 이라고 하는데, Authentication 서비스를 사용할 수 있습니다.
StartUp.cs
// 省略
app.UseRouting();

app.UseAuthentication(); // 追加
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapDefaultControllerRoute();
});
액세스를 시도해 보십시오https://localhost:5001/Home/ProtectedView.

기본 로그인 화면https://localhost:5001/Account/Login으로 방향을 변경합니다.
조회 ReturnUrl은 로그인 후 이동할 URL을 자동으로 설정합니다.
이후 User Manager와 Sign InManager를 사용하여 계정, 로그인, 로그아웃 구조를 만듭니다.
여기까지의 코드는요.
https://github.com/tatsuteb/IdentityFromEmpty/tree/v0.3
https://github.com/tatsuteb/IdentityFromEmpty/releases/tag/v0.3

새로 만들기, 로그인, 로그아웃


Views/Accent 폴더의 Register.cshtml、Login.cshtml을 준비하고 입력 창을 만듭니다.
그런 다음 Acount Controller가 Controller 폴더로 이동합니다.cs를 만들고 모든 보기에 해당하는 방법을 제공합니다.
로그아웃 처리 후 메인 화면으로 이동하기 때문에 보기를 준비하지 않았습니다.

설치 전선이 길어집니다. GiitHub을 확인하십시오.
Views/Accent 폴더
AccountController.cs
다음에 사용자가 생성, 로그인, 로그아웃하는 처리를 준비합니다.
여기도 길어지니까 일부를 발췌해 싣겠다.
UserManager의 CreateAsync를 사용하여 생성할 수 있습니다.
Controllers/AccountController.cs
[HttpPost]
public async Task<IActionResult> Register([FromForm]Register model, string returnUrl)
{
    // 省略
    var createUserResult = await _userManager.CreateAsync(
        user: user,
        password: model.Password);
    // 省略
}
Sign InManager를 사용하는 PasswordSign InAsync에 로그인합니다.
Controllers/AccountController.cs
[HttpPost]
public async Task<IActionResult> Login([FromForm]Login model, string returnUrl)
{
    // 省略

    var user = await _userManager.FindByEmailAsync(model.Email);

    var signInResult = await _signInManager.PasswordSignInAsync(
        user: user,
        password: model.Password,
        isPersistent: model.RememberMe,
        lockoutOnFailure: false);

    if (!signInResult.Succeeded)
    {
        throw new Exception("ログインに失敗しました。");
    }
	
    // 省略
}
SignInManager를 사용하는 SignOutAsync를 로그아웃합니다.
Controllers/AccountController.cs
public async Task<IActionResult> Logout()
{
    await _signInManager.SignOutAsync();

    return RedirectToAction(actionName: "Index", controllerName: "Home");
}
그럼 한번 해볼게요.
우선 메인 화면입니다.지금은 Identity의 쿠키가 없습니다.

ProtedView를 클릭하면 로그인 화면으로 리디렉션됩니다.

계정을 만들지 않았기 때문에 화면 아래의'새 등록'을 클릭하여 새 등록 화면으로 이동합니다

계정을 생성하는 동안 ProtedView 화면으로 리디렉션됩니다.
ProtedView 화면이 표시되고 오른쪽 위 모서리에 사용자 이름이 표시되는지 확인할 수 있습니다.아이덴티티를 알 수 있는 쿠키도 제작됐다.

화면 오른쪽 상단의 로그아웃을 클릭하면 Identity의 쿠키를 삭제합니다.
사용자 이름도 사라지고 메뉴도 로그인 전 상태로 돌아갑니다.
여기까지의 코드는요.
https://github.com/tatsuteb/IdentityFromEmpty/tree/v0.1
https://github.com/tatsuteb/IdentityFromEmpty/releases/tag/v0.4

최후


최소한의 코드부터 단계적으로 Identity를 가져와 이해를 조금 더 깊게 했다.
다음은 IdentityServer4를 사용한 싱글 서명에 도전하고 싶습니다.
창고는 여기 있어요.
https://github.com/tatsuteb/IdentityFromEmpty

외국 편


HttpContext의 SignInAsync를 사용하여 Identity를 사용하지 않고 보호된 페이지에 액세스합니다.
StartUp.cs의 쿠키 인증 서비스를 사용합니다.
StartUp.cs
public void ConfigureServices(IServiceCollection services)
{
    // デモ用に適当なユーザーストアを用意する
    var store = new Dictionary<string, string>();
    services.AddSingleton(store);
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            // ログイン画面等のパスを変えたいときはここで設定する
            // options.AccessDeniedPath = "/AccessDenied";
            // options.LoginPath = "/Login";
            // options.LogoutPath = "/Logout";
        });
	
    // 省略
}
	
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 省略

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
	endpoints.MapDefaultControllerRoute();
    });
}
HttpContext의 SignInAssync, SignOutAsync를 사용하여 로그인하고 로그아웃합니다.
프레젠테이션용으로 사용되기 때문에 사용자는 프레젠테이션에서 적절하게 유지할 것이다.
Controllers/AccountController.cs
[HttpPost]
public async Task<IActionResult> Login([FromForm]LoginModel model, [FromQuery]string returnUrl)
{
    // 省略

    var claims = new List<Claim>
    {
	new Claim(ClaimTypes.Name, model.Email),
	new Claim(ClaimTypes.Email, model.Email),
    };

    var claimsIdentity = new ClaimsIdentity(
	claims, 
	CookieAuthenticationDefaults.AuthenticationScheme);

    var authProperties = new AuthenticationProperties
    {
	IsPersistent = model.RememberMe,
	RedirectUri = returnUrl
    };

    await HttpContext.SignInAsync(
	CookieAuthenticationDefaults.AuthenticationScheme, 
	new ClaimsPrincipal(claimsIdentity), 
	authProperties);

    return LocalRedirect(returnUrl);
}

public async Task<IActionResult> LogOut()
{
    await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

    return RedirectToAction("Index", "Home");
}
실행한 후 ProtedView를 클릭합니다.
로그인 화면으로 방향을 바꿔야 하기 때문에 '새 등록' 을 누르면 새 로그인 화면으로 이동합니다.

새 로그인이 성공하면 로그인하여 ProtedView 화면으로 방향을 바꿉니다.
쿠키가 생성되면 ProtedView 화면도 잘 나오는지 확인할 수 있습니다.

이 전선 여기 있어요.
https://github.com/tatsuteb/IdentityFromEmpty/tree/feature/AuthWithoutIdentity

좋은 웹페이지 즐겨찾기