문제

해결책을 찾았습니다

해결책은 루트 사이트 모음을 추가하는 것이었습니다(코드가 루트 사이트 없이 하위 사이트에서 실행되었기 때문).

보다 이 솔루션


중요 업데이트 (지금까지 받은 피드백을 바탕으로)

SharePoint 2013 Server에 Visual Studio가 설치되어 있지 않습니다.모든 코드는 필수 SharePoint 2013 DLL에 대한 참조를 사용하여 원격으로 Visual Studio 2012에서 컴파일되고 디지털 서명되므로 SharePoint 2013 Server의 전역 어셈블리 캐시에 배포할 수 있습니다.

가장 기본적인 수준에서 이 진술은 다음과 같은 점에서 실패합니다. Page_Load();

SPContext.Current.Site.WebApplication.GetIisSettingsWithFallback(
  SPContext.Current.Site.Zone
);

왜냐하면 SPContext.Current ~이다 언제나 null.

배경

고객은 외부 사용자를 위한 양식 기반 인증과 내부 사용자(회사)를 위한 Windows 인증을 사용하여 액세스할 수 있는 SharePoint 사이트가 필요합니다.인증 공급자를 모두 설정하고 이제 기본 로그인을 얻습니다.

Sign In

모든 것이 작동하더라도 클라이언트가 Windows 인증을 자동으로 통과하기를 원할 때 Windows 인증은 여전히 ​​공급자 선택 화면을 표시하고 실패할 경우 양식 기반 인증 로그인 화면을 표시합니다.

다양한 블로그와 기사를 살펴본 후 며칠 동안 이 문제로 어려움을 겪고 있는데 더 이상 진전이 없다고 느껴지고 그게 우울합니다.지금은 정말로 근본적인 것을 놓치고 있는지 운동할 수 없습니다.

사용자 정의 로그인 페이지

이 페이지는 다음의 융합을 기반으로 합니다.

  1. %CommonProgramFiles%\Microsoft Shared\Web Server Extensions\15\Template\IdentityModel\Login\default.aspx
  2. %CommonProgramFiles%\Microsoft Shared\Web Server Extensions\15\Template\IdentityModel\Forms\default.aspx

이것은 단지 첫 번째 시도일 뿐이며 결국에는 이러한 모든 컨트롤이 필요하지 않을 것이라는 점을 깨달았습니다. 단지 일이 어떻게 진행되는지 보고 싶었을 뿐입니다.

MyCustomSignInModule 어셈블리

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Microsoft.IdentityModel.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.IdentityModel;
using Microsoft.SharePoint.IdentityModel.Pages;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Administration.Claims;
using Microsoft.SharePoint.ApplicationRuntime;
using Microsoft.SharePoint.Diagnostics;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebControls;
using System.IdentityModel.Tokens;
using System.Web.Configuration;

namespace MyCustomSignInModule
{
    public class SignInForm : FormsSignInPage
    {
        protected Label DebugText;

        private static SPIisSettings _iisSettings;

        internal static SPIisSettings iisSettings
        {
            get
            {
                if (_iisSettings == null)
                {
                    SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                        _iisSettings = SPContext.Current.Site.WebApplication.GetIisSettingsWithFallback(SPContext.Current.Site.Zone);
                    });
                }
                return _iisSettings;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            HttpRequest request = HttpContext.Current.Request;

            bool isWindowsAuth = false;
            string username = request["username"];
            string password = request["password"];


            // If no username is provided, it'll probably be Windows Authentication (NTLMv2 protocol)
            if (String.IsNullOrEmpty(username))
            {
                isWindowsAuth = true;
            }

