ASP.NET IdentityでRoleを使う手順

ASP.NET Identity 2.0とは?

ASP.NET Identity 2.0が登場し、Visual Studio 2013の標準テンプレートに組み込まれるようになりました。

ONE ASP.NETMVCでもWebAPIでも使え、OWINでソーシャル連携ログイン、nugetでも簡単にインストールできるようになりました。

が、今までのASP.NETフォーム認証と似ているようで、設定方法など全く別物になりました。

基本的なことは以下のサイトをご覧いただけるとわかると思います。

ASP.NET Identity | どっとねっとふぁん

ASP.NET Identity入門:CodeZine(コードジン)

ただ単にユーザーの登録、ログインするだけなら、標準テンプレートで十分使えると思います。

 

ロールはどこに?

フォーム認証の頃から、ロールベースのアクセス制御ができたのですが、今のテンプレートにはロールに関するコードありません。

いくつかコードを追加するだけで使えるようになるので、まとめておきます。MVC 5でのコードです。

Models/IdentityModels.cs

public class ApplicationRole : IdentityRole
{
}

App_Start/IdentityConfig.cs

public class ApplicationRoleManager : RoleManager<ApplicationRole, string>
{
    public ApplicationRoleManager(IRoleStore<ApplicationRole, string> store)
        : base(store)
    {
    }
     public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
    {
        var manager = new ApplicationRoleManager(new RoleStore<ApplicationRole>(context.Get<ApplicationDbContext>()));
        return manager;
    }
}

App_Start/Startup.Auth.cs

public partial class Startup
{
    // 認証設定の詳細については、http://go.microsoft.com/fwlink/?LinkId=301864 を参照してください
    public void ConfigureAuth(IAppBuilder app)
    {
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager≥(ApplicationUserManager.Create);
        
        // このコードを追加
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
    }
}

Controllers/AccountController.cs

public class AccountController : Controller
{
    private ApplicationUserManager _userManager; 
    private ApplicationRoleManager _roleManager;

    public AccountController()
    {
    }

    public AccountController(ApplicationUserManager userManager, ApplicationRoleManager roleManager, ApplicationSignInManager signInManager)
    {
        UserManager = userManager;
        RoleManager = roleManager;
        SignInManager = signInManager;
    }

    public ApplicationRoleManager RoleManager
    {
        get
        {
            return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();
        }
        private set
        {
            _roleManager = value;
        }
    }
}

 

これでビルドするとAccountController上でRoleManagerがつかえるようになります。

すでにDBが作成されている場合サーバーエラーが発生します。

