¿Cuál es el secreto para que la respuesta de reclamos funcione con DotNet OpenId?
-
08-07-2019 - |
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?
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>