            try
            {

                //SPIisSettings iisSettings = SPContext.Current.Site.WebApplication.IisSettings[SPUrlZone.Default];

                if (isWindowsAuth)
                {
                    // Windows Authentication it is

                    if (iisSettings.UseWindowsClaimsAuthenticationProvider)
                    {
                        SPAuthenticationProvider provider = iisSettings.WindowsClaimsAuthenticationProvider;
                        RedirectToLoginPage(provider); // This should cause automatic sign in
                    }
                }
                else
                {
                    // FBA authentication it is.

                    SPFormsAuthenticationProvider formsClaimsAuthenticationProvider = iisSettings.FormsClaimsAuthenticationProvider;

                    SecurityToken token = SPSecurityContext.SecurityTokenForFormsAuthentication(new Uri(SPContext.Current.Web.Url), formsClaimsAuthenticationProvider.MembershipProvider, formsClaimsAuthenticationProvider.RoleProvider, username, password, SPFormsAuthenticationOption.PersistentSignInRequest);

                    if (null != token)
                    {
                        EstablishSessionWithToken(token);
                        base.RedirectToSuccessUrl();
                    }
                }
            }
            catch (Exception ex)
            {
                DebugText.Text = ex.ToString();
            }

        }

        // Microsoft.SharePoint.IdentityModel.LogonSelector
        private void RedirectToLoginPage(SPAuthenticationProvider provider)
        {
            string components = HttpContext.Current.Request.Url.GetComponents(UriComponents.Query, UriFormat.SafeUnescaped);
            string url = provider.AuthenticationRedirectionUrl.ToString();
            if (provider is SPWindowsAuthenticationProvider)
            {
                components = EnsureUrlSkipsFormsAuthModuleRedirection(components, true);
            }
            SPUtility.Redirect(url, SPRedirectFlags.Default, this.Context, components);
        }

        // Microsoft.SharePoint.Utilities.SPUtility
        private string EnsureUrlSkipsFormsAuthModuleRedirection
            (string url, bool urlIsQueryStringOnly)
        {
            if (!url.Contains("ReturnUrl="))
            {
                if (urlIsQueryStringOnly)
                {
                    url = url + (string.IsNullOrEmpty(url) ? "" : "&");
                }
                else
                {
                    url = url + ((url.IndexOf('?') == -1) ? "?" : "&");
                }
                url = url + "ReturnUrl=";
            }
            return url;
        }

        // Microsoft.SharePoint.IdentityModel.Pages.IdentityModelSignInPageBase
        private void EstablishSessionWithToken(SecurityToken securityToken)
        {
            if (securityToken == null)
            {
                throw new ArgumentNullException("securityToken");
            }
            SPFederationAuthenticationModule fam = SPFederationAuthenticationModule.Current;
            if (fam == null)
            {
                throw new InvalidOperationException();
            }

            fam.SetPrincipalAndWriteSessionToken(securityToken);
        }

        private SPAuthenticationProvider
                GetAuthenticationProvider(string providerName)
        {
            SPIisSettings iisSettings =
                SPContext.Current.Site.WebApplication.IisSettings[SPUrlZone.Default];

            foreach (SPAuthenticationProvider currentProvider in
                        iisSettings.ClaimsAuthenticationProviders)
            {
                if (currentProvider.DisplayName.ToLower() ==
                            providerName.ToLower())
                {
                    return currentProvider;
                }
            }

            return null;
        }
    }
}

과정

VM에서 테스트 Sharepoint 인스턴스가 실행되고 있지만 모든 개발이 원격으로 수행되므로 Visual Studio가 설치되어 있지 않습니다.내가 따르는 현재 프로세스는 다음과 같습니다.

  1. C# 클래스 라이브러리 구축(이것은 MyCustomSignInModule.Dll)
  2. 징후 MyCustomSignInModule.Dll VM GAC에 배치할 수 있습니다.
  3. 등록하다 MyCustomSignInModule.Dll VM 인스턴스의 GAC에서.
  4. 구하다 SignInForm.aspx%CommonProgramFiles%\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ 이는 다음과 같습니다. <SharePointSiteRoot>/_layouts/ IIS의 가상 디렉터리.
  5. SharePoint 중앙 관리 사이트에서 사용자 지정 로그인 페이지를 내 페이지로 설정합니다. ~/_layouts/SignInForm.aspx.
  6. 다음을 사용하여 IIS 재설정 iisreset.
  7. SharePoint 사이트 액세스를 테스트합니다(여기서 넘어갑니다).

