質問

解を見つけた

ソリューションは、(コードがルートサイトなしでサブサイトで実行されていたときに)ルートサイトコレクションを追加することでした。

このソリューション


重要なアップデート(FEEDBACKに基づくはこれまで

SharePoint 2013サーバーにVisual Studioがインストールされていません。すべてのコードは、必要なSharePoint 2013 DLLへの参照を使用してRealoceを使用してリモートでコンパイルされ、SharePoint 2013サーバー上のグローバルアセンブリキャッシュにデプロイできます。

最も基本的なレベルでは、このステートメントはPage_Load()の時点で失敗します。

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

SPContext.Current常に nullです。

背景

クライアントには、外部ユーザーのフォームベース認証と内部ユーザーのWindows認証を使用してアクセス可能なSharePointサイトがあります(企業)。受信プロバイダを介して、現在の認証プロバイダをセットアップしてきました。

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上で実行されているTest SharePointインスタンスを持っていますが、すべての開発がリモートで行われるため、Visual Studioがインストールされていません。私がフォローする過程;

    1. C#クラスライブラリを構築(これはMyCustomSignInModule.Dllになります)
    2. MyCustomSignInModule.Dllでは、VM GACに配置できるようにします。
    3. VMインスタンスのGAC内のMyCustomSignInModule.Dllをレジスタ。
    4. SignInForm.aspxを、IISの%CommonProgramFiles%\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\仮想ディレクトリと同等の<SharePointSiteRoot>/_layouts/に保存します。
    5. SharePointサーバーの全体管理サイトでカスタムサインインページをPage ~/_layouts/SignInForm.aspxに設定します。
    6. iisresetを使用してIISをリセットします。
    7. SharePointサイトへのアクセスをテストします(これはそれが倒れるところです)。

      問題

      rome in in in in in in

      それがそれほど明確でない場合はエラーがある。

      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はNULLであるため、SPContext.Currentが原因で発生していますが、それがNULLであり、私が見た記事がこれまでにこれを解決するのを助けるためにこれまでにありませんでした。私はここで私の全体のプロセスを投稿することを願っています

役に立ちましたか?

解決

Finally got to the bottom of what was causing the issue, firstly would like to thank both @MdMazzotti and @Hugh Wood for their persistent help.

In the end I stumbled on the fix which turned out to be partly because the way the site was built. In my particular case the site was built as a sub-site in SharePoint, for whatever reason this meant there was no Site Collection at the root of the SharePoint website which was the cause of the Null SPContext in my code.

After adding a Root Site Collection my code began to work as expected.

他のヒント

I'm just guessing here, but here are some things that I think could help.

Add this JavaScript code to the custom sign in page (before your if-statement):

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

You could also add this JavaScript to your page to test if it works or not, using the console:

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

If it returns something, then we have progress! If not, then I'll have to continue my search, since I find your question interesting.

EDIT

Instead of using this server-side code:

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

Try using this instead:

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

I searched around and noticed that in some of the code examples I encountered, the _iisSettings was different from yours. Perhaps that is why your SPContext.Current is null?

Please check this answer: https://stackoverflow.com/questions/5081251/how-can-this-throw-a-nullreferenceexception

SPContext.Current doesn't work under Elevated Privileges, so you have to rewrite like in the answer above.

Can you check this MSDN article: http://msdn.microsoft.com/en-us/library/office/ms468609(v=office.14).aspx

I think because you use a C# Class Library project in Visual studio, you are not in a web context and can't use SPContext.Current as explained in the MSDN article above.

ライセンス: CC-BY-SA帰属
所属していません sharepoint.stackexchange
scroll top