1

私の会社にカスタム "認証"を実装する必要があります。 私は引用符で囲みます。ユーザがアプリケーションにヒットする前に技術的に認証され、そうであればuserIdがリクエストヘッダに存在するからです。クッキー認証を使用するASP.NET Core 2.0カスタムミドルウェア

私がする必要があるのは、データベースにクエリを行い、そのIDに基づいて追加のユーザー情報を取得し、アプリケーション内で簡単に使用できるようにHttpContext.Userオブジェクトを設定する方法です。

ここでは、ASP.NET Core IdentityなしでCookie認証を使用する方法について説明します。私はそのアイデアを、ユーザーのためにデータベースにクエリを行い、dbフィールドからClaimsを設定し、context.SignInAsyncを使用してCookieを作成するカスタムミドルウェアと組み合わせました。私はこのミドルウェアをapp.UseAuthentication()の前に置きます。この問題は、.Userオブジェクトが設定されていない最初の要求時に発生します.SignInメソッドはCookieを作成するだけで、.Userオブジェクトは設定しないようです。認証ミドルウェアは、最初の要求時には存在しないため、クッキーはまだ表示されません。

誰でもアイデアを提供できますか?たぶん私はそれについて間違っている、またはこのテクニックは大丈夫ですが、私はそれを動作させるために必要なものが欠けている。 Startup.csで

public void ConfigureServices(IServiceCollection services) 
    { 
     services.AddMvc(); 


     services.AddAuthentication("MyAuthenticationCookie") 
      .AddCookie("MyAuthenticationCookie"); 
    } 

    public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
    { 
     if (env.IsDevelopment()) 
     { 
      app.UseDeveloperExceptionPage(); 
      app.UseBrowserLink(); 
     } 
     else 
     { 
      app.UseExceptionHandler("/Home/Error"); 
     } 

     app.UseStaticFiles(); 

     app.UseMyUserMiddleware(); 

     app.UseAuthentication(); 

     app.UseMvc(routes => 
     { 
      routes.MapRoute(
       name: "default", 
       template: "{controller=Home}/{action=Index}/{id?}"); 
     }); 
    } 

カスタムミドルウェア:

public class MyUserMiddleware 
{ 
    private readonly RequestDelegate _next; 

    public MyUserMiddleware(RequestDelegate next) 
    { 
     _next = next; 
    } 

    public Task Invoke(HttpContext context) 
    { 
     // Sign in user if this auth cookie doesn't exist 
     if (context.Request.Cookies[".AspNetCore.MyAuthenticationCookie"] == null) 
     { 
      // Get user from db - not done 

      // Set claims from user object - put in dummy test name for now 
      var claims = new List<Claim> 
      { 
       new Claim(ClaimTypes.Name, "TEST"), 

      }; 

      var claimsIdentity = new ClaimsIdentity(claims, "MyAuthenticationCookie"); 

      context.SignInAsync("MyAuthenticationCookie", new ClaimsPrincipal(claimsIdentity)); 
     } 

     return this._next(context); 
    } 
} 

public static class MyUserMiddlewareExtensions 
{ 
    public static IApplicationBuilder UseMyUserMiddleware(
     this IApplicationBuilder builder) 
    { 
     return builder.UseMiddleware<MyUserMiddleware>(); 
    } 
} 
+0

「ユーザーは技術的に認証されてからアプリケーションにアクセスします」それはイントラネットアプリケーションのように思えます。 Windows認証を試しましたか? "userIdはリクエストヘッダーに存在します"だから、リクエストヘッダにカスタムリクエストヘッダプロパティ "x-user-id"、2があるでしょうか? whoooは何かです。 –

+0

私はその部分の仕方を決めることはできません。 – user1560457

+0

'Services.AddAuthentication()'と 'context.SignInAsync()'の 'MyAuthenticationCookie'を' CookieAuthenticationDefaults.AuthenticationScheme'に置き換えてみてください。そして、 '.AddCookie(options => {options.Cookie.Name =" xxxxxx ";})'にクッキーの名前を設定します。 –

答えて

2

短い答え:あなたは&は、請求項を取得認証するためにカスタムAuthorizationHandlerを使用する必要があります。

長い答え:ASP.NET COREでは、認証ミドルウェアから離れるべきです。代わりにAuthenticationHandlerを使用する必要がありますmicrosoft

