Asp.net mvc 4 MVC4和x27;s DotNetOpenAuth TwitterClient示例不尊重以前的登录
如果我使用Asp.net mvc 4 MVC4和x27;s DotNetOpenAuth TwitterClient示例不尊重以前的登录,asp.net-mvc-4,twitter-oauth,dotnetopenauth,Asp.net Mvc 4,Twitter Oauth,Dotnetopenauth,如果我使用Internet应用程序模板创建ASP.NET MVC 4 Web应用程序,它将预安装使用一系列OAuth和OpenID提供程序实现身份验证所需的所有组件和配置。只需将我的Twitter用户密钥和密码添加到AuthConfig.cs即可激活通过Twitter的身份验证 然而,它似乎并不像我预期的那样有效 如果我尝试使用Twitter进行身份验证,无论我是否已登录Twitter,它都会显示一个Twitter登录页面。它还将我从Twitter注销,这样我就不得不在下次访问Twitter时重
Internet应用程序
模板创建ASP.NET MVC 4 Web应用程序,它将预安装使用一系列OAuth和OpenID提供程序实现身份验证所需的所有组件和配置。只需将我的Twitter用户密钥和密码添加到AuthConfig.cs
即可激活通过Twitter的身份验证
然而,它似乎并不像我预期的那样有效
如果我尝试使用Twitter进行身份验证,无论我是否已登录Twitter,它都会显示一个Twitter登录页面。它还将我从Twitter注销,这样我就不得不在下次访问Twitter时重新进行身份验证
这是一个bug,还是需要一些额外的配置来将其转换为更常见的无缝工作流程(对于其他提供商,如谷歌,该工作流程正常工作)
提前谢谢
蒂姆如果其他人遇到这个问题,我将在这里介绍我的发现(以及一个相当丑陋的解决方法) 使用Fiddler检查
DotNetOpenAuth
和Twitter之间的HTTP流量,很明显身份验证请求包含force\u login=false
querystring参数,这表明DNOA工作正常。但是,如果我使用Fiddler的脚本功能来修改出站请求并删除force_login
参数,那么一切都会正常工作。我猜想Twitter的实现在这里是错误的,因为它将任何force\u login
参数的存在视为等同于force\u login=true
由于我认为不可能让Twitter修改其API的行为,因此我已经调查了是否有更易访问的解决方案
查看DNOA代码,我看到force\u login=false
参数通过DotNetOpenAuthWebConsumer.RequestAuthentication()
方法无条件地添加到HTTP请求中(并在需要时修改为true
)
因此,理想的解决方案是DNOA对其身份验证请求参数提供更细粒度的控制,TwitterClient
明确删除force\u login=false
参数。不幸的是,当前的DNOA代码库并不直接支持这一点,但是通过创建两个自定义类可以实现相同的效果
第一个是IOAuthWebWorker
的自定义实现,它是原始DotNetOpenAuthWebConsumer
类的直接副本,只有一行更改将重定向参数字典初始化为空字典:
using System;
using System.Collections.Generic;
using System.Net;
using DotNetOpenAuth.AspNet.Clients;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth;
using DotNetOpenAuth.OAuth.ChannelElements;
using DotNetOpenAuth.OAuth.Messages;
namespace CustomDotNetOpenAuth
{
public class CustomDotNetOpenAuthWebConsumer : IOAuthWebWorker, IDisposable
{
private readonly WebConsumer _webConsumer;
public CustomDotNetOpenAuthWebConsumer(ServiceProviderDescription serviceDescription, IConsumerTokenManager tokenManager)
{
if (serviceDescription == null) throw new ArgumentNullException("serviceDescription");
if (tokenManager == null) throw new ArgumentNullException("tokenManager");
_webConsumer = new WebConsumer(serviceDescription, tokenManager);
}
public HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint profileEndpoint, string accessToken)
{
return _webConsumer.PrepareAuthorizedRequest(profileEndpoint, accessToken);
}
public AuthorizedTokenResponse ProcessUserAuthorization()
{
return _webConsumer.ProcessUserAuthorization();
}
public void RequestAuthentication(Uri callback)
{
var redirectParameters = new Dictionary<string, string>();
var request = _webConsumer.PrepareRequestUserAuthorization(callback, null, redirectParameters);
_webConsumer.Channel.PrepareResponse(request).Send();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_webConsumer.Dispose();
}
}
}
}
创建了这两个自定义类之后,实现只需要在MVC4AuthConfig.cs
文件中注册新的CustomTwitterClient
类的实例:
OAuthWebSecurity.RegisterClient(new CustomTwitterClient("myTwitterApiKey", "myTwitterApiSecret"));
OAuthWebSecurity.RegisterClient(new CustomTwitterClient("myTwitterApiKey", "myTwitterApiSecret"));