#title(OpenIDでログインできるサイトを作成する4) #contents *OpenIDでログインできるサイトを作成する4 [#cf9daf2d] 今回も[[DotNetOpenId>http://code.google.com/p/dotnetopenid/]]を使用して、ASP.NETでOpenIDでログインできるサイトを作成する方法を紹介します。今回は、DotNetOpenIdで用意されているコントローラを一切使用しない方法です。 **OpenIdRelyingPartyクラスを使う [#n19233c2] DotNetOpenIdには便利なコントロールが多数あるため、これらを使うとかなり楽ができます。しかし場合によってはこれらのコントロールを使えないこともあるでしょう。そのようなときは、OpenIdRelyingPartyクラスを使うことになります。 OpenIdRelyingPartyクラスを使った方法も決して難しくありません。認証の開始は、CreateRequestメソッドでIAuthenticationRequestを作成した後にRedirectToProviderメソッドを呼び出すだけです。認証に成功したかを判断するには、PageのLoadイベントハンドラでOpenIdRelyingPartyを作成し、ResponseプロパティのStatusの値を調べます。Authenticatedであれば認証に成功しています。 以下にOpenIdRelyingPartyクラスを使ったログインページの例を示します。ここではユーザーのメールアドレスも要求しています。 #code(vbnet){{ <%@ Page Language="vb" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) 'OpenIdRelyingPartyを作成する Dim rp As New DotNetOpenId.RelyingParty.OpenIdRelyingParty() '設定を変更する rp.Settings.RequireSsl = False Try 'IAuthenticationRequestを作成する Dim req As DotNetOpenId.RelyingParty.IAuthenticationRequest = _ rp.CreateRequest(TextBox1.Text) 'SREGで個人情報を要求する Dim cr As New DotNetOpenId.Extensions.SimpleRegistration.ClaimsRequest() cr.PolicyUrl = New Uri(Request.Url, _ Response.ApplyAppPathModifier("~/PrivacyPolicy.aspx")) cr.Email = DotNetOpenId.Extensions.SimpleRegistration.DemandLevel.Request req.AddExtension(cr) 'OPにリダイレクトする req.RedirectToProvider() Catch ex As DotNetOpenId.OpenIdException MessageLabel.Text = "エラー: " & ex.Message Catch ex As System.Net.WebException MessageLabel.Text = "エラー: " & ex.Message End Try End Sub Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) 'OpenIdRelyingPartyを作成する Dim rp As New DotNetOpenId.RelyingParty.OpenIdRelyingParty() If rp.Response IsNot Nothing Then '認証に成功したか調べる Select Case rp.Response.Status Case DotNetOpenId.RelyingParty.AuthenticationStatus.Authenticated '認証に成功したとき '個人情報を取得する Dim claims As DotNetOpenId.Extensions.SimpleRegistration. _ ClaimsResponse = rp.Response.GetExtension(Of _ DotNetOpenId.Extensions.SimpleRegistration.ClaimsResponse)() If claims IsNot Nothing Then Session("Email") = claims.Email End If 'ログインする。ユーザー名はClaimed Identifierを使う FormsAuthentication.RedirectFromLoginPage( _ rp.Response.ClaimedIdentifier, False) Exit Select Case DotNetOpenId.RelyingParty.AuthenticationStatus.Canceled 'キャンセルされたとき MessageLabel.Text = "キャンセルされました。" Exit Select Case DotNetOpenId.RelyingParty.AuthenticationStatus.Failed '失敗したとき MessageLabel.Text = "OpenIDの認証に失敗しました: " + _ rp.Response.Exception.Message Exit Select Case DotNetOpenId.RelyingParty.AuthenticationStatus.SetupRequired 'setupモードで認証を行う必要があるとき 'immediateモードで認証を行っていないのであれば、必要なし MessageLabel.Text = "setupモードで認証を行う必要があります。" Exit Select End Select End If End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title>OpenIDテスト</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="Label1" runat="server" AssociatedControlID="TextBox1" Text="OpenID : "></asp:Label> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp:Button ID="Button1" runat="server" Text="ログイン" onclick="Button1_Click" /> <br /> <br /> <asp:Label ID="MessageLabel" runat="server"></asp:Label> </div> </form> </body> </html> }} #code(csharp){{ <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button1_Click(object sender, EventArgs e) { //OpenIdRelyingPartyを作成する DotNetOpenId.RelyingParty.OpenIdRelyingParty rp = new DotNetOpenId.RelyingParty.OpenIdRelyingParty(); //設定を変更する rp.Settings.RequireSsl = false; try { //IAuthenticationRequestを作成する DotNetOpenId.RelyingParty.IAuthenticationRequest req = rp.CreateRequest(TextBox1.Text); //SREGで個人情報を要求する DotNetOpenId.Extensions.SimpleRegistration.ClaimsRequest cr = new DotNetOpenId.Extensions.SimpleRegistration.ClaimsRequest(); cr.PolicyUrl = new Uri(Request.Url, Response.ApplyAppPathModifier( "~/PrivacyPolicy.aspx")); cr.Email = DotNetOpenId.Extensions.SimpleRegistration.DemandLevel.Request; req.AddExtension(cr); //OPにリダイレクトする req.RedirectToProvider(); } catch (DotNetOpenId.OpenIdException ex) { MessageLabel.Text = "エラー: " + ex.Message; } catch (System.Net.WebException ex) { MessageLabel.Text = "エラー: " + ex.Message; } } protected void Page_Load(object sender, EventArgs e) { //OpenIdRelyingPartyを作成する DotNetOpenId.RelyingParty.OpenIdRelyingParty rp = new DotNetOpenId.RelyingParty.OpenIdRelyingParty(); if (rp.Response != null) { //認証に成功したか調べる switch (rp.Response.Status) { case DotNetOpenId.RelyingParty.AuthenticationStatus.Authenticated: //認証に成功したとき //個人情報を取得する DotNetOpenId.Extensions.SimpleRegistration.ClaimsResponse claims = rp.Response.GetExtension <DotNetOpenId.Extensions.SimpleRegistration.ClaimsResponse>(); if (claims != null) { Session["Email"] = claims.Email; } //ログインする。ユーザー名はClaimed Identifierを使う FormsAuthentication.RedirectFromLoginPage( rp.Response.ClaimedIdentifier, false); break; case DotNetOpenId.RelyingParty.AuthenticationStatus.Canceled: //キャンセルされたとき MessageLabel.Text = "キャンセルされました。"; break; case DotNetOpenId.RelyingParty.AuthenticationStatus.Failed: //失敗したとき MessageLabel.Text = "OpenIDの認証に失敗しました: " + rp.Response.Exception.Message; break; case DotNetOpenId.RelyingParty.AuthenticationStatus.SetupRequired: //setupモードで認証を行う必要があるとき //immediateモードで認証を行っていないのであれば、必要なし MessageLabel.Text = "setupモードで認証を行う必要があります。"; break; } } } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>OpenIDテスト</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="Label1" runat="server" AssociatedControlID="TextBox1" Text="OpenID : "></asp:Label> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp:Button ID="Button1" runat="server" Text="ログイン" onclick="Button1_Click" /> <br /> <br /> <asp:Label ID="MessageLabel" runat="server"></asp:Label> </div> </form> </body> </html> }} realmやreturn_toを変更するには、IAuthenticationRequestのRealmやReturnToUrlプロパティを変更します。または、OpenIdRelyingParty.CreateRequestメソッドのオーバーロードを使って、2番目、3番目のパラメータにrealmとreturn_toを指定することもできます。 上記の例ではページのLoadイベントハンドラで認証に成功したかを調べていますが、もしこのページにOpenIdLoginコントローラが設置されていればその必要はなく、OpenIdLoginコントローラが代わりにやってくれます。 **「Yahoo! JAPAN IDでログイン」ボタンを設置する [#td07804c] 例えばYahoo! JAPANではOpenID URLに「yahoo.co.jp」と入力して認証を行うことができます。これを利用して、「Yahoo! JAPAN IDでログイン」というリンクを作成して、このリンクをクリックしたときにYahoo! JAPANの認証画面にジャンプようにすることができます。 Yahoo! JAPANではこの様なリンクを作成したときのために、「Yahoo! JAPAN IDログインボタン」の画像が用意されています。このように専用のボタン画像が用意されているOPはYahoo! JAPANだけでなく、他にも以下のようなOPがあります。 -[[Yahoo! JAPAN>http://developer.yahoo.co.jp/other/openid/loginbuttons.html]] -[[mixi>http://developer.mixi.co.jp/openid/button]] -[[BIGLOBE>http://openid.biglobe.ne.jp/forrp.html]] -[[エキサイト>http://openid.excite.co.jp/in/inf/rp.php]] このような画像を利用したImageButtonコントロールを使って、「Yahoo! JAPAN IDでログイン」ボタンを設置する例を以下に示します。ここではボタンの画像に"btnXSYid.gif"という画像ファイルを使っていますので、この画像ファイルがアプリケーションのルートに置かれている必要があります。 なお現在Yahoo! JAPANのOpenIDはベータ版であり、HTTP(ポート番号80)、HTTPS(ポート番号443)上で実際のホスト名を使用しているRPしかサポートしていないため、テスト環境から実行すると「このサイトにはログインできません」というエラーが出るかもしれません。 #code(vbnet){{ <%@ Page Language="vb" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> Protected Sub ImageButton1_Click(ByVal sender As Object, _ ByVal e As ImageClickEventArgs) 'OpenIdRelyingPartyを作成する Dim rp As New DotNetOpenId.RelyingParty.OpenIdRelyingParty() Try 'IAuthenticationRequestを作成する Dim req As DotNetOpenId.RelyingParty.IAuthenticationRequest = _ rp.CreateRequest("yahoo.co.jp") 'OPにリダイレクトする req.RedirectToProvider() Catch ex As DotNetOpenId.OpenIdException MessageLabel.Text = "エラー: " & ex.Message Catch ex As System.Net.WebException MessageLabel.Text = "エラー: " & ex.Message End Try End Sub Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) 'OpenIdRelyingPartyを作成する Dim rp As New DotNetOpenId.RelyingParty.OpenIdRelyingParty() If rp.Response IsNot Nothing Then '認証に成功したか調べる Select Case rp.Response.Status Case DotNetOpenId.RelyingParty.AuthenticationStatus.Authenticated '認証に成功したとき 'ログインする。ユーザー名はClaimed Identifierを使う FormsAuthentication.RedirectFromLoginPage( _ rp.Response.ClaimedIdentifier, False) Exit Select Case DotNetOpenId.RelyingParty.AuthenticationStatus.Canceled 'キャンセルされたとき MessageLabel.Text = "キャンセルされました。" Exit Select Case DotNetOpenId.RelyingParty.AuthenticationStatus.Failed '失敗したとき MessageLabel.Text = "OpenIDの認証に失敗しました: " + _ rp.Response.Exception.Message Exit Select End Select End If End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title>OpenIDテスト</title> </head> <body> <form id="form1" runat="server"> <div> <asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/btnXSYid.gif" onclick="ImageButton1_Click" /> </div> <asp:Label ID="MessageLabel" runat="server"></asp:Label> </form> </body> </html> }} #code(csharp){{ <%@ Page Language="C#" %> <%@ Register assembly="DotNetOpenId" namespace="DotNetOpenId.RelyingParty" tagprefix="RP" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void ImageButton1_Click(object sender, ImageClickEventArgs e) { //OpenIdRelyingPartyを作成する DotNetOpenId.RelyingParty.OpenIdRelyingParty rp = new DotNetOpenId.RelyingParty.OpenIdRelyingParty(); try { //IAuthenticationRequestを作成する DotNetOpenId.RelyingParty.IAuthenticationRequest req = rp.CreateRequest("yahoo.co.jp"); //OPにリダイレクトする req.RedirectToProvider(); } catch (DotNetOpenId.OpenIdException ex) { MessageLabel.Text = "エラー: " + ex.Message; } catch (System.Net.WebException ex) { MessageLabel.Text = "エラー: " + ex.Message; } } protected void Page_Load(object sender, EventArgs e) { //OpenIdRelyingPartyを作成する DotNetOpenId.RelyingParty.OpenIdRelyingParty rp = new DotNetOpenId.RelyingParty.OpenIdRelyingParty(); if (rp.Response != null) { //認証に成功したか調べる switch (rp.Response.Status) { case DotNetOpenId.RelyingParty.AuthenticationStatus.Authenticated: //認証に成功したとき //ログインする。ユーザー名はClaimed Identifierを使う FormsAuthentication.RedirectFromLoginPage( rp.Response.ClaimedIdentifier, false); break; case DotNetOpenId.RelyingParty.AuthenticationStatus.Canceled: //キャンセルされたとき MessageLabel.Text = "キャンセルされました。"; break; case DotNetOpenId.RelyingParty.AuthenticationStatus.Failed: //失敗したとき MessageLabel.Text = "OpenIDの認証に失敗しました: " + rp.Response.Exception.Message; break; } } } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>OpenIDテスト</title> </head> <body> <form id="form1" runat="server"> <div> <asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/btnXSYid.gif" onclick="ImageButton1_Click" /> </div> <asp:Label ID="MessageLabel" runat="server"></asp:Label> </form> </body> </html> }} **次回予告 [#m14ba394] OpenIDでログインできるサイトを作成する方法は今回で終わりです。次回はOPを作成する方法というのが自然な流れかもしれませんが、需要がほとんどなさそうですので(OPがやたらと増えるのも考えものかもしれませんし)、どうなるかはまだ未定です。 **コメント [#m14cd5c1] #comment //これより下は編集しないでください #pageinfo([[:Category/.NET]] [[:Category/ASP.NET]],2009-07-29 (水) 01:57:07,DOBON!,2009-07-29 (水) 01:57:07,DOBON!) |