ユーザーと管理者がコントローラー全体を表示できるが、管理者のみが作成、削除、および編集できる各方法にアプリケーションをロックダウンしようとしています。
メソッドを保持する 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 の場所
ありがとう