Created
April 20, 2013 14:41
-
-
Save ichiroku11/5426204 to your computer and use it in GitHub Desktop.
DotNetOpenAuthのYConnect用OAuth 2.0クライアントのサンプル
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.IO; | |
| using System.Linq; | |
| using System.Net; | |
| using System.Text; | |
| using System.Web; | |
| using DotNetOpenAuth.AspNet.Clients; | |
| using DotNetOpenAuth.Messaging; | |
| using Newtonsoft.Json.Linq; | |
| namespace MvcApp { | |
| internal static class HttpWebResponseExtensions { | |
| public static string GetResponseBody(this HttpWebResponse response) { | |
| using(var stream = response.GetResponseStream()) | |
| using(var reader = new StreamReader(stream)) { | |
| return reader.ReadToEnd(); | |
| } | |
| } | |
| } | |
| internal static class DictionaryExtensions { | |
| public static IDictionary<string, string> AddIfNotEmpty(this IDictionary<string, string> dictionary, string key, string value) { | |
| if(!string.IsNullOrEmpty(value)) dictionary[key] = value; | |
| return dictionary; | |
| } | |
| } | |
| public class YahooClient : OAuth2Client { | |
| private static string Escape(string target) { | |
| return Uri.EscapeDataString(target); | |
| } | |
| private readonly string _appId; | |
| private readonly string _appSecret; | |
| public YahooClient(string appId, string appSecret) | |
| : base("yahoo") { | |
| _appId = appId; | |
| _appSecret = appSecret; | |
| } | |
| // AuthorizationエンドポイントのURIを取得 | |
| protected override Uri GetServiceLoginUrl(Uri returnUrl) { | |
| var builder = new UriBuilder("https://auth.login.yahoo.co.jp/yconnect/v1/authorization"); | |
| builder.Query = string.Join("&", | |
| "response_type=code", | |
| "client_id=" + Escape(_appId), | |
| "redirect_uri=" + Escape(returnUrl.AbsoluteUri), | |
| "scope=" + Escape("openid profile")); | |
| return builder.Uri; | |
| } | |
| // 取得したアクセストークンを使ってユーザ情報を取得 | |
| protected override IDictionary<string, string> GetUserData(string accessToken) { | |
| // UserInfo API | |
| var builder = new UriBuilder("https://userinfo.yahooapis.jp/yconnect/v1/attribute"); | |
| builder.Query = string.Join("&", "schema=openid"); | |
| var request = WebRequest.Create(builder.Uri); | |
| // Authorizationヘッダーにアクセストークンを含める | |
| request.Headers.Add( "Authorization", "Bearer " + Escape(accessToken)); | |
| // リクエスト送信 => ユーザ情報の取得 | |
| using(var response = (HttpWebResponse)request.GetResponse()) { | |
| if(response.StatusCode != HttpStatusCode.OK) return null; | |
| var json = response.GetResponseBody(); | |
| var userData = JObject.Parse(json); | |
| if(userData == null) return null; | |
| // "id"と"username"は必須 | |
| // todo: | |
| return new Dictionary<string, string>() | |
| .AddIfNotEmpty("id", (string)userData["user_id"]) | |
| .AddIfNotEmpty("username", (string)userData["name"]); | |
| } | |
| } | |
| // Tokenエンドポイントへリクエストを送信して、アクセストークンを取得 | |
| protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) { | |
| var request = WebRequest.Create("https://auth.login.yahoo.co.jp/yconnect/v1/token"); | |
| request.ContentType = "application/x-www-form-urlencoded"; | |
| request.Method = "POST"; | |
| // Basic認証 | |
| var credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes(_appId + ":" + _appSecret)); | |
| request.Headers.Add( "Authorization", "Basic " + credentials); | |
| // POSTデータ | |
| var postData = string.Join("&", | |
| "grant_type=authorization_code", | |
| "code=" + Escape(authorizationCode), | |
| "redirect_uri=" + Escape(returnUrl.AbsoluteUri)); | |
| // POSTデータをリクエストに書き込む | |
| request.ContentLength = postData.Length; | |
| using(var stream = request.GetRequestStream()) | |
| using(var writer = new StreamWriter(stream)) { | |
| writer.Write(postData); | |
| writer.Flush(); | |
| } | |
| // リクエスト送信 => アクセストークン取得 | |
| using(var response = (HttpWebResponse)request.GetResponse()) { | |
| if(response.StatusCode != HttpStatusCode.OK) return null; | |
| var json = response.GetResponseBody(); | |
| var tokenData = JObject.Parse(json); | |
| if(tokenData == null) return null; | |
| return (string)tokenData["access_token"]; | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
私も知りたい。