私は自分のJWTトークン認証を使用し、デフォルトのテンプレートで無料で提供されるasp.net IDを使用しません。私は、asp.net IDなしで外部認証を実装する方法に関するドキュメント/ガイダンスをどこでも探しましたが、そこにあるすべての記事は、asp.net ID認証に関するものです。
(ChallengeResultを使用して)googleログインページにユーザーをリダイレクトすることに成功しましたが、プロバイダーがアプリをリダイレクトバックすると失敗します。
削除しました:app.UseAuthentication();inStartup.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--HIDDEN DATA --52462e4156a..5cde&Prompt = none失敗:Microsoft.AspNetCore.Server.Kestrel [13]接続ID "0HLAKEGSHERH7"、リクエストID "0HLAKEGSHERH7:00000002":ハンドルされていない例外がアプリケーションによってスローされました。 System.InvalidOperationException:スキームのサインインを処理するように構成されているIAuthenticationSignInHandlerはありません:Bearerat Microsoft.AspNetCore.Authentication.AuthenticationService.d__13.MoveNext()- -例外がスローされた以前の場所からのスタックトレースの終わり--- System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler d__12.MoveNext()---例外がスローされた前の場所からのスタックトレースの終わり--- System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at Microsoft .AspNetCore.Authentication.AuthenticationMiddleware.d__6.MoveNext()---例外がスローされた前の場所からのスタックトレースの終わり--- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Th System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at row。)at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.d__3.MoveNext()---例外がスローされた前の場所からのスタックトレースの終わり--- System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame`1.d__2.MoveNext()
解決するには:
IAuthenticationSignInHandlerがスキームのサインインを処理するように構成されていません:Bearer
外部認証の結果を一時的に保存する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です。これは「Cookie」を格納する文字列定数です。コード内で文字列「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