asp.net mvc 用多个枚举装饰 [Authorize()]
我有一个控制器,我希望两个角色能够访问它。 1-管理员或 2-主持人
我知道你可以执行 [Authorize(Roles="admin, moderators")] 但我在枚举中有我的角色。 使用枚举我只能授权一个角色。 我不知道如何授权两个。
我尝试过类似 [Authorize(Roles=MyEnum.Admin, MyEnum.Moderator)] 的方法,但无法编译。
有人曾经提出过这个建议:
[Authorize(Roles=MyEnum.Admin)]
[Authorize(MyEnum.Moderator)]
public ActionResult myAction()
{
}
但它不能作为 OR 起作用。 我认为在这种情况下,用户必须同时属于这两个角色。 我忽略了一些语法吗? 或者在这种情况下我必须滚动自己的自定义授权?
I have a controller and I want two roles to be able to access it. 1-admin OR 2-moderator
I know you can do [Authorize(Roles="admin, moderators")] but I have my roles in an enum. With the enum I can only authorize ONE role. I can't figure out how to authorize two.
I have tried something like [Authorize(Roles=MyEnum.Admin, MyEnum.Moderator)] but that wont compile.
Someone once suggested this:
[Authorize(Roles=MyEnum.Admin)]
[Authorize(MyEnum.Moderator)]
public ActionResult myAction()
{
}
but it doesn't work as an OR. I think in this case the user has to be part of BOTH roles. Am I overlooking some syntax? Or is this a case where I have to roll my own custom authorization?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
这是我的版本,基于 @CalebHC 和 @Lee Harold 的答案。
我遵循在属性中使用命名参数的风格并覆盖基类
Roles
属性。@CalebHC 的答案使用了一个新的
Is
属性,我认为这是不必要的,因为AuthorizeCore()
被重写(在基类中使用 Roles),因此使用我们的也拥有自己的角色
。 通过使用我们自己的Roles
,我们可以在控制器上编写Roles = Roles.Admin
,它遵循其他.Net属性的样式。我在
CustomAuthorizeAttribute
中使用了两个构造函数来显示传入的真实活动目录组名称。在生产中,我使用参数化构造函数来避免类中的魔术字符串:组名称是在期间从 web.config 中提取的。Application_Start()
并使用 DI 工具在创建时传入。您需要在
Views\Shared
文件夹中添加一个NotAuthorized.cshtml
或类似文件,否则未经授权的用户将会看到错误屏幕。以下是基类 AuthorizationAttribute.cs 的代码。
控制器:
自定义授权属性:
Here's my version, based on @CalebHC and @Lee Harold's answers.
I've followed the style of using named parameters in the attribute and overridden the base classes
Roles
property.@CalebHC's answer uses a new
Is
property which I think is unnecessary, becauseAuthorizeCore()
is overridden (which in the base class uses Roles) so it makes sense to use our ownRoles
as well. By using our ownRoles
we get to writeRoles = Roles.Admin
on the controller, which follows the style of other .Net attributes.I've used two constructors to
CustomAuthorizeAttribute
to show real active directory group names being passed in. In production I use the parameterised constructor to avoid magic strings in the class: group names are pulled from web.config duringApplication_Start()
and passed in on creation using a DI tool.You'll need a
NotAuthorized.cshtml
or similar in yourViews\Shared
folder or unauthorized users will get an error screen.Here is the code for the base class AuthorizationAttribute.cs.
Controller:
CustomAuthorizeAttribute:
要添加到 CalebHC 的代码并回答 ssmith 关于处理具有多个角色的用户的问题...
我们的自定义安全主体返回一个字符串数组,表示用户所在的所有组/角色。因此,首先我们必须转换与枚举中的项目匹配的数组。 最后,我们查找任何匹配项 - 如果是,则用户已获得授权。
请注意,我们还将未经授权的用户重定向到自定义“NotAuthorized”视图。
整个班级是这样的:
To add to CalebHC's code and answer ssmith's question about handling users who have multiple roles...
Our custom security principal returns a string array representing all the groups/roles that a user is in. So first we have to convert all the strings in the array that match items in the enum. Finally, we look for any match - if so, then the user is authorized.
Note that we're also redirecting an unauthorized user to a custom "NotAuthorized" view.
The whole class looks like this:
我不完全同意之前答案的复杂性。 这是我的版本,使用字典将角色枚举值转换为字符串。
当然,每当引入新角色时,就需要更新映射。
可以在这样的控制器中使用
I did not fully agree with the complexity of previous answers. Here's my version using a dictionary to convert Role enum values to string.
Of course, the mapping needs to be updated whenever there is a new role introduced.
Which can be used in the controllers like this
或者你可以像这样连接:
Or you could concatenate like:
这是一个简单且优雅的解决方案,它允许您简单地使用以下语法:
创建自己的属性时,使用
params
构造函数中的 关键字:这将允许您按如下方式使用该属性:
Here is a simple and elegant solution which allows you to simply use the following syntax:
When creating your own attribute, use the
params
keyword in your constructor:This will allow you to use the attribute as follows:
尝试使用位或运算符,如下所示:
如果这不起作用,您可以自己动手。 我目前刚刚在我的项目中这样做了。 这就是我所做的:
另外,请确保向您的枚举添加一个 flags 属性,并确保它们的值都从 1 开始。 像这样:
左移位给出值 1、2、4、8、16 等。
嗯,我希望这会有所帮助。
Try using the bit OR operator like this:
If that doesn't work, you could just roll your own. I currently just did this on my project. Here's what I did:
Also, make sure to add a flags attribute to your enum and make sure they are all valued from 1 and up. Like this:
The left bit shifting gives the values 1, 2, 4, 8, 16 and so on.
Well, I hope this helps a little.
我在这里结合了一些解决方案来创建我个人最喜欢的解决方案。 我的自定义属性只是将数据更改为 SimpleMembership 期望的形式,并让它处理其他所有内容。
我的角色枚举:
创建角色:
自定义属性:
像这样使用:
I combined a few of the solutions here to create my personal favorite. My custom attribute just changes the data to be in the form that SimpleMembership expects and lets it handle everything else.
My roles enum:
To create roles:
Custom attribute:
Used like so:
要使用多个枚举来装饰 [Authorize()],您可以编写如下代码:
您也可以为单个角色编写此代码:
To decorate [Authorize()] with multiple enums, you can write code just like this:
You are also can write this code for single role:
尝试
Try