Pregunta

¿Cuál es el secreto para que ClaimsResponse funcione con DotNetOpenId ?

Por ejemplo, en este código (del blog de Scott Hanselman ) el objeto ClaimsResponse debería tener muchas cosas bonitas como 'apodo' y 'dirección de correo electrónico', pero el objeto ClaimsResponse en sí mismo es 'nulo':

 OpenIdRelyingParty openid = new OpenIdRelyingParty();  
 if (openid.Response != null)  
 {  
    // Stage 3: OpenID Provider sending assertion response  
    switch (openid.Response.Status)  
    {  
       case AuthenticationStatus.Authenticated:  
          ClaimsResponse fetch = openid.Response.GetExtension(typeof(ClaimsResponse)) as ClaimsResponse;  
          string nick = fetch.Nickname;  
          string homepage = openid.Response.ClaimedIdentifier;  
          string email = fetch.Email;  
          string comment = Session["pendingComment"] as string;  
          string entryId = Session["pendingEntryId"] as string;  
          if (String.IsNullOrEmpty(comment) == false && String.IsNullOrEmpty(entryId) == false)  
          {  
             AddNewComment(nick, email, homepage, comment, entryId, true);  
          }  
          break;  
    }  
 }  

Al principio, pensé que era porque no estaba redirigiendo al proveedor con un 'ClaimsRequest' ... pero usar este código para redirigir al proveedor OpenId todavía no ayuda:

OpenIdRelyingParty openid = new OpenIdRelyingParty();  
IAuthenticationRequest req = openid.CreateRequest(openid_identifier.Text);  
ClaimsRequest fetch = new ClaimsRequest();  
fetch.Email = DemandLevel.Require;  
fetch.Nickname = DemandLevel.Require;  
req.AddExtension(fetch);  
req.RedirectToProvider(); 

¿Qué estoy haciendo mal? ¿O han experimentado otros desarrolladores el mismo dolor?

¿Fue útil?

Solución

Su código se ve bien. Pero tenga en cuenta que la extensión sreg, que está utilizando, no es compatible con todos los OP. Si el OP con el que se está autenticando no lo admite, entonces la extensión de respuesta será nula como está viendo. Por lo tanto, un cheque nulo siempre es una buena idea.

myopenid.com admite sreg, si está buscando un OP para probar.

Otros consejos

No sé si ha resuelto el problema o no, pero encontré la solución después de muchas horas de lucha. En realidad, debe cambiar su archivo web.config para reclamar el correo electrónico y el nombre completo aquí está web.config que funciona para mí. Lo descargué del proyecto nerddinner. En realidad, copié todo excepto web.config y no recibía el campo de correo electrónico. Entonces más tarde descubrí que algo más está mal. Copié web.config del proyecto nerddinner y todo estaba funcionando.

aquí está el archivo, si no desea ir al proyecto nerddinner.

<?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> 

Con la última versión de DotNet OpenId, este código parece funcionar bien para mí:

var request = openid.CreateRequest(openid_identifier);
var fields = new ClaimsRequest();
fields.Email = DemandLevel.Require;
fields.Nickname = DemandLevel.Require;
request.AddExtension(fields);
request.RedirectToProvider();

a la vuelta del proveedor:

var claimResponse = openid.Response.GetExtension<ClaimsResponse>();

PD: estoy usando MVC, no WebForms.

Utilicé

   /* worked */var fetch = new FetchRequest();
   fetch.Attributes.AddRequired(WellKnownAttributes.Contact.Email);
   request.AddExtension(fetch);

en lugar de

   /* didnt work*/
   var fields = new ClaimsRequest();
   fields.Email = DemandLevel.Require;
   fields.FullName = DemandLevel.Require;
   request.AddExtension(fields); 

Y en la respuesta intente

    this.Request.Params["openid.ext1.value.alias1"];

simplemente en lugar de acceder a los reclamos. Esto funcionó conmigo en ASP.Net para google.

El problema en ASP.Net es que la solicitud no se envía completa cuando se usa ClaimsRequest, puede ver que si usó Fiddler. y la respuesta tampoco se recupera correctamente si necesita acceder a los parámetros directos desde Request.params, todos están allí.

Ninguno de los anteriores funcionó para mí (usando PayPal Access como identificador) en C #

Lo siguiente funcionó para mí:

OpenIdRelyingParty openid = new OpenIdRelyingParty();

protected void Page_Load(object sender, EventArgs e)
{
    var response = openid.GetResponse();

    if (response != null)
    {
        switch (response.Status)
        {
            case AuthenticationStatus.Authenticated:

                if (this.Request.Params["openid.ext1.value.alias1"] != null)
                {
                    Response.Write(this.Request.Params["openid.ext1.value.alias1"]);
                    Response.Write(this.Request.Params["openid.ext1.value.alias2"]);
                }
                else {
                    Response.Write("Alias wrong");
                }
                break;
        }
    }
}
 protected void loginButton_Click(object sender, EventArgs e)
{

    var openidRequest = openid.CreateRequest(openIdBox.Text);
    var fetch = new FetchRequest();

    fetch.Attributes.AddRequired(WellKnownAttributes.Contact.Email);
    fetch.Attributes.AddRequired(WellKnownAttributes.Name.FullName);
    openidRequest.AddExtension(fetch);

    openidRequest.RedirectToProvider();

}

Podría recibir parámetros correctamente después de lo siguiente actualizado en web.config que copié de una muestra.

<section name="dotNetOpenAuth"
         type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection"
         requirePermission="false" 
         allowLocation="true"/>

bajo <configsections>

y agregue esto solo

<dotNetOpenAuth>
    <openid>
        <relyingParty>
            <behaviors>
                <add type="DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth"/>
            </behaviors>
        </relyingParty>
    </openid>
</dotNetOpenAuth>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top