Archive

Archive for the ‘ASP.NET 4.5’ Category

ASP.NET Identity 2.0.0 が RTM になりました

Announcing RTM of ASP.NET Identity 2.0.0

表題どおりの内容がアナウンスされています。
VS2013のテンプレートで全面的に採用されている ASP.NET Identity ですが、はやくもバージョンが 2.0.0 になりました。
上記記事をみてもらうとわかりますが、1.0 では足りていないと感じていた機能がいろいろ追加されたようです。

  • アカウントのロック
  • 登録確認
  • パスワードリセット
  • ユーザーおよびロールの一覧

ここまできて、やっと使えるかなぁ。。。

名古屋のときはPPTをみてもらえばわかるようにVS2013のテンプレートは実開発に使うにはいまいちじゃね? という話でまとめたのですが、自分として問題と感じていた一番の原因が Identity のアップデートでクリアされるように感じています。
まぁ、まだしっかり見てませんけど。

記事内にあるようにサンプルも提供されていて、ユーザー管理とかまで含めた実装サンプルになっているようです。
これはきちんと解析してみる価値がありそうですね。
Blogネタとしてもよさそうです。
しばらくこの話になるかな?(w

名古屋での発表資料公開

昨日名古屋でお話しさせていただいた資料を公開しました。
時間配分ミスってスキャッフォールディングの話できなかった。。。
まぁ、スキャッフォールディングは直接テンプレートということでもないですから、、、と言い訳しておこう。

さわってみておもしろかったので、そのあたりたぶんこの Blog にまとめるかと思います。

 

ASP.NET Identity プロファイルの追加

この記事は One ASP.NET Advent Calendar 2013 の10日目の記事です。

デフォルトのテンプレートを利用している場合、ASP.NET Identity ではユーザーの情報として独自のデータ保持できるようにデータベースを拡張することが Entity Framework の Migration の機能を利用することで比較的簡単にできるようになっています。
どのような手順が必要か、は以下の記事で十分わかるかと。

Customizing profile information in ASP.NET Identity in VS 2013 templates

ということで、これで今回の記事は終わり、、、ではあまりに悲しいので、上記記事では ASP.NET MVC でやっているところを WebForms を使っても同じことができることを検証してみます。
サンプルアプリケーションとしては、以前の記事でつくったものにユーザーの表示名( DisplayName )を追加し、ログイン時の表示をユーザー名から表示名に変えてみることにします。

まず、  ApplicationUser クラスに DisplayName プロパティを追加します。

1

この状態で一度ビルドを実行しておいて、ここからは Entity Framework のマイグレーションの手順を実行します。
メニューから「ツール」-「ライブラリ パッケージ マネージャー」-「パッケージ マネージャー コンソール」とたどって、パッケージマネージャーコンソールを表示させます。
そこで

  1. Enamble-Migrations
  2. Add-Migration "DisplayName" <- 文字列は作成されるファイル/クラス名に使われるので他と区別できればなんでもよい
  3. Update-Database

と実行します。

2

えと、上記キャプチャで実行順まちがえてエラーになっているのはスルーの方向で(w

この操作により、 Migrations フォルダが作成され、DBの構成変更に必要なプログラムが自動生成されます。

3

また、実際に作成ずみの DB に DisplayName 項目が追加されます。

4

あとはこれを使っていくだけですね。

Register.aspx (ユーザー登録画面)に表示名の入力欄を追加します。

5

また、Register.aspx.cs ファイルに DisplayName を保存するプログラムを追記します。

6

とりあえず、DisplayName の登録についてはこれだけでOK。

表示のほうですが、 Site.Master.cs ファイルに DisplayName を取得する GetDisplayNmae() メソッドを以下のように追加します。

7

一度 UserManager オブジェクトを生成して、そこから UserID をキーに ApplicationUser オブジェクトをとりだし、 DisplayName を取得する、という手順を踏む必要があります。
また、 using で必要な名前空間を指定しておく必要があります。
この名前空間が正しく指定されていないと、たとえば Context.User.Identity オブジェクトは存在するのに GetUserId() メソッドが存在しない(ようにみえる)なんてことがあるので注意です。

で、このメソッドの追加ができたら、 Site.Master.aspx ファイルのユーザー名の表示箇所をこのメソッドに置き換えましょう。

8

さて、これで実行してみます。

9

こんな感じで登録すると

10

登録に成功するときちんと表示名が表示されるようになります。

以前もユーザーのプロファイルを保持する仕組みというのは存在していたんですが、使いにくいところがありました。
これならデータベースの構造もわかりやすいですね。

UserId をもとにログインしているユーザーのプロパティを取得する方法はこれでいいんですが。。。
管理者がすべてのユーザーの情報を表示したい、なんてときはどうするのがよいのか、今悩んでます。
直接 DB から取り出して利用するしかないのかなぁ。。。
このあたりはまだ宿題、ということで。

ASP.NET Identity を読み解く

前回の記事で ASP.NET Identity でなにができるのか、はざっくり説明しました。
で、これがどのように実現されているのか、を調べてみました。

まずは Web.config になにか情報がないか、もう一度確認してみると。。。

 

1

認証の設定モードを None にしているだけでなく、認証に利用する FormsAuthenticationModule をはずしています。
これ以上の情報は Web.config 内にはないようです。

では、ソースコードになにか情報はないか。

2

Startup.Auth.cs で UseCookieAuthentication メソッドを呼び出しています。
このメソッドは何をやっているんでしょう。。。
ということでいろいろ情報をさがしていくと、 Katana プロジェクトというものにいきつきました。

Katana プロジェクトの概要

このプロジェクトについては上記 MSDN マガジンの記事でみていただくとして。
Katana プロジェクトは Codeplex 上に展開されていますので、ここからソースコードを取り出すことができます。

http://katanaproject.codeplex.com/

テンプレートで利用されているすべてのモジュールのソースコードが存在するわけではありませんが、 UseCookieAuthentication メソッドについては CookieAuthenticationExtensions クラスのメソッドとしてソースを参照することができます。
で、 UseCookieAuthentication メソッドの内容は、ほぼこの2行。

app.Use(typeof(CookieAuthenticationMiddleware), app, options);
app.UseStageMarker(PipelineStage.Authenticate);

1行めは CookieAuthenticationMiddleware を利用するために登録している、といったところでしょうか。
で、2行めは HttpApplication の AuthenticateRequest イベントのタイミングで CookieAuthenticationMiddleware を利用することで登録される CookieAuthenticationHandler を実行する、ということになるのかな?
2行めの UseSategeMarker メソッドについては次の Blog の記事が参考になります。

OWIN Middleware in the IIS integrated pipeline

CookieAuthenticationHandler では認証チケット(cookie)を解析して、問題がなければ AuthenticationTicket を生成し、その内容が最終的には HttpContext 内の User オブジェクトに設定されるようです。

WebForms や ASP.NET MVC の承認の機能はこの User オブジェクトの中身をみて認証済みかどうか、といった判断をしているので、こちらは以前のまま、ということになるようです。

Startup.Auth.cs には UseGoogleAuthentication 他のメソッドがありますが、これらも大きな動きは同じようになっていると思われます。
ただ、 UseGoogleAuthentication の場合、

app.UseStageMarker(PipelineStage.Authenticate);

この UseStageMarker の設定が存在しないので、認証のタイミングはデフォルトの PreRequestHandlerExecute イベントのときになるのかな?

ASP.NET Identity をひととおり使う分にはこんなとこまで知ってる必要は「まったく」ないですが、ついつい調べちゃうのはプログラマの性ですかね(^^;
さて、疑問におもってたところがなんとなくは理解できたので、次は自分の要求にあったカスタマイズをどう実現していくか、という方向に走りますか。。。

カテゴリー:ASP.NET 4.5, ASP.NET Identity, VS2013

新しい認証の仕組み ー ASP.NET Identity

VS2013 では One ASP.NET という掛け声のもと、 ASP.NET の各種テンプレートが変更されました。
この変更で認証の仕組みがいままでのメンバーシップから ASP.NET Identity へと変わっています。
ASP.NET Identity がどういったものか、というのは次のサイトからたどっていろいろ見てもらうのがよいのですが。。。

ASP.NET Identity

まぁ、これで終わっちゃうのもなんなので、ざっくり紹介してみます。

上記のサイトでの紹介もほとんど ASP.NET MVC のテンプレートなので、ここではわざと WebForms としてプロジェクトを構築して確認することにします。

1

右側に「認証: 個人ユーザー アカウント」と設定されています。
「認証の変更」ボタンをクリックすることでこの設定を変えることができます。

2

ここでは変更せずに、個人ユーザーアカウントのままプロジェクトを作成します。

#というか、他のパターンをまだ検証していません。

さて、プロジェクトができたらルートフォルダの Web.confg の内容を確認してみましょう。

3

authentication mode は Forms ではなく ”None” です。
また、メンバーシップ、プロファイル、ロールはみんな「無効」です。
これで従来のメンバーシップが利用されていないことははっきりします。

ついでに、 Account フォルダの下にある Web.config の内容も確認してみましょう。

4

これは Manage.aspx というファイルにたいし、ログインしている必要がある、という従来どおりの設定ですね。
ここで、メンバーシップは使っていないものの、許可/拒否の設定は従来どおり、というのがわかります。

では実際にユーザー登録を行ってみましょう。
アプリケーションを実行し、登録リンクをクリックします。

5

ユーザーの登録画面が表示されるので、適当なユーザーを作成します。

6

ユーザー登録については、同じユーザー名がいる場合はエラーになります。
また、英数字以外は登録できません。
「.」をいれるだけでエラーになります。当然日本語も。
日本語はまぁいいんですけど、メールアドレスをユーザー名として使うこともできないんですね。
このあたりは拡張したくなるかも。。。

ユーザー登録が無事に終わると、ユーザー名が表示され、ログオフリンクが表示されます。

7

この状態でユーザー名をクリックすると、パスワードが変更できるようになっています。

8

ログオフしてからログインリンクをクリックすると、下記のようなログイン画面が表示されます。

10

登録したユーザーでログインできることを確認しておきましょう。

で、テンプレートで認証関係で実装されているのはこの程度のようです。
パスワードリマインダとかはありません。
まぁ、メールアドレス登録するところがないので、リマインダメールとか送れないわけですが。

こんな状態で ASP.NET Identity を使うのに意味があるの?と思われそうですが、SNSを使ったログインが可能になる、という大きな利点があります。

App_Start フォルダ内の Startup.Auth.cs ファイルを表示します。

9

上記のように app.UseGoogleAuthentication(); の行を有効にしましょう。
Google アカウント以外では Microsoft アカウント、Twitter、Facebook でのログイン機能が用意されています。
その中で Google アカウントはなんの設定もなく使えるので、これで試してみます。

アプリケーションを実行し、ログインリンクをクリックします。

11

右側に Google によるログインボタンが表示されます。
このボタンをクリックすると、Google アカウントのログイン画面が表示されます。

12

ここで Google アカウントでログインすると、利用する情報の許可のページが表示されます。

13

関連付けフォームが表示されるので、ユーザー名を入力します。

14

これで登録は完了します。
次回以降、Google アカウントでのログイン情報が保持されている間は Google によるログインボタンをクリックするだけでログインできます。
ログイン情報が消えた場合も、再度 Google でログインすることで関連づけしたユーザーとしてログインされることになります。

さて、登録したユーザーのデータはどこにあるのかみてみましょうか。
ソリューションエクスプローラーで「すべてのファイルを表示」の状態にすると、 App_Data フォルダ内に mdf ファイルが作成されていることがわかります。

15

この mdf ファイルをダブルクリックするとサーバーエクスプローラーにデータベースの情報が表示されますので、ここからテーブルの定義や中身を見ることができます。

16

ASPNET.mdf のころと比べるとテーブル構成も非常にシンプルになっていて、必要最低限の情報しか持たない感じですね。
メールアドレスの登録もない、というのは前に書きましたが、複数回ログインに失敗したときのアカウントロック等の機能もなさそうです。
このあたりは必要であれば自分で実装しろ、ということなのでしょう。

テンプレートの標準では、 ASP.NET Identity は EntityFramework を利用する形で実装されており、Entity Framework Migration の機能をつかうと拡張も簡単、という話が次のページに紹介されています。

Customizing profile information in ASP.NET Identity in VS 2013 templates

このあたりをからめて、すぐに必要になりそうな機能をどう実装したらいいか、これからまとめてみたいと考えてます。
さてさて、どうなるかな?

One ASP.NET と Web サイトプロジェクト

VisualStudio 2013 では One ASP.NET の概念にあわせ、Web アプリケーションのテンプレートの選択の仕方が変わりました。
新しいプロジェクトを選ぶと、Web 関係では次のように「ASP.NET Web アプリケーション」だけが選択できるようになっています。

1

ここで OK ボタンを押したあとで、Web Forms、MVC 等のどの技術を使うか選択することになります。

1-1

1-2

この画面をみると、選択した技術に加えて他の技術のフォルダーやコア参照が追加できることがわかります。
実際に使うかどうか別として、Web Forms と MVC のハイブリッドな環境なんかも簡単につくることができますね。

テンプレートで作成されるのは Web Froms でも MVC でも同じ内容のサンプルアプリケーションです。

2

新しいサンプルアプリケーションはレスポンシブデザインが採用され、ブートストラップに対応しています。
このあたりの詳細は .NET Week – エバンジェリストセミナーチャックさんのセッション武田さんのセッション をみていただくのがよいと思います。

さて、最初のプロジェクトの選択画面をよくみてください。
選択できるのは「ASP.NET Web アプリケーション」です。
「Web アプリケーション」 プロジェクトがまとめられている、となると、「Web サイト」 プロジェクトは??? という疑問がでてきませんか?

ということで、メニューから [ファイル]-[新規作成]-[Web サイト] と選択してみましょう。

3

残念ながら、こちらは以前と同じような選択画面がでてきます。
特に変わったところはありません。

ただし、 ASP.NET Web フォーム サイト を作成すると、そこで提供されるサンプルアプリケーションは Web Froms や MVC とまったく同じ内容になっています。

4

Web サイトのテンプレートでも認証の機能として新しく導入された ASP.NET Identity が利用されています。

# ASP.NET Identity については別に紹介する予定。。。

なので、ここまでは One ASP.NET といえますかねぇ。
実は、Web サイトのテンプレートとして Razor v3 を選択すると。。。

5

サンプルアプリケーションは以前のまま。

6

認証も SimpleMembership が利用されています。
このあたりは WebMatrix 側が変わってないため、そちらと互換性を持たせるためかなぁ、と思ってます。

サンプルアプリケーションの内容が変わったので、これからはその中身を少し追いかけていきますかね。
しばらくは大きく変わった ASP.NET Identity の話が中心になるかな。

最新の GridView なら、、、の裏側

間があいてしまいましたが。
前回の記事でほのめかしておいた、ItemType プロパティを設定したときになにが起きてるのか、というあたりをちょっとのぞいてみましょう。

まず、GridView の AutoGenerateCollumns プロパティを false にして、BoundField コントロールとして ID、Name、Mail の各項目を追加します。

image

こんな感じになります。
で、実行して動作を確認すると、、、

image

こんな動きをします。
ItemType を追加した直後とちょっとちがいますね?

さて、BoundField コントロールをすべて DynamicField コントロールに置き換えましょう。

image

これで動かすと、

image

はい、ItemType を追加したときと同じ動きになりました。

これでわかりますかね?
ItemType を設定する前は GridView の内部では BoundField コントロールが使われていて、ItemType を追加すると、DynamicField コントロールが使われるんですね。

GridView の内部で使われるコントロールが変化するあたりは ASP.NET 4 で追加された EnableDynamicData 拡張メソッドを利用したときと一緒です。
というか、拡張メソッドを利用するのはちょっと面倒だったんですが、ItemType プロパティを設定するだけで動くようになった、というのが正しいんですかね?

DynamicField コントロールは検証コントロールまで自動的に追加してくれるのでクライアント側の検証が動作するんですね。
クライアント側の検証では「控えめなバリデーション」が使われるようになったのは 4.5 からなんですが、そのあたりは kiyokura さんの Blog のこの記事で確認してもらうのがよいかな?

DynamicField コントロールについては別にもう少し掘り下げてみようかと思います。
というか、ちょっと面白い動きしたはずなんですが、いま確認とってないので確認でき次第まとめる、ということで。

DynamicField コントロール面白いんですけどね。
いかんせん、情報がないですよね。
EnableDynamicData 拡張メソッドの話も、日本語だと私の Blog の記事とナオキ君が CodeZine に書いた記事ぐらいしか見つからないし。。。

あ、ひとつ注意点を。
DynamicField コントロールを明示的に記述して使うとき、ItemType プロパティの設定を削除するとエラーになります。
VSUG Day でのセッションを聞かれた方は覚えてるかもしれませんが、最後のほうで DynamicField コントロール使おうとしてエラーになって動かなかったのはこのせいでした。

ItemType プロパティのからみで、もうひとつ。
ItemType プロパティを設定しなくてもモデルバインディングは動きます。
それは前回の記事の動作で確認できますよね。

このモデルバインディング、ASP.NET MVC のように汎用的に使えるといろいろと面白いんですが、WebForms ではどうやら特定のコントロールでのみ使えるような感じです。
このあたりもきちんと調べてみないと。。。

というところで、今回の記事はここまで。
次は、、、モデルバインディングの話が先になるかな?

カテゴリー:.NET, ASP.NET 4.5, ASP.NET 備忘録