Skip to content

Instantly share code, notes, and snippets.

@ichiroku11
Created April 20, 2013 14:41
Show Gist options
  • Select an option

  • Save ichiroku11/5426204 to your computer and use it in GitHub Desktop.

Select an option

Save ichiroku11/5426204 to your computer and use it in GitHub Desktop.
DotNetOpenAuthのYConnect用OAuth 2.0クライアントのサンプル
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"];
}
}
}
}
@teasdfa

teasdfa commented Apr 9, 2015

Copy link
Copy Markdown

私も知りたい。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment