0

Я читал множество руководств для получения базовой аутентификации пользователей с использованием внешних служб аутентификации, и я просто не могу заставить эту чертову работать.Аутентификация Google +/Facebook в ядре ASP.NET

Я начал работу с проекта «Core plate» .NET Core с уровнем безопасности на уровне пользователя. Я создал свои ключи для доступа к 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 и указываю на страницу «Реестр», где я создаю свою локальную учетную запись с псевдонимом и т. Д.

Теперь я могу пойти добавьте локальный пароль в мою учетную запись. Все работает плавно. Поэтому я выхожу из системы и снова пытаюсь войти в систему, используя мои учетные данные Google, после удаления моего файла cookie. Удивительно, но меня снова заносят на страницу «Регистрация», но я не могу зарегистрироваться, потому что я уже зарегистрирован. Мой локальный пароль также не будет работать.

Так что я копаю в это немного больше. В 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 
     }); 
    } 

трассировать код, как он проходит через _signInManager.GetExternalLoginInfoAsync() вызов, и ... результат NotAllowed?

NotAllowed является одним из 4-х возможных результатов, насколько я могу сказать, другие 3 будучи Succeeded, RequiresTwoFactor и IsLockedOut. Остальные 3 значения отправляются где-то еще, поэтому я должен предположить, что NotAllowed ожидается, когда локальная учетная запись не существует ... кроме того, что существует локальный счет.

Может кто-нибудь дать мне представление о том, что здесь происходит? Как только я подписываюсь с Google (или Facebook, там происходит то же самое), я не могу войти в систему с ними, и есть почти нулевая полезная обратная связь, чтобы определить, какова фактическая проблема.

ответ

1

Не обращайте внимания; Я идиот.

Я думал, что я был очень крутой, когда я ставлю эту строку:

opt.SignIn.RequireConfirmedEmail = true; 

... но, так как я не подтверждал письмо, думаю, что не происходит? SMH ...

Смежные вопросы