私はこれで数日間頭を壁にぶつけていましたが、ついにうまくいくものがあります. ただし、それが有効な解決策であるかどうかを知りたいと思います!
まず、新しい 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 が含まれているように見えますが、これは内部プロパティのみです。キャストすることで、パブリック プロパティにアクセスできます。私はこれを行うのが好きだとは言えませんが、Asp.Net チームのDotNetOpenAuthが最初にプロパティを隠した理由も理解できません。正当な理由があるはずです。
次に、このクライアントを AuthConfig に登録します。
OAuthWebSecurity.RegisterClient( new TwitterClient(
consumerKey: "",
consumerSecret: ""), "Twitter", null);
これで、AccountController の ExternalLoginCallback メソッドで、extraData ディクショナリで accessSecret を使用できるようになりました。