OpenIDを使用した認証サーバーの設定
31095 ワード
This article is part of a series called Setting up an Authorization Server with OpenIddict. The articles in this series will guide you through the process of setting up an OAuth2 + OpenID Connect authorization server on the the ASPNET Core platform using OpenIddict.
ロビンソン / 認証サーバ
OpenIDDictで実装された認証サーバ。
この部分では、我々の認可サーバーのための最小限のセットアップとして機能するASPNETコアプロジェクトを作成します.MVCを使用してページを提供し、基本的なログインフォームを含むプロジェクトに認証を追加します.
新しい空のASPNETプロジェクトを作成します。
前の記事で述べたように、認証サーバーは別のWebアプリケーションです.次のコンテンツは、ユーザー名のパスワードログインでASPNETコアアプリケーションを設定することをご案内します.使用しないほうを選ぶASPNET Core Identity 物事を本当に簡単に保つ.基本的にすべてのユーザー名のパスワードの組み合わせが動作します.
新しいWebアプリケーションの作成から始めましょう
AuthorizationServer
使用ASP.NET Core Empty template :dotnet new web --name AuthorizationServer
我々は、このプロジェクトで動作します、我々はこのガイドでソリューションファイルを追加しません.OpenIDDictは私たちは
https
ローカルで開発しても、プロトコル.ローカル証明書が信頼されるようにするには、次のコマンドを実行しなければなりません.dotnet dev-certs https --trust
Windowsでは、証明書ストアとOSX上の証明書がキーチェーンに追加されます.Linuxでは、distrosを通して証明書を信頼する標準的な方法はありません.この主題についてもっと読んでくださいHanselman's blog article .すべての期待通りに動作するアプリケーションを起動します
dotnet run --project AuthorizationServer
訪問https://localhost:5001 . あなたはHello World!
あなたのブラウザで.MVC
ASPNETコア空のテンプレートに基づいたプロジェクトを作成しました.これは非常に最小限のテンプレートです.私は意図的にこれをしました、私が物事をはっきりさせて、単純にしておくためにできるだけ私のプロジェクトで少しの『雑音』を持つのが好きであるので.
このテンプレートの使用の欠点はMVC 我々自身.まず、MVCを変更することによって
Startup.cs
クラスusing Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace AuthorizationServer
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
}
}
MVCは、呼び出しによって構成されますservices.AddControllersWithViews()
. エンドポイントはデフォルトルーティングを使用する設定です.また、静的ファイルの提供を有効にして、WWWRootフォルダーからスタイルシートを提供する必要があります.さて、コントローラ、ビュー、ビューモデルを作成しましょう.プロジェクトフォルダ内の次のフォルダ構造を追加します.
/Controllers
/Views
/Views/Home
/Views/Shared
/ViewModels
/wwwroot
/wwwroot/css
レイアウト
最初の項目は、レイアウトファイル
_Layout.cshtml
にViews/Shared
フォルダ.このファイルは、アプリケーションの一般的なレイアウト、および負荷を定義しますBootstrap とjnからのjQuery.jQueryはブートストラップの依存性です.<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"/>
<title>OpenIddict - Authorization Server</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="~/css/site.css"/>
</head>
<body>
<div class="container-sm mt-3">
<div class="row mb-3">
<div class="col text-center">
<h1>
Authorization Server
</h1>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-8 col-xl-4 offset-md-2 offset-xl-4 text-center mb-3">
@RenderBody()
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
</body>
</html>
レイアウトとビューの作業には、\Views
フォルダ_ViewStart.cshtml
@{
Layout = "_Layout";
}
_ViewImports.cshtml
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
のホームページ
基本を加える
HomeController
に/Controllers
フォルダには、ホームページを提供する唯一の目的があります.using Microsoft.AspNetCore.Mvc;
namespace AuthorizationServer.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
}
追加Index.cshtml
にViews/Home
HomeControllerが提供するフォルダ<h2>MVC is working</h2>
スタイルシート
最後に、少なくとも、我々はいくつかのスタイリングが必要です.スタイルシートを追加する
site.css
にwwwroot\css
フォルダ:focus {
outline: 0 !important;
}
.input-validation-error {
border: 1px solid darkred;
}
form {
width: 100%;
}
.form-control {
border:0;
border-radius: 0;
border-bottom: 1px solid lightgray;
font-size:0.9rem;
}
.form-control:focus{
border-bottom-color: lightgray;
box-shadow: none;
}
.form-control.form-control-last {
border-bottom: 0;
}
.form-control::placeholder {
opacity: 0.6;
}
.form-control.input-validation-error {
border: 1px solid darkred;
}
いくつかのスタイル規則は、後に作成するログインフォームを予想するスタイルシートに既に追加されています.SASSを使ったり、SASSとブートストラップをカスタマイズしたい場合は、ASSNETでブートストラップのSASSを設定してください.
アプリケーションを実行し、すべてが動作しているかどうかを確認してください.
認証を有効にする
ASP .ネットコアauthentication は
IAuthenticationService
. 認証サービスは認証ハンドラを使用して認証関連のアクションを完了します.認証ハンドラは起動時に登録され、設定オプションは「scheme」と呼ばれます.認証方式は認証サービスを登録することによって指定される
Startup.ConfigureServices
.このプロジェクトについてはcookie authentication , そこで、クッキー認証スキームを
ConfigureServices
メソッドStartup.cs
:public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = "/account/login";
});
}
ログインパスは/account/login
, 我々はすぐにこのエンドポイントを実装します.認証された認証方式を使用する認証ミドルウェアは
UseAuthentication
アプリケーションの拡張方法IApplicationBuilder
:app.UseRouting();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
への呼び出しUseAuthentication
への呼び出しの後に作られますUseRouting
, 経路情報が認証決定のために利用可能であるようにUseEndpoints
, ユーザがエンドポイントにアクセスする前に認証されるようにします.ログインページ
認証が有効になったので、ユーザを認証するログインページが必要になります.
まず、ユーザーを認証するために必要な情報を含むログインビューモデルを作成します.必ずこのファイルを
ViewModels
フォルダusing System.ComponentModel.DataAnnotations;
namespace AuthorizationServer.ViewModels
{
public class LoginViewModel
{
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
public string ReturnUrl { get; set; }
}
}
フォルダを作成するAccount
にViews
フォルダとログインビューを追加します.Login.cshtml
, ログインフォームを含む@model AuthorizationServer.ViewModels.LoginViewModel
<form autocomplete="off" asp-route="Login">
<input type="hidden" asp-for="ReturnUrl"/>
<div class="card">
<input type="text" class="form-control form-control-lg" placeholder="Username" asp-for="Username" autofocus>
<input type="password" class="form-control form-control-lg form-control-last" placeholder="Password" asp-for="Password">
</div>
<p>
<button type="submit" class="btn btn-dark btn-block mt-3">Login</button>
</p>
</form>
最後にAccountController
:using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using AuthorizationServer.ViewModels;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace AuthorizationServer.Controllers
{
public class AccountController : Controller
{
[HttpGet]
[AllowAnonymous]
public IActionResult Login(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model)
{
ViewData["ReturnUrl"] = model.ReturnUrl;
if (ModelState.IsValid)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, model.Username)
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(new ClaimsPrincipal(claimsIdentity));
if (Url.IsLocalUrl(model.ReturnUrl))
{
return Redirect(model.ReturnUrl);
}
return RedirectToAction(nameof(HomeController.Index), "Home");
}
return View(model);
}
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync();
return RedirectToAction(nameof(HomeController.Index), "Home");
}
}
}
だから、ここで何が起こる?アカウントコントローラに2つのログインアクション(GETとPOST)があります.
get actionは、作成したログインフォームを提供します.オプションのクエリパラメータがあります.
returlUrl
どの店にViewData
, それで、我々は成功したログインの後、ユーザーをリダイレクトするためにこれを使うことができます.ポストアクションはもっと面白い.ファースト
ModelState
が有効です.つまり、ユーザ名とパスワードが必要です.ここでは資格情報をチェックしません.この例ではどんな組み合わせも有効です.通常、これはあなたのデータベースに対する資格情報をチェックする場所です.モデル状態が有効な場合、クレームIDが構築されます.ユーザーの名前を1つ追加します.注意してください、我々はクッキー認証方式を指定します
CookieAuthenticationDefaults.AuthenticationScheme
) クレームアイデンティティを作成するとき.これは基本的に文字列で、Startup.cs
クッキー認証を設定するときのクラス.The
SignInAsync
メソッドは、CookieAuthenticationHandlerを呼び出すAuthenticationServiceを呼び出す拡張メソッドです.これは、クレームIDの作成時に指定したスキームです.サインをした後に、ユーザをリダイレクトする必要があります.戻りURLが指定された場合、ローカルURLであるかどうかを確認しますprevent open redirect attacks リダイレクトする前に.さもなければ、ユーザはホームページにリダイレクトされます.
最後のアクションログアウトは、認証サービスをユーザに署名するよう要求します.認証サービスは、認証ミドルウェア、我々のケースでは、クッキー認証ミドルウェアを呼び出すと、ユーザーを署名する.
ホームページ更新
ホームページを更新
Views/Home/Index.cshtml
):@using Microsoft.AspNetCore.Authentication
@if (User.Identity.IsAuthenticated)
{
var authenticationResult = await Context.AuthenticateAsync();
var issued = authenticationResult.Properties.Items[".issued"];
var expires = authenticationResult.Properties.Items[".expires"];
<div>
<p>You are signed in as</p>
<h2>@User.Identity.Name</h2>
<hr/>
<dl>
<dt>Issued</dt>
<dd>@issued</dd>
<dt>Expires</dt>
<dd>@expires</dd>
</dl>
<hr/>
<p><a class="btn btn-dark" asp-controller="Account" asp-action="Logout">Sign out</a></p>
</div>
}
@if (!User.Identity.IsAuthenticated)
{
<div>
<p>You are not signed in</p>
<p><a class="btn btn-sm btn-dark" asp-controller="Account" asp-action="Login">Sign in</a></p>
</div>
}
ユーザーが認証されるならば、我々はユーザー名、現在のセッションに関する情報とサインアウトボタンを示します.ユーザーが認証されていない場合は、ログインフォームにユーザーをナビゲートする記号インボタンを表示します.アプリケーションを起動するには、ホームページの「ボタン」ボタンを参照してください.
クリックするとき
Sign in
ログインフォームに移動します.サインをするには、ちょうどランダムな資格情報、すべての空の値を記入する罰金です.
すべてが正しく動作するならば、あなたはあなたがサインされることを示すホームページにリダイレクトされなければなりません:
次
現在、我々は基本的なASPNETコアプロジェクトを認証を実行して実行している、これまでのところファンシーはありません.OpenIDDictをプロジェクトに追加し、クライアントの資格情報の流れを実装します.
Reference
この問題について(OpenIDを使用した認証サーバーの設定), 我々は、より多くの情報をここで見つけました https://dev.to/robinvanderknaap/setting-up-an-authorization-server-with-openiddict-part-ii-create-aspnet-project-4949テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol