2017-05-24 7 views
0

SharePoint 추가 기능 (SharePoint Online)을 개발했으며 Azure에서 호스팅됩니다. 추가 기능은 ASP.NET MVC 응용 프로그램입니다.SharePointContextFilter 특성이 SharePoint 컨텍스트를 다시 작성하지 못함

  1. /홈/색인 :

    여기 상황의 사용자는 응용 프로그램의 방문 페이지에 시작 섹션 Actions로 이동합니다.

  2. 작업/인덱스 :이 페이지에서, 사용자는 몇 가지 매개 변수를 선택하고

  3. 작업을 편집 할 작업을 선택해야/편집/123는 : 편집 페이지가 열립니다 폼이다 모든 컨트롤이 작업에 대한 정보로 채워져 표시됩니다.

  4. POST : 일부 필드 또는 없음을 변경 한 후, 사용자는 저장 버튼을 클릭합니다.

나는 목록에 표시되지 않았지만, 모든 URL은 SPHostUrl, SPAppWebUrl, SPLanguage, SPClientTag & SPProductNumber 매개 변수가 있습니다.

이 모든 사용자가 시간 (분)에 대한 응용 프로그램/페이지와 상호 작용하지 않고 다음저장 버튼을 누를 때를 제외하고 잘 작동합니다. 단추를 누르면 응용 프로그램이 SharePointContextFilter 특성을 전달하지 못합니다. SharePointContext가 더 이상 존재하지 않습니다.

SharePointContext spContext = LoadSharePointContext(httpContext); 

일반적으로는 존재하지 않거나 유효하지 않은 경우, 코드가 시도하고이 요청에 따라 기반으로 만든 것입니다 라인을 따르는 것은 반환합니다.

public static string GetContextTokenFromRequest(HttpRequestBase request) 
{ 
    string[] paramNames = { "AppContext", "AppContextToken", "AccessToken", "SPAppToken" }; 
    foreach (string paramName in paramNames) 
    { 
     if (!string.IsNullOrEmpty(request.Form[paramName])) 
     { 
      return request.Form[paramName]; 
     } 
     if (!string.IsNullOrEmpty(request.QueryString[paramName])) 
     { 
      return request.QueryString[paramName]; 
     } 
    } 
    return null; 
} 

그래서이 실패 할 경우, 컨텍스트의 생성 및 저장이 실패하고, :

string contextTokenString = TokenHelper.GetContextTokenFromRequest(httpRequest); 

이 메소드의 코드는 다음 CreateSharePointContext 방법에서, contextTokenString 항상 입니다 앱이 기본 오류 페이지를 반환합니다.

이 컨트롤러를 호출하게 jQuery 코드입니다 : 여기

var request = $.ajax({ 
    url: '@Url.Action("Edit", "Actions")' + window.buildSpAppParameters(), 
    data: $("#updateForm").serialize(), 
    cache: false, 
    type: "POST" 
}); 

buildSpAppParameters 함수의 코드입니다 :

function buildSpAppParameters() { 
    var spHostUrl = getQueryStringParameter("SPHostUrl"); 
    var appWebUrl = getQueryStringParameter("SPAppWebUrl"); 
    var spLanguage = getQueryStringParameter("SPLanguage"); 
    var spClientTag = getQueryStringParameter("SPClientTag"); 
    var spProductNr = getQueryStringParameter("SPProductNumber"); 

    return "?SPHostUrl=" + spHostUrl + 
      "&SPAppWebUrl=" + appWebUrl + 
      "&SPLanguage=" + spLanguage + 
      "&SPClientTag=" + spClientTag + 
      "&SPProductNumber=" + spProductNr; 
} 

가 왜 처음에 작동 않지만, 사용자가 대기하는 경우 일정 기간 동안 코드가 컨텍스트를 다시 만들거나 만들 수 없습니까? 실종 된 것이 있습니까? 어떻게 해결할 수 있습니까?

참고 : 다음 질문은 알고 있습니다 : Sharepoint 2013 MVC 5 provider-hosted app. Fails to authenticate on HttpPost using [SharePointContextFilter] 읽고 유용한 정보가 있지만 그다지 도움이되지 않습니다.

답변

1

이 모든 세션이 만료과 SharePointContext 분실 한 사용자가 분

