トップ   差分 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

XMLに手を出した

おぼえがき・その3


今更だけど.Net Framework2.0
このページのケータイ用のも作るのはまた大変そうな予感。


Form認証にOpenIDを…(・∀・;)

…まずできるのか?ってところからスタート…

そもそも
・OpenIDを調べる
・.netの認証を調べる
…ところから始めなきゃいけなかった。

IISが絡んでくると途端にメンドクサイと思ってしまうな…
やりたいことはRaiting絡みで簡易アクセス制限付けたい。ってところ。

簡単そうなのでForm認証の方を実装。
マイクロソフトのチュートリアルからやっぱ簡単に実装できた。
けど後でログインUIがあることを知ったしそっちが推奨とか…まいっか!
で、アクセス用のパスとかを発行する手続きを実装…している時にふと
個人情報収集する必要もないんだから「そうだOpenIDにしよう」

…と思ったがハテ(´・ω・`)OpenIDとは?ってなもんだ。
どこかのブログパーツサイトでユーザー登録しなくても使えるのが便利だと思った仕掛けで
仕組みはまだわかっちゃいない。


その前に認証APIとか

OpenID…仕様読んでみたけど(´∀`)誰か翻訳して…って状態でとまどりそう。
なのでその前にLivedoorやYahooやはてなの認証APIを使ってみることにした

はてなの場合

当初はClickイベントで…と思ったが
サイト内をクリックしたときにいきなり認証画面になるようにしたので
認証後に許可ページに遷移しないといけない(ReturnUrl?パラメタに設定されている)。
ReturnUrl?を保持するには…はてなを呼び出してしまうのでやっぱURLパラメタ。
なので手順としては
1.はてな認証API呼び出し用のLink文字列をPage_Loadで生成
 (その際にReturnUrl?をセット)
2.はてなからのコールバックでその後の処理


四苦八苦したのがそのURLパラメタ。
あとプキー(#゚∀゚)MD5hex?!っていう暗号化。
はてなからサイト許可をしなかった時を考慮してないのでロジックが少し変

// はてな認証API
protected void Page_Load(object sender, EventArgs e)
{
  //ReturnUrl取得
  //認証ページはWebconfigのauthenticationで設定しているのでこんな取り方。
    //おそらくここにもはてなからのコールバックを考慮する必要があるかと。
  string redurl
    = FormsAuthentication.GetRedirectUrl(this.UserName.Text, false).ToString();
  
  //はてなAPI用リンク文字列生成
    //パラメタ名は小文字のみっぽい。
    string AuthUrl =
      "http://auth.hatena.ne.jp/auth?api_key=はてなからもらったAPIキー"
   + "&returl" + System.Web.HttpUtility.UrlDecode(redurl).ToString();
   + "&api_sig=";


  //シグニチャ生成
    string AuthSig = "はてなからもらったパス値";
    //連結する他のシグニチャはalpha順に
    //api_key以外のパラメタは少ないので手動。
    AuthSig += "api_key" + "はてなからもらったAPIキー";
    AuthSig += "returl" + System.Web.HttpUtility.UrlDecode(redurl).ToString();

    //MD5hexに変換
  //まずMD5 ASCIIでバイト変換すると巧く行く…
    byte[] authsigbit = UnicodeEncoding.ASCII.GetBytes(AuthSig);
    System.Security.Cryptography.MD5CryptoServiceProvider hsalgo =
                 new System.Security.Cryptography.MD5CryptoServiceProvider(); 
    byte[] md5sig = hsalgo.ComputeHash(authsigbit.Length);    
    //MD5→hexへ
  System.Text.StringBuilder result = new System.Text.StringBuilder();
    foreach (byte bits in md5sig){
       result.Append(bits.ToString("x2"));
    }
  string HashStr = result.ToString();
    AuthUrl += HashStr;

    //画面UIにセット。
    //HatenaLoginLinkはHyperLink。
    this.HatenaLoginLink.NavigateUrl = AuthUrl;
  
  
  //はてな認証APIからの戻りは同じくPage_Loadになるはず。
  //同ページにPost_Back(ボタンクリックとか)があるので…
    if (this.Page.IsPostBack)
    {
    //こういう書き方は多分…
    }
    else
    {
       //はてなからのコールバックを判定するのがこのパラメタ。
       if (this.Page.Request.QueryString.GetValues("cert") != null 
     && this.Page.Request.QueryString["cert"].Length > 0)
       {
           //certを取得
            string AuthCert = this.Page.Request.QueryString["cert"].ToString();
           //ReturnUrlを取得
            string ReturnUrl = "";
            if (this.Page.Request.QueryString.GetValues("returl") != null
              && this.Page.Request.QueryString["returl"].Length > 0)
            {
                ReturnUrl = this.Page.Request.QueryString["returl"].ToString();
            }
            else
            {
                //ReturnUrlが無かった時にトップページを表示。
                ReturnUrl = "トップページURL";
            }

            //はてなからログイン情報を取得するためのリクエスト文字列
            string AuthCertUrl
        = "http://auth.hatena.ne.jp/api/auth.xml?"
       + "api_key=はてなからもらったAPIキー"
       + "&cert=" + AuthCert
         + "&api_sig=";
      
            //シグニチャ
       string AuthCertSig =  "はてなからもらったパス値"
       + "api_key=はてなからもらったAPIキー"
       + "cert=" + AuthCert
      
      //MD5hex変換
      // 〜前述と同じなので中略〜
      //HashCertStrにMD5hex文字列をセット。
       
      //リクエスト文字列完成。
            AuthCertUrl += HashCertStr;

            //HTTP GET リクエストを投げて…
            WebRequest req = WebRequest.Create(AuthCertUrl);
            req.Method = "GET";
            req.Timeout = 1000;
      //XMLで取得。
            StreamReader sr
        = new StreamReader(req.GetResponse().GetResponseStream());

            //はてなから受け取ったストリーム(XML)を読めるようにする
            XmlDocument xml = new XmlDocument();
            xml.Load(sr);
            //読み込んだXMLのリーダーを生成
            XmlNodeReader xrder = new XmlNodeReader(xml);

            //エラー情報があるか探す。
            xrder.ReadToFollowing("has_error");
            try
            {
        //エラーがなければ制限ページへリダイレクト。
               if (String.Equals("false", xrder.ReadString()))
               {
                   sr.Dispose();
                   FormsAuthenticationTicket ticket
         = new FormsAuthenticationTicket("ユーザー名とか", false, 5000);
                    FormsAuthentication.SetAuthCookie("ユーザー名とか", false);
                    this.Page.Response.Redirect(ReturnUrl);
               }
               else
               {
           //エラー内容を表示
                  xrder.ReadToFollowing("message");
                  this.MsgOpen.Text
                     = xrder.ReadString() + ", Invalid credentials. Please try again.";
                  sr.Dispose();
               }
            }
            catch
            {
        //XMLを読むのに失敗した時の処理。
                this.MsgOpen.Text
         = xrder.ReadString() + ", Invalid credentials. Please try again.";
                sr.Dispose();
            }
         }
      }
}



Form認証のIDやパスを発行…

発行手続き実装(不採用の予定)に当たってイロイロ調べていると
こんなのみつけたASP.NETのブログシステム〜記事はXML〜
RSSでコメント領域までフィルタリングできるんだ〜。ウチもコレのっければよかったなぁ
とか考えながら…イヤイヤ。WEB上で書きこみする必要もないサイトだった、と本末転倒しそうになった。


(続く)

EOF


Last-modified: 2009-05-30 (土) 21:33:36 (5447d)