0

I have an ASP.NET MVC website, where most of my controllers are decorated with Authorize attributes, to enforce forms authentication.

I'm about to make this website available on Facebook via a Facebook app, but for my FB users I want to use a different authentication/authorization, I want to use CanvasAuthorize attribute on my controllers.

The problem is that I can't use both on my controllers/actions, because then both of them would be enforced to access the relevant action, but I want only Authorize for the normal website and I want only the CanvasAuthorize when the website is accessed from FB (via FB app).

I started to

  1. refactor hugely my existing controllers to 'controllerhelpers'
  2. make existing controllers (with authorize attribute) use the controllerhelpers relevant method
  3. create new controllers (decorated with CanvasAuthorize) for the FB-app, which use the relevant controllerhelper methods also

But this is huge work, and I'm not sure whether this is the way to go, or there is a much easier an elegant way to work.

Of course I want to use the same views, and in my cshtmls I'm using specific controllers's Url.Action methods, so with my current approach when I'm inserting action-paths in my cshtmls (for eg. jQuery ajax Url properties) I have to make an if-statement to use for example the 'PersonalController' when the normal website is used and use the 'FBPersonalController' when the website is used as a FB app.

In this case PersonalController is decorated with [Authorize] and FBPersonalController is decorated with [CanvasAuthorize].

So, any feedback is appreciated ;)

Thanks!

4

2 回答 2

0

Xoyoja 的回答让我找到了这个解决方案。我没有将其标记为“已接受的答案”,因为我正在评估它,但也许值得讨论:

不,不是所有的都应该装饰。但是根据您的建议,我得出以下结论:

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 用户 ID,该用户 ID 将隐含地进行身份验证。

我仍在考虑影响、最坏情况、后门是否会伤害我。

于 2012-03-29T15:43:10.557 回答
0

您可以使用条件过滤器同时支持 [Authorize] 和 [CanvasAuthorize] 吗?正如我在一个简单的 ASP.NET MVC3 应用程序中测试的那样,它可以工作。你认为它有帮助吗?

另一方面,一个不错的解决方案是,如果您可以更改设计,将身份验证内容放在一个位置,即 FormsAuthenticationService、FacebookAuthenciationService 和 OpenIDAuthencitationService 实现一个名为“IAuthenticationService”的接口。在完成 Facebook OAuth 流程后调用标准 FomsAuthentication.SetAuthCookie 方法。然后 Authorize 属性应该可以正常工作。请参阅此问题并从此处检查代码片段(Create.aspx 和 SessionController.cs)。请评价。

于 2012-03-29T05:44:14.220 回答