在ASP.NET Core 3.1中尝试与Google进行身份验证时出错,未注册身份验证处理程序

问题描述 投票:1回答:1

错误authentication Error with Google

这是我的入门班

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        // Demand authentication in the whole application
        services.AddControllersWithViews(o => o.Filters.Add(new AuthorizeFilter()));

        services.AddScoped<IConferenceRepository, ConferenceRepository>();
        services.AddScoped<IProposalRepository, ProposalRepository>();
        services.AddScoped<IAttendeeRepository, AttendeeRepository>();
        services.AddScoped<IUserRepository, UserRepository>();

        services.AddDbContext<ConfArchDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
                assembly => 
                   assembly.MigrationsAssembly(typeof(ConfArchDbContext).Assembly.FullName)));

        services
           .AddAuthentication(options =>
           {
               options.DefaultScheme = 
                    CookieAuthenticationDefaults.AuthenticationScheme;
               options.DefaultChallengeScheme = 
             GoogleDefaults.AuthenticationScheme;
           })
           .AddCookie(options =>
           {
               options.Cookie.IsEssential = true;
               //options.Cookie.SameSite = SameSiteMode.None;
           })
           .AddGoogle(options =>
           {                   
               options.SignInScheme = 
               CookieAuthenticationDefaults.AuthenticationScheme;
               options.ClientId = 
                Configuration["Authentication:Google:ClientId"];
               options.ClientSecret = 
              Configuration["Authentication:Google:ClientSecret"];
           });
    }

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

        //app.UseIdentity();
        // app.UseAuthentication();           

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseCookiePolicy();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {                   
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Conference}/{action=Index}/{id?}");
        });
    }
}

这是我的控制器,在行中抛出错误:var result = await HttpContext.AuthenticateAsync(

public class AccountController : Controller
{
    private readonly IUserRepository userRepository;

    public AccountController(IUserRepository userRepository)
    {
        this.userRepository = userRepository;
    }

    // This method must be anonymous to allow access to not logged users
    [AllowAnonymous]
    public IActionResult Login(string returnUrl = "/")
    {
        return View(new LoginModel { ReturnUrl = returnUrl });
    }

    [HttpPost]
    [AllowAnonymous]
    public async Task<IActionResult> Login(LoginModel model)
    {  
        // Looking for user in local repository in the class userrepository
        var user = userRepository.GetByUsernameAndPassword(model.Username, model.Password);
        if (user == null)
            return Unauthorized();

        // Data of the user, claims class is used to represent the data user
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
            new Claim(ClaimTypes.Name, user.Name),
            new Claim(ClaimTypes.Role, user.Role),
            new Claim("FavoriteColor", user.FavoriteColor)
        };

        // Object to save in Identity object type ClaimsIdentity
        var identity = new ClaimsIdentity(claims,
            CookieAuthenticationDefaults.AuthenticationScheme);
        // Create claims principal object with the Identity
        var principal = new ClaimsPrincipal(identity);

        await HttpContext.SignInAsync(
            CookieAuthenticationDefaults.AuthenticationScheme,
            principal,
            new AuthenticationProperties { IsPersistent = 
                 model.RememberLogin,                     
                 ExpiresUtc= DateTime.UtcNow.AddMinutes(10)
                                         });
        return LocalRedirect(model.ReturnUrl);
    }

    [AllowAnonymous]
    public IActionResult LoginWithGoogle(string returnUrl = "/")
    {
        var props = new AuthenticationProperties
        {
            RedirectUri = Url.Action("GoogleLoginCallback"),
            Items =
            {
                { "returnUrl", returnUrl }
            }
        };
        return Challenge(props, GoogleDefaults.AuthenticationScheme);
    }

    [AllowAnonymous]
    public async Task<IActionResult> GoogleLoginCallback()
    {
        // read google identity from the temporary cookie
        var result = await HttpContext.AuthenticateAsync(
            ExternalAuthenticationDefaults.AuthenticationScheme);

        var externalClaims = result.Principal.Claims.ToList();

        var subjectIdClaim = externalClaims.FirstOrDefault(
            x => x.Type == ClaimTypes.NameIdentifier);
        var subjectValue = subjectIdClaim.Value;

        var user = userRepository.GetByGoogleId(subjectValue);

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
            new Claim(ClaimTypes.Name, user.Name),
            new Claim(ClaimTypes.Role, user.Role),
            new Claim("FavoriteColor", user.FavoriteColor)
        };

        var identity = new ClaimsIdentity(claims,
            CookieAuthenticationDefaults.AuthenticationScheme);
        var principal = new ClaimsPrincipal(identity);

        // delete temporary cookie used during google authentication
        await HttpContext.SignOutAsync(
            ExternalAuthenticationDefaults.AuthenticationScheme);

        await HttpContext.SignInAsync(
            CookieAuthenticationDefaults.AuthenticationScheme, principal);

        return LocalRedirect(result.Properties.Items["returnUrl"]);
    }

    // Action to logout
    public async Task<IActionResult> Logout()
    {
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        return Redirect("/");
    }
}
asp.net-core authentication external
1个回答
0
投票

我想出了答案,在配置服务代码中应该是这样:

// Demand authentication in the whole application
services.AddControllersWithViews(o => o.Filters.Add(new 
AuthorizeFilter()));

services.AddScoped<IConferenceRepository, ConferenceRepository>();
services.AddScoped<IProposalRepository, ProposalRepository>();
services.AddScoped<IAttendeeRepository, AttendeeRepository>();
services.AddScoped<IUserRepository, UserRepository>();

services.AddDbContext<ConfArchDbContext>(options =>


 options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
        assembly => 
 assembly.MigrationsAssembly(typeof(ConfArchDbContext).Assembly.FullName)));

services.AddAuthentication(o => {
    o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    //o.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
})
.AddCookie()
.AddCookie(ExternalAuthenticationDefaults.AuthenticationScheme)
.AddGoogle(o =>
{   // ClienteId and Secret to authenticate the user from Google          
    o.SignInScheme = 
        ExternalAuthenticationDefaults.AuthenticationScheme;
    o.ClientId = Configuration["Authentication:Google:ClientId"];
    o.ClientSecret = 
       Configuration["Authentication:Google:ClientSecret"];
});
热门问题
推荐问题
最新问题