我有一个ASP.NET MVC网站,我的大多数控制器都用Authorize属性装饰,以强制表单身份验证。
我即将通过Facebook应用程序在Facebook上提供此网站,但对于我的FB用户,我想使用不同的身份验证/授权,我想在我的控制器上使用CanvasAuthorize属性。
问题是,我不能在我的控制器/操作上同时使用这两个,因为这两个控制器/操作都将被强制访问相关操作,但我只想为正常网站授权,当从FB(通过FB应用程序)访问网站时,我只想使用CanvasAuthorize。
我开始
- 将我现有的控制器大量重构为"controllerhelpers"
- 使现有控制器(具有authorize属性)使用controllerhelpers相关方法
- 为FB应用程序创建新的控制器(用CanvasAuthorize修饰),这些控制器还使用相关的controllerhelper方法
但这是一项艰巨的工作,我不确定这是一条路,还是有一种更容易、更优雅的工作方式。
当然,我想使用相同的视图,在我的cshtmls中,我使用特定控制器的Url.Action方法,因此,根据我目前的方法,当我在cshtmls中插入操作路径(例如jQuery ajax Url属性)时,我必须做出if语句,例如,当使用普通网站时使用"PersonalController",当网站用作FB应用程序时使用"FBPersonalController"。
在这种情况下,PersonalController用[Authorize]修饰,FBPersonalController则用[CanvasAuthorize]修饰。
因此,我们非常感谢任何反馈;)
谢谢!
不,不是所有的都应该装饰。但在你的提议下,我得出了以下结论:
IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions =
new Func<ControllerContext, ActionDescriptor, object>[] {
(ctrlCtx, actDesc) =>
{
if(FacebookWebContext.Current.SignedRequest != null)
{
return new CanvasAuthorize();
}
else
{
if(ctrlCtx.Controller.GetType() == typeof(AccountController)
&& actDesc.ActionName == "LogOn")
{
return null;
}
return new AuthorizeAttribute();
}
},
};
当我的网站从FB访问时,SignedRequest似乎不是null,所以可以使用CanvasAuthorize。
如果我的网站是从正常发布的url访问的,那么我使用AuthorizeAttribute。
AccountController和"LogOn"操作特定逻辑是允许从公共url登录网站所必需的。来自Facebook的Context包含Facebook UserID,它将隐含地进行身份验证。
我仍然在考虑影响,最坏的情况,后门,这是否会伤害我。
是否可以使用条件筛选器同时支持[AAuthorize]和[CanvasAuthorize]?正如我在一个简单的ASP.NET MVC3应用程序中测试的那样,它是有效的。你认为这有帮助吗?
另一方面,一个很好的解决方案是,如果你能改变你的设计,把身份验证的东西放在一个地方,也就是说,FormsAuthenticationService、FacebookAuthenciationService和OpenIDAuthenticationServer实现了一个名为"IAuthenticationServices"的接口。完成Facebook OAuth流后,调用标准的FomsAuthentication.SetAuthCookie方法。然后Authorize属性应该可以正常工作。请参阅此问题并检查此处的代码片段(Create.aspx和SessionController.cs)。请评估。