【问题标题】:Authentication with Google using OpenOAuthProvider使用 OpenOAuthProvider 向 Google 进行身份验证
【发布时间】:2015-10-09 04:09:59
【问题描述】:

我在 Visual Studio 中创建了默认的 ASP.NET 项目模板,然后转到 App_Start 文件夹中的 AuthConfig。然后我取消注释以下行:

OpenAuth.AuthenticationClients.AddGoogle();

我得到了使用 Google 登录的按钮,如下所示:

当我点击 Google 按钮时,我收到了这个错误:

An exception of type 'DotNetOpenAuth.Messaging.ProtocolException' 
occurred in DotNetOpenAuth.OpenId.RelyingParty.dll but was not handled in user code

Additional information: No OpenID endpoint found.

WE.config 文件

    <?xml version="1.0" encoding="utf-8"?>
    <!--
      For more information on how to configure your ASP.NET application, please visit
      http://go.microsoft.com/fwlink/?LinkId=169433
      -->
    <configuration>
      <configSections>


     <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      </configSections>          
      <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
        <pages>


<namespaces>
    <add namespace="System.Web.Optimization" />
  </namespaces>
<controls>
  <add assembly="Microsoft.AspNet.Web.Optimization.WebForms" namespace="Microsoft.AspNet.Web.Optimization.WebForms" tagPrefix="webopt" />
</controls></pages>
<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="2880" defaultUrl="~/" />
</authentication>
<profile defaultProvider="DefaultProfileProvider">
  <providers>


<add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
  </providers>
</profile>
<membership defaultProvider="DefaultMembershipProvider">
  <providers>
    <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
  </providers>
</membership>
<roleManager defaultProvider="DefaultRoleProvider">
  <providers>


         <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
          </providers>
        </roleManager>

        <sessionState mode="InProc" customProvider="DefaultSessionProvider">
          <providers>
            <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
          </providers>
        </sessionState>
      </system.web>
      <runtime>


     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="DotNetOpenAuth.Core" publicKeyToken="2780ccd10d57b246" />
            <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.1.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="DotNetOpenAuth.AspNet" publicKeyToken="2780ccd10d57b246" />
            <bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
      <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
      </entityFramework>

    <appSettings>
          <add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />
        </appSettings>

    </configuration>

请帮助我。我错过了什么?

【问题讨论】:

  • 您是否在 Google 开发人员中创建了 outh 键?
  • 你能提供你的 web.config 文件吗?您还可以使用 log4net 在您的项目中设置日志记录。那么你肯定会发现哪里出了问题。我为您提供了有关如何为 OpenAuth 设置日志记录的链接:stackoverflow.com/questions/3530753/no-openid-endpoint-found
  • @Webruster - 据我所知,新模板不需要创建应用程序,如果我错了,请纠正我
  • @Saasen - 使用 web.config 文件更新问题
  • 谢谢。不过我有点困惑。您是使用项目模板中的内置 OAuth 还是使用 DotNetOpenAuth?此外,在添加 Google 身份验证时,您需要提供客户端 ID 和客户端密码。这是 MVC4 还是 MVC5?

标签: asp.net dotnetopenauth


【解决方案1】:

其实这种实现(OpenId)是deprecated。如果可能,您应该更改为 MVC5。在 MVC5 中,它是非常 straightforward。该解决方案仍然有效。如果不能,您需要编写此 yourself 或使用使用 OAuth2 与 Google 通信的第三方组件。有关已弃用功能的更多信息,请参阅 this answer

【讨论】:

    【解决方案2】:

    正如您在使用Web Form Application 的聊天评论中提到的那样。点击Google 的事件。

    protected void lnkbtngplus_Click(object sender, EventArgs e) 
    { 
    try 
    { 
    var Googleurl = "https://accounts.google.com/o/oauth2/auth?response_type=code&redirect_uri=" + ConfigurationManager.AppSettings["googleplus_redirect_url"] + "&scope=googleapis.com/auth/…" + ConfigurationManager.AppSettings["googleplus_client_id"]; 
    Session["loginWith"] = "google"; 
    Response.Redirect(Googleurl); 
    } 
    
    catch (Exception ex) 
    { 
    Master.Messages(ex.Message); 
    } 
    }
    

    在您的重定向网址上,您可以收集如下所示的参数值

      try
                    {
                        var url = Request.Url.Query;
                        if (url != "")
                        {
                            string queryString = url.ToString();
                            char[] delimiterChars = { '=' };
                            string[] words = queryString.Split(delimiterChars);
                            string code = words[1];
                            SocialNetwork.GoogleUserOutputData json_data = SocialNetwork.Googlemethod(code);
                            String email = String.Empty;
                            String id = String.Empty;
                            email = json_data.email;
                            id = json_data.given_name;
                            if (email != null && email != "")
                            {
                                txtFname.Text = id;
                                txtemail.Text = email;
    
    
                            }
    
    
                        }
                    }
    
                    catch (Exception ex)
                    {
    
                    }
    

    SocialNetwork 类文件我有以下方法

    #region Google
    
    
    
         protected static string Parameters;
    
    
         public static GoogleUserOutputData Googlemethod(string code)
         {
             GoogleUserOutputData serStatus1 = new GoogleUserOutputData();
             string json_data = string.Empty;
             if (code != null)
             {
                 //get the access token 
                 HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
                 webRequest.Method = "POST";
                 Parameters = "code=" + code + "&client_id=" + googleplus_client_id + "&client_secret=" + googleplus_client_sceret + "&redirect_uri=" + googleplus_redirect_url + "&grant_type=authorization_code";
                 byte[] byteArray = Encoding.UTF8.GetBytes(Parameters);
                 webRequest.ContentType = "application/x-www-form-urlencoded";
                 webRequest.ContentLength = byteArray.Length;
                 Stream postStream = webRequest.GetRequestStream();
                 // Add the post data to the web request
                 postStream.Write(byteArray, 0, byteArray.Length);
                 postStream.Close();
    
                 WebResponse response = webRequest.GetResponse(); 
                 postStream = response.GetResponseStream();
                 StreamReader reader = new StreamReader(postStream);
                 string responseFromServer = reader.ReadToEnd();
    
                 GooglePlusAccessToken serStatus = JsonConvert.DeserializeObject<GooglePlusAccessToken>(responseFromServer);//JsonConvert.DeserializeObject<GooglePlusAccessToken>(responseFromServer);
                 //GooglePlusAccessToken serStatus = new GooglePlusAccessToken();
                 if (serStatus != null)
                 {
                     string accessToken = string.Empty;
                     accessToken = serStatus.access_token;
    
                     if (!string.IsNullOrEmpty(accessToken))
                     {
                         using (var w = new WebClient())
                         {
                             json_data = w.DownloadString("https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + accessToken);
                             serStatus1 = JsonConvert.DeserializeObject<GoogleUserOutputData>(json_data);
                         }
                     }
                     else
                     { }
                 }
                 else
                 { }
             }
             return serStatus1;
         }
    
         public class GoogleUserOutputData
         {
             public string id { get; set; }
             public string name { get; set; }
             public string given_name { get; set; }
             public string email { get; set; }
             public string picture { get; set; }
         }
         public class GooglePlusAccessToken
         {
             public string access_token { get; set; }
             public string token_type { get; set; }
             public int expires_in { get; set; }
             public string id_token { get; set; }
             public string refresh_token { get; set; }
         }
    
        #endregion
    

    根据我上面提供的工作示例添加来自 google 的 autentication 屏幕截图

    【讨论】:

      【解决方案3】:

      您可能会通过添加以下代码缺少 ConfigureAuth for Google 身份验证:

       app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
              {
                  ClientId = "*****************.googleusercontent.com",
                  ClientSecret = "********************"
      
              });
      

      在 Startup.Auth.cs 上

       public void ConfigureAuth(IAppBuilder app)
          {
              // Configure the db context, user manager and signin manager to use a single instance per request
              app.CreatePerOwinContext(ApplicationDbContext.Create);
              app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
              app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
      
              // Enable the application to use a cookie to store information for the signed in user
              // and to use a cookie to temporarily store information about a user logging in with a third party login provider
              // Configure the sign in cookie
              app.UseCookieAuthentication(new CookieAuthenticationOptions
              {
                  AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                  LoginPath = new PathString("/Account/Login"),
                  Provider = new CookieAuthenticationProvider
                  {
                      // Enables the application to validate the security stamp when the user logs in.
                      // This is a security feature which is used when you change a password or add an external login to your account.  
                      OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                          validateInterval: TimeSpan.FromMinutes(30),
                          regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                  }
              });            
              app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
      
              // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
              app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
      
              // Enables the application to remember the second login verification factor such as phone or email.
              // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
              // This is similar to the RememberMe option when you log in.
              app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
      
              // Uncomment the following lines to enable logging in with third party login providers
              //app.UseMicrosoftAccountAuthentication(
              //    clientId: "",
              //    clientSecret: "");
      
              //app.UseTwitterAuthentication(
              //   consumerKey: "",
              //   consumerSecret: "");
      
              //app.UseFacebookAuthentication(
              //   appId: "",
              //   appSecret: "");
      
              // The same with Facebook, Twitter, MicrosoftAccount 
              app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
              {
                  ClientId = "*****************.googleusercontent.com",
                  ClientSecret = "********************"
      
              });
      

      【讨论】:

        猜你喜欢
        • 2017-03-11
        • 1970-01-01
        • 2018-10-19
        • 1970-01-01
        • 2015-03-24
        • 2019-08-15
        • 2012-04-23
        • 2011-10-20
        • 2014-09-11
        相关资源
        最近更新 更多