データベースの作成後、'ApplicationDbContext' コンテキストの背後にあるモデルが変更されました。Code First Migrations を使用したデータベースの更新を検討してください (http://go.microsoft.com/fwlink/?LinkId=238269)。
  説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。 
 この場合データベースの更新が必要です。

パッケージマネージャで以下のコマンドを実行します。

PM> Enable-Migrations
コンテキストが既存のデータベースを対象にしているかをチェックしています...
データベース初期化子で作成されたデータベースが検出されました。既存のデータベースに対応する移行 '201410121217026_InitialCreate' がスキャフォールディングされました。代わりに自動移行を使用するには、Migrations フォルダーを削除し、-EnableAutomaticMigrations パラメーターを指定して Enable-Migrations を再実行します。
Code First Migrations がプロジェクト WebApplicationIdentity で有効になりました。
PM> Add-Migration "AddRole"
移行 'AddRole' をスキャフォールディングしています。
この移行ファイルのデザイン コードには、現在の Code First モデルのスナップショットが含まれています。このスナップショットは次の移行をスキャフォールディングする際、モデルに対する変更の計算に使用されます。モデルに追加の変更を行い、この移行に含める場合は、'Add-Migration AddRole' を再実行して再度スキャフォールディングできます。
PM> Update-Database
ターゲット データベースに適用されている SQL ステートメントを表示するには、'-Verbose' フラグを指定します。
明示的な移行を適用しています: [201410121336408_AddRole]。
明示的な移行を適用しています: 201410121336408_AddRole。
Seed メソッドを実行しています。

すでに別のEntity Frameworkでcontextが作成されている場合は、Enable-Migrations -ContextTypeName [context名]で、Context名を指定できますので、ApplicationDbContextを指定してください。

ロール(RoleManager)を使う

RoleManager.Rolesプロパティでロールの一覧が取得できます。

RoleManager.RoleExistsメソッドで存在確認、Createメソッドで作成ができます。

~Asyncもありますので必要な方を使ってください。

 

ユーザーとロールの関連は、UserManager.AddToRole、AddToRoles、GetRoles、IsInRole、RemoveFromRole、RemoveFromRolesメソッドなどで操作できます。

 

mvcのコントローラーでロールのアクセス制御をする場合は、依然と同様で、

[Authorize(Roles = "ロール名")]

で使用できます。

 

ASP.NET関連本

 

独習ASP.NET 第4版

独習ASP.NET 第4版

 

 

 

プログラミング MICROSOFT ASP.NET4 (Microsoft Press)

プログラミング MICROSOFT ASP.NET4 (Microsoft Press)

 

 

 

 

昔書いたコードのEntityFrameworkを6.0にバージョンアップしたら、いろいろ困ったという話

昔書いたコードのEntityFrameworkを6.0にバージョンアップして、

モデルを作り直したら、ObjectContextからDbContextへ変わってしまって、対応に追われました。

コードの修正したので結果を書いておきます。

 

何がどう変わったのか

Entity Framework 4.1でDbContext APIが追加され、軽量なDbContextクラスが追加されました。
2011年ごろだったと思いますので、すでに3年前のことです。

ADO.NET Entity Framework 4.1 における Code First

 

まずEntityFrameworkのバージョンと、データベースファーストでのObjectContext/DbContextの関係を整理します。
EF4.0までは、ObjectContext
EF5では、.NET 4.5の場合DbContext、.NET 4.0の場合はObjectContext(EFのバージョンは4.4でした)
EF6では、.NET 4.0でもDbContextとなりました。

なんでこんな複雑なことになっているのかは、EF5が、.NET4.5のコアに関連したようですが、EF6でそれが解消されたようです。

Entity Framework 5 のパフォーマンスに関する考慮事項
Entity Framework 6: 上級者向けエディション

バージョンアップしてモデルを作り直したら何が起きたか?

ほとんどは問題ないのですが、一部整理された部分があるので、そこだけコードの修正が必要です。
修正はめんどうですが、整理されてわかりやすくなっていると思います。

 

SQLコマンドの実行

ObjectContext.ExecuteStoreCommand メソッド から
DbContext.Database.ExecuteSqlCommand メソッド へ変わりました。


何かデータベースへ作用させるものは、dbContext.Databaseへまとめたということのようです。
当然CommandTimeoutなんかも移動しています。


変更の追跡

ObjectContext.ObjectStateManager プロパティ から
DbContext.ChangeTracker プロパティ へ変わりました。

 

GetObjectStateEntries()とか長い名前がEntries()になり、
HasChanges()なんかもついて、スッキリ便利になってます。


データベースのオプション

ObjectContext.ContextOptions プロパティ から
DbContext.Configuration プロパティ に変わりました。


エンティティーセットとクエリ

ObjectContext.ObjectSet<TEntity>から
DbContext.DbSet<TEntity>に変わりました。

 

エンティティーセットをWhereしてみると結果が
ObjectQuery<T>から
IQueryable<T>に変わりました。

 

SQLクエリの実行が
ObjectContext.ExecuteStoreQueryから
DbSet<TEntity>.SqlQueryに変わりました。


Windows FormsのBindingSource

ここが少し面倒でした。
今まではそのままクエリ結果等をDataSourceへ渡すだけでよかったのですが、
EntityFrameworkを実行すると、System.NotSupportedExceptionが発生します。

 

追加情報:ストア クエリ (DbSet、DbQuery、DbSqlQuery、DbRawSqlQuery) への直接のデータ バインドはサポートされていません。
代わりに、DbSet で Load を呼び出すなどして DbSet にデータを設定し、ローカル データにバインドしてください。
WPF の場合は DbSet.Local に、WinForms の場合は DbSet.Local.ToBindingList() にバインドします。
ASP.NET WebForms の場合は、クエリで ToList() を呼び出した結果にバインドしたり、モデル バインドを使用したりできます。
詳細については、http://go.microsoft.com/fwlink/?LinkId=389592 を参照してください。

だそうです。

 

結局どうすればいいのかというところですが、

 

データ取得のみの場合には、ToList()などでList<T>にしてしまえば問題ありません。

 

更新するデータソースの場合は、DbSet<TEntity>.Local プロパティが追加されていますので、それをDataSourceへ渡してあげればOKです。
その際あらかじめ、DbSet<TEntity>.Load()で読み込んであげてください。
あとはそのままで大丈夫でした。

 

DbSet<TEntity>.SqlQueryメソッドで取得したDbSqlQuery<TEntity>はLocalがありません。
そのままDataSourceへ渡してもエラーが出ます。
この場合は、ObservableCollectionを作成し、コンストラクタでDbSqlQuery<TEntity>を渡して、
作成したObservableCollectionをDataSourceへ渡してあげればOKです。
ここでしばらく嵌りました。

 

 

よくよく思い返してみれば、データアクセスの技術ってかなりの頻度で更新されてますね。

業務システムだと結構重要なところなので、非常に便利なのはいいけれど、コードの修正は大変です。

ADO.NETのDataSetとかの時代のプログラムをEntityFrameworkで書き直す気は起きません・・・。

 

 

 

 

Microsoft ADO.NET Entity Framework Step by Step (Step by Step Developer)

Microsoft ADO.NET Entity Framework Step by Step (Step by Step Developer)

 

 

Programming Entity Framework

Programming Entity Framework

 

  

Programming Entity Framework: DbContext

Programming Entity Framework: DbContext

  • 作者: Julia Lerman,Rowan Miller
  • 出版社/メーカー: Oreilly & Associates Inc
  • 発売日: 2012/03
  • メディア: ペーパーバック
  • クリック: 1回
  • この商品を含むブログを見る
 

  

Entity Framework 6 Recipes (Recipes Apress)

Entity Framework 6 Recipes (Recipes Apress)

  • 作者: Brian Driscoll,Nitin Gupta,Rob Vettor,Zeeshan Hirani,Larry Tenny
  • 出版社/メーカー: Apress
  • 発売日: 2013/10/29
  • メディア: ペーパーバック
  • この商品を含むブログを見る
 

   

Entity Framework 4.0 Recipes: A Problem-Solution Approach (Expert's Voice in .NET)

Entity Framework 4.0 Recipes: A Problem-Solution Approach (Expert's Voice in .NET)

 

 

Entity Framework 6

Entity Framework 6

 

 

 

ITシステムの安定性が高いと、顧客満足度が下がってしまうのか?というお話

ITシステムはトラブルがなくて安定的に使える方がいい。

当たり前です。誰でもそうだということでしょう。

 

トラブルが発生し、それを解消すると喜ばれるというのも事実。

(もちろんトラブルが多すぎれば、悪印象なのは当然です。)

安定したシステムはそれがない。=喜ばれる機会が少ない。

 

では、適度にトラブルがあり、それを解消していくことが一番顧客満足度が高いのか?となってしまいます。ITのみならず、ほかの業種にも言えることだと思います。

一発で完璧な仕事をする人と、何度も修正修正しながら仕事をする人。

どちらがいいのでしょうか?

 

技術者の威信にかけて、安定したシステムを作りたい。

が、こういったジレンマに陥ることもけっこうあります。

 

不思議ですね。安定している方がいいに決まっているのに・・・。

Windows Server 2008 Hyper-VでVHDの最適化するときにエラーが発生した場合の対処(追加)

Windows Server 2008 Hyper-VでVHDの最適化するときにエラーが発生した場合の対処

このケースでも最適化できないケースが発生してしまいました。

 

が、ボリュームシャドーコピーを削除後、ディスクの最適化をすることで解消しました。

 

The Microsoft Conference 2013 Days2まとめ

Days 1まとめをご覧ください。

 

ほぼ1日開発系セッションに居座ってました。

開発者向けキーノート のCloud First, Mobile First, Developer First !というのがとてもよくマイクロソフトの行く先を示していると感じました。

 

思い出せば約1~2年前、

Windows Phoneが迷走しだし、Windows 8のスタートメニュー除去に関する不評、それに加えて日本においてのiOSの躍進から、マイクロソフトは大丈夫なのか?と不安に思っていました。

しかし、MSC2013に参加して、それらの不安がかなり払拭されました。

 

開発者として、マイクロソフトを支持する4つの理由。

1.VS2013は地味に良い改良が加えられている。

2.Windows Azureは必要なサービスがほぼ整って使わない理由が見つからない。

3.オープンな技術や、他社のデバイス、他社のサービスとの連携にも積極的な姿勢。

4.エンタープライズ品質。

ただし、2013年末時点で、ですがね。

 

 

あとイベント自体に苦言があるとすれば、セッションの立見がかなり頻発していたのはちょっとまずいのではないのかな?ただでさえ2日間かんづめで疲れているのに。

 

The Microsoft Conference 2013 Days1まとめ

The Microsoft Conference 2013 に参加してきました。

色々なセッションがありましたので、すべては網羅できませんが、私が気になった事をまとめてみます。

続きを読む

Windows 8.1 Proがやってきた。SurfaceProに入れてみた。

10月17日20時 Windows 8.1の提供が始まりました。

3.63GBとかなり大きいのでダウンロードに時間はかかりますが、ダウンロード中も作業は可能です。新機能を確認したりしてじっくり待ちましょう。

 

このアップデートでSurfaceがiPadのように人気になるか?といわれれば疑問ですが、企業向けの機能は着実に進化しており、ビジネスシーンでのタブレットとしてどんどん良くなっていくと思います。

 

 

@IT Windows 8.1クロスロード

http://www.atmarkit.co.jp/ait/subtop/features/win/win81_index.html

 

ASCII.jp 山市良の「企業ユーザーはここに注目しよう!Windows 8.1の新機能」

http://ascii.jp/elem/000/000/821/821824/

 

IT Media Enterprise Windows 8.1は選択肢になり得るか? マイクロソフトが推す法人向けの新機能

http://www.itmedia.co.jp/enterprise/articles/1310/14/news006.html

 

ZDNet Japan 「Windows 8.1」が10月17日から提供--BYOD対応などモバイル系機能を強化

http://japan.zdnet.com/os/analysis/35038436/

 

TechCrunch  Windows 8.1、太平洋時間で明日の午前4時〔日本時間今日の午後8時〕に一般公開

http://jp.techcrunch.com/2013/10/17/20131016windows-8-1-will-start-to-roll-out-tomorrow-at-4-am-pdt/

 

Windows 8.1 の新機能 - MSDN - Microsoft

http://msdn.microsoft.com/ja-jp/windows/apps/bg182409.aspx