의 숫자에 대한 응용 프로그램/페이지와 상호 작용하지 않는 경우를 제외하고 잘 작동합니다. 그래서 우리는 컨텍스트를 재생성해야합니다.

GetContextTokenFromRequest 메서드에 따르면 컨텍스트 토큰은 쿼리 문자열 형식으로 전달되어야합니다. 그러나 buildSpAppParameters 메서드에서 쿼리 문자열에서 컨텍스트 토큰이 전달 된 것을 확인할 수 없습니다. 쿼리 문자열 매개 변수의 이름은 AppContext 또는 AppContextToken 또는 AccessToken 또는 SPAppToken이어야합니다.

이 문제를 해결하려면 브라우저의 현재 URL에 AppContext 또는 AppContextToken 또는 AccessToken 또는 SPAppToken이라는 쿼리 매개 변수가 있는지 확인할 수 있습니다. 그렇다면 URL에서이 매개 변수의 값을 읽고 buildSpAppParameters 메소드에서 서버를 전달할 수 있습니다. 예를 들어 URL에 AppContextToken이라는 쿼리 매개 변수가 있으면 다음과 같이 코드를 수정할 수 있습니다.

function buildSpAppParameters() { 
    var spHostUrl = getQueryStringParameter("SPHostUrl"); 
    var appWebUrl = getQueryStringParameter("SPAppWebUrl"); 
    var spLanguage = getQueryStringParameter("SPLanguage"); 
    var spClientTag = getQueryStringParameter("SPClientTag"); 
    var spProductNr = getQueryStringParameter("SPProductNumber"); 

    var appContextToken = getQueryStringParameter("AppContextToken"); 

    return "?SPHostUrl=" + spHostUrl + 
     "&SPAppWebUrl=" + appWebUrl + 
     "&SPLanguage=" + spLanguage + 
     "&SPClientTag=" + spClientTag + 
     "&SPProductNumber=" + spProductNr + 
     "&AppContextToken=" + appContextToken; 
} 

당신의 URL은 쿼리 매개 변수를 포함하지 않는 경우

, 당신은 컨텍스트 토큰이 처음에 도착했을 때 쿠키에 컨텍스트 토큰을 저장하는 코드를 수정해야합니다.

string contextTokenString = TokenHelper.GetContextTokenFromRequest(httpRequest); 
if (!string.IsNullOrEmpty(contextTokenString)) 
{ 
    HttpCookie cookie = new HttpCookie("AppContextToken", contextTokenString); 
    cookie.HttpOnly = true; 
    Response.Cookies.Add(cookie); 
} 

그런 다음 토큰이 쿼리 문자열을 통해 전달되지 않은 경우 컨텍스트 토큰은 쿠키에서 가져올 수 있습니다.

public static string GetContextTokenFromRequest(HttpRequestBase request) 
{ 
    string[] paramNames = { "AppContext", "AppContextToken", "AccessToken", "SPAppToken" }; 
    foreach (string paramName in paramNames) 
    { 
     if (!string.IsNullOrEmpty(request.Form[paramName])) 
     { 
      return request.Form[paramName]; 
     } 
     if (!string.IsNullOrEmpty(request.QueryString[paramName])) 
     { 
      return request.QueryString[paramName]; 
     } 
    } 
    if (request.Cookies["AppContextToken"] != null) 
    { 
     return request.Cookies["AppContextToken"].Value; 
    } 
    return null; 
} 
+0

내 상황에 대한 일부 수정 사항과 함께 귀하의 쿠키 제안을 구현했습니다. 내가 궁금해하는 유일한 것 : 충분히 안전할까요? – Abbas

+0

토큰을 암호화하고 암호화 된 토큰을 쿠키로 보낼 수 있습니다. 암호화 된 토큰을 다시 얻은 후에는 서버 측에서 해독 할 수 있습니다. 세션 만료 시간을 연장하여이 문제를 해결할 수도 있습니다. 세션을 Azure SQL 또는 Azure Redis Cache에 저장하고 필요에 맞게 Session의 만료 시간을 구성 할 수 있습니다. – Amor

+0

결국 세션의 TimeOut 속성을 확장하여 문제를 해결했습니다. 나는 그것이 문제를 이해하는데 도움이되었으므로 당신의 대답을 명심해야 할 것입니다. 다시 한번 감사드립니다. – Abbas