4

たくさんの記事やフォーラムを読んでいますが、それでも理解できません... Visual Studio Express 2012 for Webと、MVC4 + Razor + EntityFrameworkCodeFirstを使用してインターネットアプリケーションを構築しています。

私が理解している限り、SimpleMembershipを使用したMVC4でのユーザーとロールの管理は、以前のバージョンよりも簡単で、かなり単純なはずです。

私のアプリケーションでは、特定のユーザーグループのみを承認する必要があります(たとえば、管理者のみが特定のページにアクセスできます)。これは、[Authorize]アノテーションにパラメーターを渡すことによって行われることを理解しています:[Authorize(Roles = "Admins")]しかし、これらのロールを作成するにはどうすればよいですか、またユーザーを追加するにはどうすればよいですか?

認証を要求するために、コントローラーメソッドの上にアノテーション[Authorize](パラメーターなし)を追加しました。これは、追加の構成を行ったり、他に何も追加したりすることなく機能しました。また、自動的に作成されたデータベースを見ると、UserId列とRoleId列を持つwebpages_UsersInRolesという名前のテーブルがあります。これらすべては、すべてがセットアップされて使用できるように見えるので、これは非常に単純なタスクでなければならないと私に思わせますが、私はどのように理解することができません;)

私がこれまでに試したのは(そしてそれは機能しませんでした)これでした:DropCreateDatabaseIfModelChangesから継承する「DataContextDbInitializer」クラスがあります。Seedメソッドはそのクラス内でオーバーライドされ、これを追加しました(System.Web.Securityをインポートする必要がありました)。

Membership.CreateUser("user1", "123456");
Roles.CreateRole("Admins");
Roles.AddUserToRole("user1", "Admins");

また、このタグをWeb.configファイルのタグに挿入しました。

<roleManager
enabled="true"
cacheRolesInCookie="true" >
</roleManager>

試してみるために、コントローラーのアクションメソッドの上に[Authorize(Roles = "Admins")]を追加し、「admin」としてログインしてそのメソッドにアクセスしようとしましたが、運が悪かったです:(

他に何が欠けているのかわかりません...誰かが私を狂わせているので、誰かがこれを案内してくれると本当に嬉しいです:P

ありがとう!

4

2 に答える 2

6

私の推測では、Seedメソッドは呼び出されていません。メソッドにブレークポイントを設定し、デバッガーで実行して、これが呼び出されていることを確認します。アプリケーションに他の変更を加えない限り、EF移行は使用されません。デフォルトでは、データベースはInitializeSimpleMembershipAttributeで初期化されます。次のコードに示すように、この属性がアカウントコントローラーに追加されていることがわかります。

[Authorize]
[InitializeSimpleMembership]
public class AccountController : Controller
{
  ....
}

このように、 AccountControllerにアクセスしたときにのみ呼び出されます。定義はFilters\InitializeSimpleMembershipAttribute.csにあります。これは、このクラスのコードスニペットであり、呼び出されない理由の手がかりになる可能性があります。

// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();

InitializeSimpleMembershipAttributeの多くのコードは、フォーム認証がMVCアプリケーションに使用されないシナリオを処理するために配置されています。常にフォーム認証を使用する場合は、このコードを削除して、データベースを自分で初期化できます。この属性をAccountControllerから削除し、独自の初期化コードをGlobal.asaxApplication_Startメソッドに配置するだけです。このようなものをApplication_Startメソッドに追加します

Database.SetInitializer<UsersContext>(new MyDBInitializer());

シードメソッドは次のようになります

WebSecurity.InitializeDatabaseConnection("DefaultConnection",
      "UserProfile", "UserId", "UserName", autoCreateTables: true);

var roles = (SimpleRoleProvider)Roles.Provider;
var membership = (SimpleMembershipProvider)Membership.Provider;

if (!roles.RoleExists("Admin"))
{
     roles.CreateRole("Admin");
}
if (membership.GetUser("user1", false) == null)
{
     membership.CreateUserAndAccount("user1", "123456");
}
if (!roles.GetRolesForUser("user1").Contains("Admin"))
{
    roles.AddUsersToRoles(new[] { "user1" }, new[] { "Admin" });
} 

WebSecurity.InitializeDatabaseConnectionメソッドを呼び出して、SeedメソッドでWebマトリックスセキュリティデータベースを初期化する必要があることに注意してください。

SimpleMembershipのシードに関する詳細情報は、サンプルプロジェクトの完全なソースコードを含むこのブログ投稿にあります。

于 2013-01-25T19:22:44.347 に答える
3

最後に、私はなんとかすべてを機能させることができました!

私のシードメソッドは次のようになります。

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

if (!Roles.RoleExists("Admins"))
{
    Roles.CreateRole("Admins");
}
if (!WebSecurity.UserExists("admin"))
{
    WebSecurity.CreateUserAndAccount("admin", "123456");
}
if (!Roles.GetRolesForUser("admin").Contains("Admins"))
{
    Roles.AddUsersToRoles(new[] { "admin" }, new[] { "Admins" });
}
base.Seed(context);

Global.asaxのApp_Startは次のようになります。

Database.SetInitializer(new DataContextDbInitializer());
DataContext c = new DataContext();
c.Database.Initialize(true);

これが実際に何かを行っているかどうかはわかりませんが、Web.configのsystem.webタグ内にこれがあります。

<roleManager enabled="true" cacheRolesInCookie="true" />

また、AccountControllerから[InitializeSimpleMembership]を削除し、AccountModelsのUsersContextクラスを削除しました。このビットを自分のコンテキストクラスに移動しました。

public DbSet<UserProfile> UserProfiles { get; set; }

次に、すべてが機能するかどうかをテストするために、HomeControllerのAbout()メソッドの上に[Authorize(Roles = "Admins")]アノテーションを使用します。正常に機能している場合は、HomeController / Aboutによって制御される[About]ページを表示できるようにするために、admin/123456としてログインする必要があります。どちらですか;)

于 2013-01-28T11:02:39.643 に答える