【问题标题】:Image url in Asp.Net 4.5 Webforms when using google authentication使用谷歌身份验证时 Asp.Net 4.5 Webforms 中的图像 url
【发布时间】:2025-12-03 13:10:01
【问题描述】:

我有一个基于 webforms 的 ASP.Net 4.5(不是 ASP.Net Core)网站。

我正在使用 Login.aspx 页面上的 Google 按钮登录用户,这是 Visual Studio 2017 社区中的标准模板。

当我查看 Visual Studio 2017 中的代码时,我可以看到在 RegisterExternalLogin.aspx.cs 中获取针对 Google 的身份验证信息(即下面代码中的 loginInfo 变量)的代码,但是当我检查对象 User.Identity.Claims 之后在另一个页面的代码隐藏中进行身份验证(例如在 About.aspx.cs 中),然后我发现登录用户的图像 url 没有声明。

问题

是否可以使用 .Net 框架 4.5(不是 ASP.Net Core)中现有的 ASP.Net Identity/OWIN 身份验证从 Google 获取图像 url?如果是,那如何获得呢?

RegisterExternalLogin.aspx.cs 中 Google 身份验证后执行的代码

 if (!IsPostBack)
        {
            var manager = new UserManager();
            var loginInfo = Context.GetOwinContext().Authentication.GetExternalLoginInfo();
            if (loginInfo == null)
            {
                Response.Redirect("~/Account/Login");
            }
            var user = manager.Find(loginInfo.Login);
            if (user != null)
            {
                IdentityHelper.SignIn(manager, user, isPersistent: false);
                IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
            }

【问题讨论】:

    标签: c# asp.net asp.net-identity google-authentication


    【解决方案1】:

    经过一番研究,我发现如何在 webforms ASP.Net 应用程序中使用标准 ASP.Net Identity/OWIN 获取个人资料图片网址。

    必须注意的是,成功验证后来自 google 的响应已经包含个人资料图片 url,但由于它不是从响应中提取并由 asp 提供的。 net identity/owin 框架代码,看起来好像图像 url 不存在。因此,我们需要做的就是提取此图片 url 并将其放入 asp.net 声明对象中。 (无需专门致电谷歌获取个人资料图片网址)

    您需要对 Visual Studio 模板发出的标准代码进行以下 2 处更改。

    1. Startup.Auth.cs 中添加自定义代码,在 Google 身份验证完成其操作并返回其响应时执行。此自定义代码位于 OnAuthenticated 函数中。我们将访问个人资料图片网址,可以通过 context.User 对象的子对象找到该网址,并将其声明添加到 Google's context.Identity

    在 Startup.Auth.cs 中

        var options = new GoogleOAuth2AuthenticationOptions()
        {
           ClientId = "someValue1",
           ClientSecret = "someValue2",
           //ADD CODE AS BELOW in addition to above 2 lines
           Provider = new GoogleOAuth2AuthenticationProvider()
           {
            OnAuthenticated = (context) =>
             {
                //following line will add a new claim for profile image url
                context.Identity.AddClaim(new Claim("picUrl", ((Newtonsoft.Json.Linq.JValue)(context.User.SelectToken("image").SelectToken("url"))).Value.ToString()));
                return Task.FromResult(0);
             }
           }
    
        };
    
    1. 当用户使用标准代码的IdentityHelper.SignIn 方法登录时,我们需要将图像的 Google 身份声明转移到 ASP.Net 身份声明。在此之后,我们可以访问任何 aspx 页面的代码隐藏中的图像 url,如本答案末尾的 code-sn-p 所示。

    在 IdentityModels.cs 中

    public static void SignIn(UserManager manager, ApplicationUser user, bool isPersistent)
    {
        IAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
        authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
        var identity = manager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
    
        //CUSTOM CODE Start
        //get image url claim from Google Identity
       if (authenticationManager.GetExternalLoginInfo().Login.LoginProvider == "Google")
         {
            var externalIdentity = authenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
            var picClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type.Equals("picUrl"));
            var picUrl = picClaim.Value;
            //add a claim for profile pic url to ASP.Net Identity
            identity.AddClaim(new System.Security.Claims.Claim("picUrl", picUrl));
         }
        //CUSTOM CODE end
    
        authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent , ExpiresUtc = DateTime.UtcNow.AddMinutes(5), RedirectUri="http://www,appsprocure.com"  }, identity);
    }
    

    现在,只要您想使用个人资料图片网址,只需使用如下代码即可。

    如何在页面代码隐藏中使用图片网址声明

    var ctx = Request.GetOwinContext();
    ClaimsPrincipal user = ctx.Authentication.User;
    IEnumerable<Claim> claims = user.Claims;
    var pictureClaim = claims.FirstOrDefault(c => c.Type == "picUrl");
    if (pictureClaim != null)
    {
        Response.Write(string.Format("<img src='{0}' alt='profileImageMissing' />", pictureClaim.Value));
    }
    

    【讨论】: