claimsResponse Return Null

2019-04-28 13:56发布

hello i have a following code in asp.net. i have used DotNetOpenAuth.dll for openID. the code is under

protected void openidValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
    // This catches common typos that result in an invalid OpenID Identifier.
    args.IsValid = Identifier.IsValid(args.Value);
}

protected void loginButton_Click(object sender, EventArgs e)
{
    if (!this.Page.IsValid)
    {
        return; // don't login if custom validation failed.
    }
    try
    {
        using (OpenIdRelyingParty openid = this.createRelyingParty())
        {
            IAuthenticationRequest request = openid.CreateRequest(this.openIdBox.Text);

            // This is where you would add any OpenID extensions you wanted
            // to include in the authentication request.
            ClaimsRequest objClmRequest = new ClaimsRequest();
            objClmRequest.Email = DemandLevel.Request;
            objClmRequest.Country = DemandLevel.Request;
            request.AddExtension(objClmRequest);

            // Send your visitor to their Provider for authentication.
            request.RedirectToProvider();
        }
    }
    catch (ProtocolException ex)
    {
        this.openidValidator.Text = ex.Message;
        this.openidValidator.IsValid = false;
    }
}

protected void Page_Load(object sender, EventArgs e)
{
    this.openIdBox.Focus();
    if (Request.QueryString["clearAssociations"] == "1")
    {
        Application.Remove("DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.ApplicationStore");

        UriBuilder builder = new UriBuilder(Request.Url);
        builder.Query = null;
        Response.Redirect(builder.Uri.AbsoluteUri);
    }

    OpenIdRelyingParty openid = this.createRelyingParty();
    var response = openid.GetResponse();
    if (response != null)
    {
        switch (response.Status)
        {
            case AuthenticationStatus.Authenticated:
                // This is where you would look for any OpenID extension responses included
                // in the authentication assertion.
                var claimsResponse = response.GetExtension<ClaimsResponse>();
                State.ProfileFields = claimsResponse;
                // Store off the "friendly" username to display -- NOT for username lookup
                State.FriendlyLoginName = response.FriendlyIdentifierForDisplay;
                // Use FormsAuthentication to tell ASP.NET that the user is now logged in,
                // with the OpenID Claimed Identifier as their username.
                FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, false);
                break;
            case AuthenticationStatus.Canceled:
                this.loginCanceledLabel.Visible = true;
                break;
            case AuthenticationStatus.Failed:
                this.loginFailedLabel.Visible = true;
                break;

            // We don't need to handle SetupRequired because we're not setting
            // IAuthenticationRequest.Mode to immediate mode.
            ////case AuthenticationStatus.SetupRequired:
            ////    break;
        }
    }
}

private OpenIdRelyingParty createRelyingParty()
{
    OpenIdRelyingParty openid = new OpenIdRelyingParty();
    int minsha, maxsha, minversion;
    if (int.TryParse(Request.QueryString["minsha"], out minsha))
    {
        openid.SecuritySettings.MinimumHashBitLength = minsha;
    }
    if (int.TryParse(Request.QueryString["maxsha"], out maxsha))
    {
        openid.SecuritySettings.MaximumHashBitLength = maxsha;
    }
    if (int.TryParse(Request.QueryString["minversion"], out minversion))
    {
        switch (minversion)
        {
            case 1: openid.SecuritySettings.MinimumRequiredOpenIdVersion = ProtocolVersion.V10; break;
            case 2: openid.SecuritySettings.MinimumRequiredOpenIdVersion = ProtocolVersion.V20; break;
            default: throw new ArgumentOutOfRangeException("minversion");
        }
    }
    return openid;
}

for above code I am always getting

var claimsResponse = response.GetExtension<ClaimsResponse>();

I am always getting claimsResponse == null. What is the reason why it happen. Is there any requirement which is required for openid like domain validation for RelyingParty?? please give me answer as soon as possible.

3条回答
混吃等死
2楼-- · 2019-04-28 13:57

