Sharepoint 2013 MVC 5提供商托管的应用程序.无法使用[SharePointContextFilter]在HttpPost上进行身份验证

Lys*_*Lys 6 sharepoint-2013 asp.net-mvc-5

过去一周我一直在敲打我的头脑,无法解决针对sharepoint提供商托管应用程序的正确身份验证的一些问题.

我目前正在为公司的Sharepoint在线开发一个sharepoint应用程序.我正在使用Visual Studio 2013.我将该应用程序部署为公司的Windows Azure门户上的云服务.一切顺利到我需要制作HttpPost的时候,然后应用程序无法进行身份验证.Conroller的设计如下:

    [SharePointContextFilter]
    public ActionResult Index()
    {
        UserSingleton user_temp = UserSingleton.GetInstance();

        User spUser = null;

        SharePointContext spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);

        using (var clientContext = spContext.CreateUserClientContextForSPHost())
        {
            if (clientContext != null)
            {
                spUser = clientContext.Web.CurrentUser;

                clientContext.Load(spUser, user => user.Title, user => user.Email);

                clientContext.ExecuteQuery();

                ....code....

            }
        }

           ....code....

        return View();
    }
Run Code Online (Sandbox Code Playgroud)

加载索引页面很顺利,操作会创建用户上下文,这一切都很好.当我尝试提交HttpPost时问题就出现了:

    [HttpPost]
    [ValidateAntiForgeryToken]
    [SharePointContextFilter]
    public ActionResult GetService(System.Web.Mvc.FormCollection fc)
    {
        PlannedHours ph = this.PopulateModel(fc);

        if (ph == null)
            return View("NoInfoFound");

        ViewData["PlannedHours"] = ph;

        return View("Index");
    }
Run Code Online (Sandbox Code Playgroud)

当我通过帖子按钮拨打此电话时,我收到"无法确定您的身份.请通过启动您网站上安装的应用再试一次." Shared/Error.cshtml视图.问题是当我删除[SharePointContextFilter]然后它工作,但这意味着请求不通过[SharePointContextFilter]因此它没有正确认证?或者是吗?因为它无法验证用户的合法性.

当我不删除[SharePointContextFilter]并调用帖子时,我注意到的一件事情,那么网址最终没有{StandardTokens}查询.是假设是这样的 - 我的意思是它像hostname.com/Home/GetService一样,但是当我使用actionlink时,spcontext.js总是将{StandardTokens}查询附加到基本URL - 像hostname.com/Home一样/ ActionNAme /?SPHostUrl = HTTPS%3A%2F%2FSHAREPOINTPAGEURL ....

我注意到的是,我调用hostname.com/Home/ActionNAme/而没有附加无法传递[SharePointContextFilter]的查询.

我是相当新到SharePoint 2013和MVC 5(剃刀),所以请,如果你知道为什么我的HttpPost未能通过[SharePointContextFilter]试着解释我或给予任何建议.我尝试过使用HttpGet但是,当我调用具有[SharePointContextFilter]的HttpGet并附加SPHostUrl =令牌时,它可以工作.但后来我无法使用[ValidateAntiForgeryToken].甚至在这样的应用程序中是否需要[ValidateAntiForgeryToken],因为[SharePointContextFilter]总是检查用户的合法性?我现在很困惑.网上有大量的资料可供阅读,没有什么可以解释何时附加这些标准代币,什么时候使用[SharePointContextFilter]等.事实上我第一次在我的网站上开发一个sharepoint应用程序.生活和我一直在研究和编码过去3周.所以我的知识还很有限,在回答时要记住这一点.在此先感谢,我希望我得到一些关于正在发生的事情的澄清!

----------------------------- UPDATE -------------------- --------------------

好的,快速更新.我发现了一些相当奇怪的东西.SharePointContextFilterAttribute.cs

    public class SharePointContextFilterAttribute : ActionFilterAttribute
    {
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        Uri redirectUrl;
        switch (SharePointContextProvider.CheckRedirectionStatus(filterContext.HttpContext, out redirectUrl))
        {
            case RedirectionStatus.Ok:
                return;
            case RedirectionStatus.ShouldRedirect:
                filterContext.Result = new RedirectResult(redirectUrl.AbsoluteUri);
                break;
            case RedirectionStatus.CanNotRedirect:
                filterContext.Result = new ViewResult { ViewName = "Error" };
                break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

始终返回最后一个案例(RedirectionStatus.CanNotRedirect),因为方法SharePointContextProvider.CheckRedirectionStatus(filterContext.HttpContext,out redirectUrl)包含一些我无法解决的问题.

首先:

     Uri spHostUrl = SharePointContext.GetSPHostUrl(httpContext.Request);

        if (spHostUrl == null)
        {
            return RedirectionStatus.CanNotRedirect;
        }
Run Code Online (Sandbox Code Playgroud)

好吧我理解 - 如果httpContext.Request不包含spHostUrl它将无法重定向.出于某种原因必须存在.

但是以下内容:

    if (StringComparer.OrdinalIgnoreCase.Equals(httpContext.Request.HttpMethod,                    "POST"))
        {
            return RedirectionStatus.CanNotRedirect;
        }
Run Code Online (Sandbox Code Playgroud)

等WHAAAT?!?不允许POST?!!?这里发生了什么?我真的不知道我做错了什么或什么?我甚至可以使用SharePointContext.cs吗?我真的需要有人来澄清到底发生了什么...我很感激!

Lib*_*n M 8

以上解决方案对我不起作用.我的帖子有同样的问题,但对我来说就是这个问题

return RedirectToAction("Index");
Run Code Online (Sandbox Code Playgroud)

导致错误.

我改成了:

return RedirectToAction("Index", new {SPHostUrl = SharePointContext.GetSPHostUrl(HttpContext.Request).AbsoluteUri});
Run Code Online (Sandbox Code Playgroud)

它起作用了.

我不确定这是你的问题的解决方案,因为你正在做返回视图,但它可能有助于某人:)


Ole*_*huk 1

我也遇到了同样的问题,花了几天时间才解决。我不知道为什么 SharePointContextFilter 无法正常工作并且没有重定向。所以我的应用程序是通过 POST 方法启动的,刷新页面时我有重新提交表单确认对话框。我还收到“无法确定您的身份。请启动您网站上安装的应用程序再试一次。”。

\n\n

为了解决这个问题,我使用了Post/Redirect/Get模式。我更改了 Index 操作,将 RedirectToAction 更改为另一个 IndexGet 操作。但是你应该有两个 IndexGet 方法 \xe2\x80\x94 用于 post 和 get。

\n\n

最后我为此采取了三项行动。索引操作重定向到 POST IndexGet 操作:

\n\n
    public ActionResult Index()\n    {            \n        return RedirectToAction("IndexGet");\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

Post 和 Get 的两个 IndexGet 方法具有相同的代码:

\n\n
    [HttpPost]\n    public ActionResult IndexGet(string tmp)\n    {\n        //your code from Index action\n        return View();\n    }\n\n    [HttpGet]\n    public ActionResult IndexGet()\n    {\n        //your code from Index action\n        return View();\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以它的工作方式是这样的:在开始时,通过 POST 调用 Index 操作。它重定向到 POST IndexGet 操作,在此位置 SharePointContextFilter 正常工作并通过 GET 调用 IndexGet。这个模式解决了我的问题。

\n