簡體   English   中英

沒有ASP.NET標識的.NET核心外部身份驗證

[英].NET Core External Authentication without ASP.NET Identity

我使用自己的JWT令牌身份驗證,而不是使用默認模板免費提供的asp.net身份。 我到處尋找有關如何在沒有asp.net身份的情況下實現外部身份驗證的文檔/指導,但所有文章都是針對asp.net身份驗證的。

我已設法將用戶重定向到谷歌登錄頁面(使用ChallengeResult),但當提供商重定向回來時,應用程序失敗了。

我刪除了: app.UseAuthentication(); Startup.cs中 ,(禁用身份驗證),然后我就能夠到達回調函數,但后來我不知道如何在不使用登錄管理器的情況下從響應中檢索數據。

啟動

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Authentication:Secret"]));

        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = signingKey,
            ValidateIssuer = true,
            ValidIssuer = Configuration["Urls:Base"],
            ValidateAudience = true,
            ValidAudience = Configuration["Urls:Base"],
            ValidateLifetime = true,
            ClockSkew = TimeSpan.Zero
        };

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(o =>
        {
            o.TokenValidationParameters = tokenValidationParameters;
        }
        ).AddGoogle(googleOptions =>
        {
            googleOptions.ClientId = "x";//Configuration["Authentication:Google:ClientId"];
            googleOptions.ClientSecret = "x";//Configuration["Authentication:Google:ClientSecret"];
            googleOptions.CallbackPath = "/api/authentication/externalauthentication/externallogincallback";
        });

        services.Configure<RequestLocalizationOptions>(
            opts =>
            {
                var supportedCultures = new List<CultureInfo>
                {
                        new CultureInfo("en"),
                        new CultureInfo("sv")
                };

                opts.DefaultRequestCulture = new RequestCulture(culture: "en", uiCulture: "en");
                opts.SupportedCultures = supportedCultures;
                opts.SupportedUICultures = supportedCultures;
            });

        services.AddMvc(config =>
        {
            var policy = new AuthorizationPolicyBuilder()
                             .RequireAuthenticatedUser()
                             .Build();

            config.Filters.Add(new AuthorizeFilter(policy));
        });

        services.RegisterAppSettings(Configuration);

        services.AddOptions();

        services.InjectServices();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseAuthentication();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();

            EndpointsAppSettings endpointAppSettings = new EndpointsAppSettings();
            Configuration.GetSection("Endpoints").Bind(endpointAppSettings);

            app.UseCors(builder =>
            {
                builder.WithOrigins(endpointAppSettings.Aurelia)
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials();
            });
        }

        var logService = app.ApplicationServices.GetService<ILogService>();

        loggerFactory.AddProvider(new LogProvider(logService));

        app.UseRequestLocalization(app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>().Value);

        app.UseMvc();

        app.UseDefaultFiles();

        app.UseStaticFiles();
    }
}

調節器

[Route("api/authentication/[controller]")]
public class ExternalAuthenticationController : Controller
{
    [AllowAnonymous]
    [HttpPost(nameof(ExternalLogin))]
    public IActionResult ExternalLogin(ExternalLoginModel model)
    {
        if (model == null || !ModelState.IsValid)
        {
            return null;
        }

        var properties = new AuthenticationProperties { RedirectUri = "http://localhost:3000/#/administration/organisations" };

        return Challenge(properties, model.Provider);
    }

    [AllowAnonymous]
    [HttpGet(nameof(ExternalLoginCallback))]
    public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
    {
        if (remoteError != null)
        {
            return null;
        }

        //Help me retrieve information here!

        return null;
    }
}

ExternalLoginCallback的堆棧跟蹤

info:Microsoft.AspNetCore.Hosting.Internal.WebHost [1]請求啟動HTTP / 1.1 GET http:// localhost:5000 / api / authentication / externalauthentication / externallogincallback?state = CfDJ8CyKJfDTf - 隱藏數據 - 52462e4156a..5cde&prompt =無失敗:Microsoft.AspNetCore.Server.Kestrel [13]連接ID“0HLAKEGSHERH7”,請求ID“0HLAKEGSHERH7:00000002”:應用程序拋出了未處理的異常。 System.InvalidOperationException: 沒有配置IAuthenticationSignInHandler來處理該方案的登錄: Microsoft.AspNetCore.Authentication.AuthenticationService.d__13.MoveNext()的承載 - 從拋出異常的上一個位置的堆棧跟蹤結束---在系統Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler d__12.MoveNext()中的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(。任務任務)中的.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()---來自先前位置的堆棧跟蹤結束拋出---在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.d__6.MoveNext()--- stack of end從拋出異常的先前位置追蹤---在System.Ru的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()處 Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.d__3.MoveNext()中的ntime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任務任務)---拋出異常的前一個位置的堆棧跟蹤結束---在System.Runtime.ExceptionServices上Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame`1.d__2.MoveNext()中的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任務任務)中的.ExceptionDispatchInfo.Throw()

  1. 為什么我得到:沒有IAuthenticationSignInHandler配置為處理該方案的登錄:承載,這是如何解決的?
  2. 如何在ExternalLoginCallback操作中檢索用戶信息? 使用默認的mvc模板,就像執行操作一樣簡單:var info = await _signInManager.GetExternalLoginInfoAsync(); 但我沒有使用登錄經理。
  3. 我還沒有找到任何關於此的文檔,當然我不能成為唯一一個不使用內置的巨型dumbo asp.net身份進行外部身份驗證的人嗎? 如果你是一個比我更好的Google員工,請指出我正確的方向!

要解決:

沒有IAuthenticationSignInHandler配置為處理該方案的登錄:承載

我必須添加一個cookie處理程序,它將暫時存儲外部身份驗證的結果,例如外部提供程序發送的聲明。 這是必要的,因為在完成外部身份驗證過程之前通常會涉及一些重定向。

啟動

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(o =>
{
    o.TokenValidationParameters = tokenValidationParameters;
})
.AddCookie()
.AddGoogle(googleOptions =>
{
    googleOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    googleOptions.ClientId = "x";//Configuration["Authentication:Google:ClientId"];
    googleOptions.ClientSecret = "x";//Configuration["Authentication:Google:ClientSecret"];
    //googleOptions.CallbackPath = "/api/authentication/externalauthentication/signin-google";
});

這里的重要部分是CookieAuthenticationDefaults.AuthenticationScheme。 這是一個存儲“Cookies”的字符串常量。 雖然我們可以在代碼中直接使用字符串“Cookies”,但使用預設常量會更安全。 這是默認情況下為AddCookies函數指定的身份驗證方案名稱。 它可以幫助您參考cookie身份驗證。

現在是時候從回調操作中的外部身份驗證提供的聲明中檢索用戶信息了。

調節器

[AllowAnonymous]
[HttpPost(nameof(ExternalLogin))]
public IActionResult ExternalLogin(ExternalLoginModel model)
{
    if (model == null || !ModelState.IsValid)
    {
        return null;
    }

    var properties = new AuthenticationProperties { RedirectUri = _authenticationAppSettings.External.RedirectUri };

    return Challenge(properties, model.Provider);
}

[AllowAnonymous]
[HttpGet(nameof(ExternalLoginCallback))]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
    //Here we can retrieve the claims
    var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);

    return null;
}

瞧! 我們現在有一些用戶信息可供使用!

在此輸入圖像描述

有用的鏈接

http://docs.identityserver.io/en/latest/topics/signin_external_providers.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM