0

ユーザーと管理者がコントローラー全体を表示できるが、管理者のみが作成、削除、および編集できる各方法にアプリケーションをロックダウンしようとしています。

メソッドを保持する CustomAuthorize クラスを作成しました。

 public class CustomAuthorize : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            Debug.WriteLine("Show me the filterContext " + filterContext);
            if (filterContext.Result is HttpUnauthorizedResult)
            {
                Debug.WriteLine("Why is this going to the redirect to AccessDenied?");
                filterContext.Result = new RedirectResult("~/AccessDenied/Index");
            }
        }
    }

私の RoleProvider クラス:

namespace Office.WebUI.Security {
    public class OfficeRoleProvider : RoleProvider
    {

        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override string ApplicationName
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override void CreateRole(string roleName)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            throw new NotImplementedException();
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            throw new NotImplementedException();
        }

        public override string[] GetAllRoles()
        {
            throw new NotImplementedException();
        }

        public override string[] GetRolesForUser(string username)
        {
            Debug.WriteLine("Get the username" + username);
            using (EFDbContext db = new EFDbContext()) >           
            {
                User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, >stringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));
                //User user = db.TaskPrivilege.FirstOrDefault(u => >u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));

                if (user != null)
                {
                    var roles = from ur in user.UserRoles
                                from r in db.Roles
                                where user.role.RoleID == r.RoleID
                                //where ur.RoleID == r.RoleID
                                select r.Name;
                    if (roles != null)
                        return roles.ToArray();
                    else
                        return new string[] { }; ;
                }
                else
                {
                    return new string[] { }; ;
                }
            }
        }

        public override string[] GetUsersInRole(string roleName)
        {
           throw new NotImplementedException();
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            Debug.WriteLine("The username is " + username + " And the Role it is using is >" + roleName);
            using (EFDbContext db = new EFDbContext())
            {
                User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));

                if (user != null)
                {
                    var roles = from ur in user.UserRoles
                                from r in db.Roles
                                where user.role.RoleID == r.RoleID
                                //where ur.RoleID == r.RoleID
                                select r.Name;
                    if (user != null)
                        return roles.Any(r => r.Equals(roleName, >StringComparison.CurrentCultureIgnoreCase));
                    else
                        return false;
                }
                else
                {
                    return false;
                }
            }
        }

        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override bool RoleExists(string roleName)
        {
            throw new NotImplementedException();
        }
    }

}

私のデータベースには、Role と RoleID を列として保持する Roles テーブルがあり、2 つの値が Administrator と User で、roleID が PK で、1 = Administrator & 2 = User です。UserID、Username、および role_RoleID を含む、Users という別のテーブル

ユーザーを role_RoleID に 1 (管理者) として割り当て、使用してコントローラーをロックダウンすると、

[CustomAuthorize(Roles = "管理者"]

これは機能します。

role_RoldID = 2 を割り当て、以下を使用してロックダウンすると:

[CustomAuthorize(Roles = "ユーザー"]

これはうまくいきませんか?

また、もう 1 つの質問は、コントローラーに 2 つのロールを割り当てるにはどうすればよいかということです。次に、各メソッドを 1 つのユーザー ロールにロックダウンしたいと考えています。

それが理にかなっていることを願っています。誰かが私を助けてくれることを願っています。

ありがとう

スティーブン

基本的に [CustomAuthorize(Roles = "Administrators, Support")] 、両方のロールがコントローラーを認識できるように、コントローラーをロックダウンしました。

次に、私が持っている作成/削除および編集メソッドがあります:

[CustomAuthorize(Roles = "Administrators")]

したがって、基本的にはコントローラー全体を両方のロールに表示したいのですが、作成/編集/削除できるのは管理者だけです。

user テーブルに roleID = 2(User) を割り当てると、そのユーザーのアプリケーション全体が壊れます。RoldID = 1 (管理者) を割り当てると、roldID 1 が割り当てられているすべての人に対して機能します。

現在、私はメソッドを持っています

public override string[] GetRolesForUser(string username)
{

    using (EFDbContext db = new EFDbContext())  

    {
        User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));


        if (user != null)
        {
            var roles = from ur in user.UserRoles
                        from r in db.Roles
                        where user.role.RoleID == r.RoleID

                        select r.Name;
            if (roles != null)
                return roles.ToArray();
            else
                return new string[] { }; ;
        }
        else
        {
            return new string[] { }; ;
        }
    }
}


> public override bool IsUserInRole(string username, string roleName)
>         {
>             
>             using (EFDbContext db = new EFDbContext())
>             {
>                 User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase)
> || u.Email.Equals(username,
> StringComparison.CurrentCultureIgnoreCase));
> 
>                 if (user != null)
>                 {
>                     var roles = from ur in user.UserRoles
>                                 from r in db.Roles
>                                 where user.role.RoleID == r.RoleID
>                                 //where ur.RoleID == r.RoleID
>                                 select r.Name;
>                     if (user != null)
>                         return roles.Any(r => r.Equals(roleName, >StringComparison.CurrentCultureIgnoreCase));
>                     else
>                         return false;
>                 }
>                 else
>                 {
>                     return false;
>                 }
>             }
>         }

IsUserInRole メソッドを変更して、配列パラメーターを次のように処理する必要があることはわかっています。public override bool IsUserInRole(string username, string[] roleName)

しかし、linq と主に IsUserInRole メソッドでそれを処理する方法がわかりません。

return roles.Any(r => r.Equals(roleName, >StringComparison.CurrentCultureIgnoreCase));

現在、私が信じているwhere句で、GetRolesForUserメソッドで失敗しています。

ここで、user.role.RoleID == r.RoleID

エラーメッセージは以下に表示されます。

このコマンドに関連付けられた開いている DataReader が既に存在し、最初に閉じる必要があります。説明: 現在の Web 要求の実行中に未処理の例外が発生しました。エラーの詳細とコード内のどこでエラーが発生したかについては、スタック トレースを確認してください。

例外の詳細: System.InvalidOperationException: このコマンドに関連付けられている開いている DataReader が既に存在します。これを最初に閉じる必要があります。

ソース エラー:

66 行目: var roles = user.UserRoles の ur から 67 行目: db.Roles の r から 68 行目: user.role.RoleID == r.RoleID の場所

ありがとう

4

1 に答える 1

2

このように複数の役割を実行できます。 [CustomAuthorize(Roles = "Administrator, User")] しかし、このコードを作成したことを考えると、すでにこれを知っていると思いますか?

作成/編集/削除機能にアクセスしたくUsersない場合は、デフォルトの認証機能を使用しないでください。つまり、[CustomAuthorize(Roles = "Administrator")]編集/作成/削除の[CustomAuthorize(Roles = "Administrator, User")]上、そして何よりも上に置く...

IsUserInRole承認時に呼び出されると思いますか?このメソッドは、単なる文字列ではなく、string[] roleName 配列を取る必要があります。

編集:変更

                        var roles = from ur in user.UserRoles
                        from r in db.Roles
                       where user.role.RoleID == r.RoleID
                        //where ur.RoleID == r.RoleID
                       select r.Name;

var roles = user.UserRoles.select(q=>q.Roles.Name);
于 2012-11-13T09:50:50.987 に答える