如何在 ASP.NET Core Web API 中从 google 外部提供商获取身份值

问题描述 投票:0回答:1
    [ApiController]
    [Route("[controller]")]
    public class AuthController : ControllerBase
    {
        private readonly SignInManager<IdentityUser> _signInManager;

        public AuthController(SignInManager<IdentityUser> signInManager)
        {
            _signInManager = signInManager ?? throw new ArgumentNullException(nameof(signInManager));
        }

        [HttpGet("token")]
        public ChallengeResult Token()
        {
            var properties = new GoogleChallengeProperties
            {
                RedirectUri = "/auth/retrieve",
                AllowRefresh = true,
            };

            return Challenge(properties, "Google");
        }

        [HttpGet("[action]")]
        public async Task Retrieve()
        {
            var token = await HttpContext.GetTokenAsync("access_token");
            var externalLoginInfoAsync = await _signInManager.GetExternalLoginInfoAsync();
            var identityName = User?.Identity?.Name;
            var authenticateResult = await HttpContext.AuthenticateAsync();
        }
    }

我将用户定向到 /auth/token,在那里他被重定向到 Google Oauth 页面,如果成功,他会被重定向到 /auth/retrieve,我期望用户数据在那里,但是

token, externalLoginInfoAsync, identityName, authenticateResult is null

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseNpgsql(Configuration.GetConnectionString("Default")));
            services.AddIdentity<IdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.AddAuthentication()
                .AddCookie()
                .AddGoogle(options =>
                {
                    options.Scope.Add("https://www.googleapis.com/auth/gmail.settings.basic");
                    options.AccessType = "offline";
                    options.SaveTokens = true;
                    options.SignInScheme = IdentityConstants.ExternalScheme;
                    options.Events.OnCreatingTicket = ctx =>
                    {
                        var identityName = ctx.Identity.Name;
                        return Task.CompletedTask;
                    };

                    options.ClientId = "SMTH_VALUE";
                    options.ClientSecret = "SMTH_VALUE";
                });

            services.AddControllers();
        }

我调试了谷歌提供程序并发现事件中的用户值-identityName不为空。 我如何在控制器中获取这个值?

google-oauth asp.net-core-webapi
1个回答
2
投票

您可以参考以下代码在 Startup.ConfigureServices 方法中配置 Google 身份验证:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddAuthentication()
            .AddGoogle(opt =>
            {
                opt.ClientId = "yourclientid.apps.googleusercontent.com";
                opt.ClientSecret = "yourclientsecret";
                opt.SignInScheme = IdentityConstants.ExternalScheme;
            });
        services.AddControllersWithViews();
        services.AddRazorPages();
    }

然后,使用以下示例使用Google登录并获取用户信息:

[Authorize]
public class AccountController : Controller
{
    private UserManager<ApplicationUser> userManager;
    private SignInManager<ApplicationUser> signInManager;

    public AccountController(UserManager<ApplicationUser> userMgr, SignInManager<ApplicationUser> signinMgr)
    {
        userManager = userMgr;
        signInManager = signinMgr;
    }

    // other methods

    public IActionResult AccessDenied()
    {
        return View();
    }

    [AllowAnonymous]
    public IActionResult GoogleLogin()
    {
        string redirectUrl = Url.Action("GoogleResponse", "Account");
        var properties = signInManager.ConfigureExternalAuthenticationProperties("Google", redirectUrl);
        return new ChallengeResult("Google", properties);
    }

    public IActionResult Login()
    {
        return View();
    }

    [AllowAnonymous]
    public async Task<IActionResult> GoogleResponse()
    {
        ExternalLoginInfo info = await signInManager.GetExternalLoginInfoAsync();
        if (info == null)
            return RedirectToAction(nameof(Login));

        var result = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, false);
        string[] userInfo = { info.Principal.FindFirst(ClaimTypes.Name).Value, info.Principal.FindFirst(ClaimTypes.Email).Value };
        if (result.Succeeded)
            return View(userInfo);
        else
        {
            ApplicationUser  user = new ApplicationUser
            {
                Email = info.Principal.FindFirst(ClaimTypes.Email).Value,
                UserName = info.Principal.FindFirst(ClaimTypes.Email).Value
            };

            IdentityResult identResult = await userManager.CreateAsync(user);
            if (identResult.Succeeded)
            {
                identResult = await userManager.AddLoginAsync(user, info);
                if (identResult.Succeeded)
                {
                    await signInManager.SignInAsync(user, false);
                    return View(userInfo);
                }
            }
            return AccessDenied();
        }
    }
}

结果是这样的:

更多详细信息,请参阅如何在 ASP.NET Core Identity 中集成 Google 登录功能ASP.NET Core 中的 Google 外部登录设置

© www.soinside.com 2019 - 2024. All rights reserved.