几天来,我一直在用这个头撞墙,但我终于有了一些有用的东西。有兴趣知道它是否是一个有效的解决方案!
首先,创建一个新的 OAuthClient:
public class TwitterClient : OAuthClient
{
/// <summary>
/// The description of Twitter's OAuth protocol URIs for use with their "Sign in with Twitter" feature.
/// </summary>
public static readonly ServiceProviderDescription TwitterServiceDescription = new ServiceProviderDescription
{
RequestTokenEndpoint =
new MessageReceivingEndpoint(
"https://api.twitter.com/oauth/request_token",
HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
UserAuthorizationEndpoint =
new MessageReceivingEndpoint(
"https://api.twitter.com/oauth/authenticate",
HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
AccessTokenEndpoint =
new MessageReceivingEndpoint(
"https://api.twitter.com/oauth/access_token",
HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
};
public TwitterClient(string consumerKey, string consumerSecret) :
base("twitter", TwitterServiceDescription, consumerKey, consumerSecret) { }
/// Check if authentication succeeded after user is redirected back from the service provider.
/// The response token returned from service provider authentication result.
protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response)
{
string accessToken = response.AccessToken;
string accessSecret = (response as ITokenSecretContainingMessage).TokenSecret;
string userId = response.ExtraData["user_id"];
string userName = response.ExtraData["screen_name"];
var extraData = new Dictionary<string, string>()
{
{"accesstoken", accessToken},
{"accesssecret", accessSecret}
};
return new AuthenticationResult(
isSuccessful: true,
provider: ProviderName,
providerUserId: userId,
userName: userName,
extraData: extraData);
}
}
重要的部分是将响应转换为 ITokenSecretContainingMessage。似乎响应一直都有 TokenSecret,但它只是在内部属性上。通过投射它,您可以访问公共财产。我不能说我喜欢这样做,但是我也不明白为什么DotNetOpenAuth Asp.Net 团队首先隐藏了该属性。一定有充分的理由。
然后在 AuthConfig 中注册这个客户端:
OAuthWebSecurity.RegisterClient( new TwitterClient(
consumerKey: "",
consumerSecret: ""), "Twitter", null);
现在,在 AccountController 的 ExternalLoginCallback 方法中,extraData 字典中提供了 accessSecret。