문제

Sign In Error

명확하지 않은 경우 오류는 다음과 같습니다.

System.NullReferenceException: Object reference not set to an instance of an object. at
MyCustomSignInModule.SignInForm.b__0() at 
Microsoft.SharePoint.SPSecurity.<>c__DisplayClass5.b__3() at
Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode) at 
Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode, Object param) at 
Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode) at MyCustomSignInModule.SignInForm.get_iisSettings() at 
MyCustomSignInModule.SignInForm.Page_Load(Object sender, EventArgs e) 

SPContext.Current가 null인 이유는 무엇입니까?

그만큼 NullReferenceException 에 의해 발생하고 있습니다 SPContext.Current null이지만 왜 null인지 알 수 없으며 지금까지 본 기사 중 이 문제를 해결하는 데 도움이 된 기사가 없습니다.내 전체 과정을 여기에 게시하면 누군가 내가 누락되었거나 잘못하고 있는 부분을 지적할 수 있기를 바랍니다.

도움이 되었습니까?

해결책

마침내 바닥었는지의 문제를 일으키는 첫째고 싶을 모두 감사 @MdMazzotti@휴무 에 대한 그들의 지속적인 도움이됩니다.

결국 나는 비틀 수정에 밝혀졌다는 부분적으로 방식 때문에 사이트되었습니다.에 특별한 경우 사이트에 건설되었으로 하위 사이트에서 SharePoint 이 어떤 이유로,이 의미가 없었다는 사이트에서 컬렉션의 루트 SharePoint 웹사이트의 원인이었습니다. Null SPContext 내 코드입니다.

후에 추가하는 루트 사이트 모음 나의 코드 작동하기 시작했으로 예상된다.

다른 팁

나는 그냥 여기 추측,하지만 여기에 몇 가지 일을 생각하는이 도움이 될 수 없습니다.

추가 이 JavaScript 코드를 사용자 정의 로그인 페이지(전에는 경우-성명):

SP.SOD.executeFunc('SP.js', 'SP.ClientContext');

을 추가할 수도 있습니다 이 자바 스크립트를 당신의 페이지를 테스트하는 경우 작동하는지,콘솔을 사용:

var clientContext = new  SP.ClientContext.get_current(); 
console.log(clientContext);

반환하는 경우 사용할 무언가를,그리고 우리는 진행!그렇지 않으면,그때 나는 내 검색을 계속 때문에,내가 찾는 귀하의 질문을 흥미롭습니다.

편집

대신 사용하는 이 서버 측 코드:

if (_iisSettings == null)
{
   SPSecurity.RunWithElevatedPrivileges(delegate()
   {
      _iisSettings = SPContext.Current.Site.WebApplication.GetIisSettingsWithFallback(SPContext.Current.Site.Zone);
   });
}
return _iisSettings;

도 이것을 사용하는 대신:

if (_iisSettings == null)
{
   SPSecurity.RunWithElevatedPrivileges(delegate()
   {
      _iisSettings = Microsoft.SharePoint.SPContext.Current.Site.WebApplication.GetIisSettingsWithFallback(Microsoft.SharePoint.SPContext.Current.Site.Zone);
   });
}
return _iisSettings;

검색 주변의 코드 예제가 발생 _iisSettings 다른 당신입니다.아마 그런 이유로 당신의 SPContext.현재 null?

을 확인하시기 바랍 이 대답:https://stackoverflow.com/questions/5081251/how-can-this-throw-a-nullreferenceexception

SPContext.현재 작동하지 않는 높은 권한으로,그래서 당신은 다시 쓰기에서 같은 대답이다.

확인할 수 있습니다 이 MSDN 문서 http://msdn.microsoft.com/en-us/library/office/ms468609(v=office.14).aspx

내가 생각하기 때문에 사용할 C#클래스 라이브러리 프로젝트를 Visual studio 에서,당신은 웹에서 컨텍스트를 사용할 수 없습 SPContext.현재로서에서 설명은 MSDN 문서다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 sharepoint.stackexchange
scroll top