Also make sure that you have registered the information on your OpenID-account on the provider website, and allowed the information to be sent during the login process. I had the same problem using DotNetOpenAuth but it turned out the I hadn't entered the information on my myOpenID-account. Thought that the email address is always sent, but that is not the case even though the OpenID account is connected to a email address.

So on myOpenID make sure that you have a Registration Persona (Your Account->Registration Personas)

查看更多
Melony?
3楼-- · 2019-04-28 13:58

I dont know if you have solved the problem or not, but I found the solution after many hours of struggle. Actually you need to change your web.config file to claim email and fullname here is web.config which works for me. I downloaded it from nerddinner project. Actually I copied everything except web.config and I was not getting the email field. So later on I found something else is wrong. I copied web.config from nerddinner project and everything was working.

here is the file, if you dont want to go to nerddinner project.

<?xml version="1.0" encoding="utf-8"?>
<!-- 
    Note: As an alternative to hand editing this file you can use the 
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in 
    machine.config.comments usually located in 
    \Windows\Microsoft.Net\Framework\v2.x\Config 
-->
<configuration>
  <configSections>
    <sectionGroup name="elmah">
     </sectionGroup>
    <section name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection" requirePermission="false" allowLocation="true" />
  </configSections>
  <connectionStrings configSource="connectionStrings.config">
  </connectionStrings>
  <dotNetOpenAuth>
    <openid>
      <relyingParty>
        <behaviors>
          <add type="DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth" />
        </behaviors>
      </relyingParty>
    </openid>
  </dotNetOpenAuth>
  <system.web>
    <!-- 
            Set compilation debug="true" to insert debugging 
            symbols into the compiled page. Because this 
            affects performance, set this value to true only 
            during development.
    -->
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </assemblies>
    </compilation>
    <!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
    -->
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Logon" />
    </authentication>
    <membership>
      <providers>
        <clear />
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/" />
      </providers>
    </membership>
    <profile>
      <providers>
        <clear />
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" applicationName="/" />
      </providers>
    </profile>
    <roleManager enabled="false">
      <providers>
        <clear />
        <add connectionStringName="ApplicationServices" applicationName="/" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        <add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      </providers>
    </roleManager>
    <customErrors mode="RemoteOnly" defaultRedirect="/Dinners/Trouble">
      <error statusCode="404" redirect="/Dinners/Confused" />
    </customErrors>

    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Globalization" />
        <add namespace="System.Linq" />
        <add namespace="System.Collections.Generic" />
      </namespaces>
    </pages>
    <httpHandlers>
      <add verb="*" path="*.mvc" validate="false" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
    </httpHandlers>
    <httpModules>
    </httpModules>
    <trace enabled="true" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
  </system.web>
  <!-- 
        The system.webServer section is required for running ASP.NET AJAX under Internet
        Information Services 7.0.  It is not necessary for previous version of IIS.
  -->
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
    </modules>
    <handlers>
      <remove name="MvcHttpHandler" />
      <remove name="UrlRoutingHandler" />
      <add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
    </handlers>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <appSettings>
    <add key="microsoft.visualstudio.teamsystems.backupinfo" value="8;web.config.backup" />
    <!-- Fill in your various consumer keys and secrets here to make the sample work. -->
    <!-- You must get these values by signing up with each individual service provider. -->
    <!-- Twitter sign-up: https://twitter.com/oauth_clients -->
    <add key="twitterConsumerKey" value="" />
    <add key="twitterConsumerSecret" value="" />
  </appSettings>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>
</configuration>
查看更多
再贱就再见
4楼-- · 2019-04-28 14:01

It looks like you're doing everything right. At this point it depends on the Provider you're using. Which one are you testing against? Some don't support Simple Registration (ClaimsRequest) at all. Others only support it for whitelisted RPs. Then others don't support it when your RP is at "localhost".

My advice: test against myopenid.com, as that seems to have good, consistent behavior and support for the Simple Registration extension. But your RP must always be prepared to receive null for ClaimsResponse, since you're never guaranteed the OP will give you anything.

Even if you get a non-null result, individual fields that you asked for (even if you marked them required) may be null or blank.

查看更多
登录 后发表回答