カスタム認証ハンドラを作成するには、AuthenticationHandler<TOption>を継承する新しいクラスを作成する必要があります。 TOptionはハンドラにパラメータを渡すために使用される単純なクラスです。

public class TecMobileOptions : AuthenticationSchemeOptions 
{ 
    // Add your options here 
} 

public class MyNewHandler : AuthenticationHandler<MyOptions> 
{ 
    private readonly ILogger _logger; 

    public TecMobileHandler(
     IOptionsMonitor<MyOptions> options, 
     ILoggerFactory loggerFactory, 
     UrlEncoder encoder, 
     ISystemClock clock) : base(options, loggerFactory, encoder, clock) 
    { 
     // Inject here your DbContext 
     _logger = loggerFactory.CreateLogger("name..."); 
    } 
} 

次に、HandleAuthenticateAsyncメソッドを実装する必要があります。これは、必要な認証ミドルウェアによって呼び出されます。このメソッドによって返さ

protected override async Task<AuthenticateResult> HandleAuthenticateAsync() 
    { 
     var authorization = Request.Headers["UserId"].ToString(); 
     (...) 
     return AuthenticateResult.Success(
      new AuthenticationTicket(**your claims**, Scheme.Name)); 
    } 

クレームはHttpContext.Userオブジェクトを介して利用できるようになります。

これが完了したら、スキームを認証ビルダーに追加する必要があります。

services.AddAuthentication() 
    .AddCookie("MyAuthenticationCookie"); 
    .AddScheme<MyOptions, MyHandler>("MyHandlerName"); 

最後に、安全を確保したいすべてのクラス/メソッドに承認属性を追加する必要があります

app.UseAuthentication(); 

Startup.cs /設定方法に次のコード行を追加することを忘れないでください。

[Authorize(AuthenticationSchemes = "MyHandlerName")] 
public class MyControllerController : BaseController 
{ } 

OR 

[Authorize(AuthenticationSchemes = "MyHandlerName")] 
public IActionResult MyMethod() 
{ } 

EDIT:完全なログインプロセスをカバーするソリューションです。 のは、次の2つの認証方式を定義について考えてみましょう - CookieScheme と呼ばれるベースのクッキーは - AutoSignInSchemeは:次に、あなたがAccountController

public class AccountController : Controller 
{ 
    [HttpGet] 
    [Authorize(AuthenticationSchemes = "AutoSignInScheme")] 
    public async Task<IActionResult> AutoSignIn(string returnUrl) 
    { 
     await HttpContext.SignInAsync(
      "CookieScheme", 
      new ClaimsPrincipal(new ClaimsIdentity(User.Claims, "CookieScheme"))); 
     return Redirect(returnUrl); 
    } 
} 

で追加する必要があります

[Authorize(AuthenticationSchemes = "CookieScheme")] 
public class SecuredController : Controller 
{ 
    (...) 
} 

上記の手順に従って対応するハンドラを作成しますStartup.csに次の行を追加します。

 services.AddAuthentication() 
      .AddCookie("CookieScheme", opts => 
      { 
       opts.LoginPath = new PathString("/account/AutoSignIn"); 
       opts.LogoutPath = ** TODO IF REQUIRED ** 
       opts.Cookie.Expiration = TimeSpan.FromHours(8); 
      }) 
      .AddScheme<MyOptions, MyHandler>("AutoSignInScheme"); 

ユーザーがサイトにアクセスしようとすると、オートシグリンコントローラにリダイレクトされます。クレームはあなたのDBから取得され、クッキーに保存され、ユーザーは最終的に彼の最初の宛先にリダイレクトされます。

Seb

+0

あなたの答えに感謝します。最初のリクエスト後にクッキーを作成しているようには見えません。カスタムのAuthenticationHandlerから毎回データベースを呼び出さなければならないということでユーザー情報を保持できなければ(ヘッダからIDを取得した後)。 – user1560457

+0

私は網羅的ではありませんでした!これにより、クッキーに保存できるクレームが作成されます。通常、ユーザーがログインしていない場合は、クレームを取得したページにリダイレクトし、Cookieを作成して、必要な場所にリダイレクトします。私のポストはあなたにクレームを得る方法を示していました!ミスアンダーグラウンドに申し訳ありません – Seb

+0

ミドルウェアにクッキーを設定する方法はありますか?ログインアクションの必要はありません。ユーザーは何も手動で行う必要はありません。 – user1560457

関連する問題