最初の.netコア2 Webアプリケーションの実装を開始しました。残念なことにビジネス要件のために、ユーザーはレガシー・フォーム・ログインを介して認証する必要があり、ユーザー名/パスワードはoracle dbに処理され、ユーザーが認証されるとセッションIDが生成され、起動されたアプリケーションのベースURLに追加されます。非常に古い学校ですが、それは動作します。ClaimsIdentity with .NET Core 2ミドルウェアソリューション
セッションIDが期限切れになるので、私のアプリで検証する必要があります。簡単ですが、私はクエリ文字列から取得したセッションIDをOracle APIに渡します。レスポンスはファーストネーム、ラストネームなどのユーザー情報を含むオブジェクトです。
このAPI呼び出しが正常に完了したら、新しいClaimsIdentityとPrincipalを呼び出し、SignInAsync()メソッドを呼び出します。
私は現在、自分のStartup.csに登録したカスタムミドルウェアでこれを行います。私はこれを通常のLogin Controllerメソッドで扱いますが、アプリケーションにログインがないので、私は他の方法を見ることはできませんが、私が書いたミドルウェアではありません。
public class AuthenticationHandler
{
private readonly RequestDelegate _next;
private HttpService _httpService;
public AuthenticationHandler(RequestDelegate next, HttpService httpService)
{
_httpService = httpService;
_next = next;
}
public async Task Invoke(HttpContext context, [FromServices] HttpService httpService)
{
if (context.Request.Query.Count == 1)
{
var sessionId = context.Request.Query.FirstOrDefault().Value;
var session = await _httpService.ValidateSession(sessionId);
if (!string.IsNullOrEmpty(session?.UserId))
{
var claims = new List<Claim>()
{
new Claim(CustomClaimTypes.UserId, session.UserId),
new Claim(CustomClaimTypes.BuId, session.BuId),
new Claim(CustomClaimTypes.SecurityLevel, session.SecurityLevel)
};
var identity = new ClaimsIdentity(claims, "TNReadyEVP");
var principal = new ClaimsPrincipal(identity);
await Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.SignInAsync(context, principal);
var isIn = principal.Identity.IsAuthenticated;
var isAuthed = (context.User.Identity as ClaimsIdentity).IsAuthenticated;
await _next.Invoke(context);
}
else
{
Terminate(context);
}
}
return;
}
private async void Terminate(HttpContext context)
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Invalid User");
return;
}
}
public static class MiddlewareExtensions
{
public static IApplicationBuilder ValidateSession(this IApplicationBuilder builder)
{
return builder.UseMiddleware<AuthenticationHandler>();
}
}
これまでのところ、これは正しい解決策だと私は信じています。しかし、私は私のアプリでは、以下のように、クレームは空であり、User.Identity.Authenticatedはfalseである小さなAPIを介してクレームを取得しようとするとfalseです。
私はここで何が欠けていますか?アドバイスをありがとう、これは私が前に対処していなかったそれらの奇妙なエッジケースの一つです...したがって、カスタムミドルウェアの必要性。
[HttpGet("claims")]
public async Task<IEnumerable<Claim>> Get()
{
var claims = (User as ClaimsPrincipal).Claims;
return await Task.FromResult(claims);
}
詳細については、あなたは非常に有効な点を作っています。私が昨晩実験していたように、ミドルウェアを設計していない場合にミドルウェアを動作させようとしていたという結論に達しました。 CookieAuthenticationHandlerのドキュメントを確認し、これも調べてみましょう:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?tabs=aspnetcore2x 私は基本的に大量のコードを持っています準備ができて、ただリファクタリングする必要があります。いくつかの他のエッジケースがあります。特定のURLパスがヒットしたときに認証プロバイダを起動するだけですが、それ以外にも良いスタートがあると思います...ありがとう! –