0

私は、基本認証を外部認証サービスを利用するためのガイドをたくさん読んできました。ASP.NETコアでのGoogle +/Facebook認証

私はユーザーレベルのセキュリティを備えた "ボイラープレート" .NETコアプロジェクトから始めました。私は自分のGoogleとFacebookの認証キーを作成し、必要なライブラリを含んでいます。私はそうのように私のユーザークラスを設定します。

public class ApplicationUser : IdentityUser<Guid> 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string MiddleName { get; set; } 
    public string Nickname { get; set; } 
} 

マイStartup.csファイルは次のようになります。

public class Startup 
{ 
    public Startup(IHostingEnvironment env) 
    { 
     var builder = 
      new ConfigurationBuilder().SetBasePath(env.ContentRootPath) 
       .AddJsonFile("appsettings.json", true, true) 
       .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true); 

     if (env.IsDevelopment()) 
      builder.AddUserSecrets(); 

     builder.AddEnvironmentVariables(); 

     Configuration = builder.Build(); 
    } 

    public IConfigurationRoot Configuration { get; } 

    // This method gets called by the runtime. Use this method to add services to the container. 

    public void ConfigureServices(IServiceCollection services) 
    { 
     // Add framework services. 
     services.AddDbContext<ApplicationDbContext>(
      options => options.UseNpgsql(Configuration.GetConnectionString("ApplicationDb"))); 

     services.AddIdentity<ApplicationUser, ApplicationRole>(opt => 
      { 
       opt.Password.RequireNonAlphanumeric = false; 
       opt.Password.RequireUppercase = false; 
       opt.Password.RequireLowercase = false; 
       opt.Password.RequireDigit = false; 
       opt.Password.RequiredLength = 8; 

       opt.User.RequireUniqueEmail = true; 
       opt.User.AllowedUserNameCharacters = "abcd[email protected]."; 

       opt.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); 
       opt.Lockout.MaxFailedAccessAttempts = 5; 

       opt.SignIn.RequireConfirmedEmail = true; 
       opt.SignIn.RequireConfirmedPhoneNumber = false; 
      }) 
      .AddEntityFrameworkStores<ApplicationDbContext, Guid>() 
      .AddDefaultTokenProviders(); 

     services.AddMvc(options => { options.Filters.Add(new RequireHttpsAttribute()); }); 

     // Add application services. 
     services.AddTransient<IEmailSender, AuthMessageSender>(); 
     services.AddTransient<ISmsSender, AuthMessageSender>(); 
    } 

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
     loggerFactory.AddDebug(); 

     if (env.IsDevelopment()) 
     { 
      app.UseDeveloperExceptionPage(); 
      app.UseDatabaseErrorPage(); 
      app.UseBrowserLink(); 
     } 
     else 
     { 
      app.UseExceptionHandler("/Home/Error"); 
     } 

     app.UseStaticFiles(); 

     app.UseIdentity(); 

     //Add external authentication middleware below.To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715 
     var facebookOptions = new FacebookOptions 
     { 
      AppId = Configuration["Authentication:Facebook:AppId"], 
      AppSecret = Configuration["Authentication:Facebook:AppSecret"] 
     }; 
     app.UseFacebookAuthentication(facebookOptions); 

     var googleOptions = new GoogleOptions 
     { 
      ClientId = Configuration["Authentication:Google:AppId"], 
      ClientSecret = Configuration["Authentication:Google:AppSecret"] 
     }; 
     app.UseGoogleAuthentication(googleOptions); 

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

これまでのところ、とても良いです。私はプロジェクトを立ち上げ、「ログイン」リンクをクリックすると、GoogleまたはFacebookでログインすることができます。私はGoogleを選択しています...初めて試してみると、Googleの承認を求めるメッセージが表示され、ニックネームなどで自分のローカルアカウントを作成するRegisterページが表示されます。

今、私は行くことができますアカウントにローカルパスワードを追加します。すべてがうまくいっています。だから私はログオフし、私のクッキーを削除した後、私のGoogle資格情報を使って再度ログインしようとします。意外にも、私は登録ページに再び持ち込まれますが、私はすでに登録されているため登録できません。私のローカルパスワードも機能しません。

だから私はもう少しこれを掘り下げます。 AccountControllerには、ExternalLoginCallbackというメソッドがあり、すべての魔法が発生するようです。私の方法は次のようになります。

[HttpGet] 
    [AllowAnonymous] 
    public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null) 
    { 
     if (remoteError != null) 
     { 
      ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}"); 
      return View(nameof(Login)); 
     } 
     var info = await _signInManager.GetExternalLoginInfoAsync(); 
     if (info == null) 
      return RedirectToAction(nameof(Login)); 

     // Sign in the user with this external login provider if the user already has a login. 
     var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, false); 
     if (result.Succeeded) 
     { 
      _logger.LogInformation(5, "User logged in with {Name} provider.", info.LoginProvider); 
      return RedirectToLocal(returnUrl); 
     } 
     if (result.RequiresTwoFactor) 
      return RedirectToAction(nameof(SendCode), new 
      { 
       ReturnUrl = returnUrl 
      }); 
     if (result.IsLockedOut) 
      return View("Lockout"); 
     // If the user does not have an account, then ask the user to create an account. 
     ViewData["ReturnUrl"] = returnUrl; 
     ViewData["LoginProvider"] = info.LoginProvider; 
     var email = info.Principal.FindFirstValue(ClaimTypes.Email); 
     var firstName = info.Principal.FindFirstValue(ClaimTypes.GivenName); 
     var lastName = info.Principal.FindFirstValue(ClaimTypes.Surname); 
     return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel 
     { 
      Email = email, 
      FirstName = firstName, 
      LastName = lastName 
     }); 
    } 

私は結果がNotAllowedです...それは_signInManager.GetExternalLoginInfoAsync()呼び出しを通過するように、コードをトレースし、?

NotAllowedは、私の知る限り、他の3はSucceededRequiresTwoFactor、およびIsLockedOutであること言うことができるように、4つの可能な結果の一つです。残りの3つの値は別の場所に送られますので、ローカルアカウントが存在しない場合はNotAllowedと予想されます。

誰かが私にここで何が起こっているのか考えてもらえますか? Google(またはFacebook、同じ種類のことがそこで起こる)でサインしたら、私はそれらに戻ってログインすることはできず、実際の問題が何であるかを判断する有用なフィードバックはほとんどありません。

答えて

1

気にしないでください。私はアホです。

私はこのラインを入れたときに、私は超クールされていたと思った:私は起こっていなかったものを推測し、電子メールを確認していなかったことから、

opt.SignIn.RequireConfirmedEmail = true; 

...しかし? SMH ...

関連する問題