Frage

Die Lösung gefunden

Die Lösung bestand darin, eine Stammwebsitesammlung hinzuzufügen (da der Code auf einer Unterwebsite ohne Stammwebsite ausgeführt wurde).

Sehen Diese Lösung


Wichtiges Update (basierend auf bisher eingegangenem Feedback)

Ich habe Visual Studio nicht auf dem SharePoint 2013-Server installiert.Der gesamte Code wird in Visual Studio 2012 remote mithilfe von Verweisen auf die erforderlichen SharePoint 2013-DLLs kompiliert und digital signiert, damit er im globalen Assemblycache auf dem SharePoint 2013-Server bereitgestellt werden kann.

Auf der grundlegendsten Ebene versagt diese Aussage an der Stelle von Page_Load();

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

Da SPContext.Current is immer null.

Hintergrund

Der Client benötigt eine SharePoint-Site, auf die über die formularbasierte Authentifizierung für externe Benutzer und die Windows-Authentifizierung für interne Benutzer (Unternehmen) zugegriffen werden kann.Habe beide Authentifizierungsanbieter durchlaufen und eingerichtet und erhalte jetzt die Standardanmeldung.

Sign In

Obwohl alles funktioniert, zeigt die Windows-Authentifizierung weiterhin den Anbieterauswahlbildschirm an, wenn der Client möchte, dass die Windows-Authentifizierung nur automatisch durchlaufen wird, und zeigt einen Anmeldebildschirm für die formularbasierte Authentifizierung an, wenn dies fehlschlägt.

Nachdem ich mir tagelang verschiedene Blogs und Artikel angesehen habe, habe ich das Gefühl, dass ich nicht weiter bin und das ist deprimierend.Im Moment kann ich nicht trainieren, ob mir etwas wirklich Grundlegendes fehlt.

Benutzerdefinierte Anmeldeseite

Die Seite basiert auf einem Zusammenschluss von;

  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

Dies ist nur ein erster Versuch und mir ist klar, dass ich irgendwann nicht mehr all diese Steuerelemente brauche, sondern nur sehen wollte, wie die Dinge zusammenhängen.

MyCustomSignInModule Zusammenbau

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;
        }
    }
}

Prozess

Ich habe eine Test-Sharepoint-Instanz auf der VM ausgeführt, aber kein Visual Studio installiert, da die gesamte Entwicklung remote erfolgt.Dem aktuellen Prozess folge ich;

  1. Erstellen Sie eine C # -Klassenbibliothek (dies wird sein MyCustomSignInModule.Dll)
  2. Unterzeichnen MyCustomSignInModule.Dll so kann es in der VM GAC platziert werden.
  3. Registrieren MyCustomSignInModule.Dll im GAC auf der VM-Instanz.
  4. Speichern SignInForm.aspx in die %CommonProgramFiles%\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ welches ist das Äquivalent von <SharePointSiteRoot>/_layouts/ virtuelles Verzeichnis in IIS.
  5. Legen Sie auf der SharePoint-Website für die Zentraladministration die benutzerdefinierte Anmeldeseite auf meine Seite fest ~/_layouts/SignInForm.aspx.
  6. Setzen Sie IIS mit zurück iisreset.
  7. Testen Sie den Zugriff auf die SharePoint-Site (hier fällt sie um).

Problem

Sign In Error

Wenn es nicht so klar ist, ist der Fehler;

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) 

In: SPContext.Strom ist null warum?

Der NullReferenceException wird verursacht durch SPContext.Current null sein, aber ich kann nicht trainieren, warum es null ist und keine Anzahl von Artikeln, die ich mir angesehen habe, hat mir bisher geholfen, dies zu lösen.Ich hoffe, dass mich jemand durch das Posten meines gesamten Prozesses hier auf das hinweisen kann, was ich vermisse oder falsch mache.

War es hilfreich?

Lösung

Endlich auf den Grund gekommen, was das Problem verursacht hat, möchte ich zunächst beiden danken @MdMazzotti und @Hugh Wood für ihre beharrliche Hilfe.

Am Ende bin ich über die Lösung gestolpert, die sich teilweise als die Art und Weise herausstellte, wie die Site aufgebaut war.In meinem speziellen Fall wurde die Site als Unterwebsite in SharePoint erstellt. Aus irgendeinem Grund bedeutete dies, dass sich im Stammverzeichnis der SharePoint-Website keine Websitesammlung befand, was die Ursache für die Null SPContext in meinem Code.

Nach dem Hinzufügen einer Stamm-Websitesammlung funktionierte mein Code wie erwartet.

Andere Tipps

Ich rate hier nur, aber hier sind einige Dinge, von denen ich denke, dass sie helfen könnten.

Fügen Sie diesen JavaScript-Code der benutzerdefinierten Anmeldeseite hinzu (vor Ihrer if-Anweisung):

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

Sie können dieses JavaScript auch zu Ihrer Seite hinzufügen, um über die Konsole zu testen, ob es funktioniert oder nicht:

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

Wenn es etwas zurückgibt, dann haben wir Fortschritte!Wenn nicht, dann muss ich meine Suche fortsetzen, da ich Ihre Frage interessant finde.

BEARBEITEN

Anstatt diesen serverseitigen Code zu verwenden:

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

Versuchen Sie stattdessen, dies zu verwenden:

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

Ich habe mich umgesehen und festgestellt, dass sich in einigen der Codebeispiele, auf die ich gestoßen bin, die _iisSettings von Ihren unterschieden.Vielleicht ist das der Grund für Ihren SPContext .Strom ist null?

Bitte überprüfen Sie diese Antwort:https://stackoverflow.com/questions/5081251/how-can-this-throw-a-nullreferenceexception

In: SPContext.Current funktioniert nicht unter erhöhten Berechtigungen, daher müssen Sie wie in der obigen Antwort umschreiben.

Können Sie diesen MSDN-Artikel überprüfen: http://msdn.microsoft.com/en-us/library/office/ms468609 (v = Büro.14).aspx

Ich denke, weil Sie ein C # -Klassenbibliotheksprojekt in Visual Studio verwenden, befinden Sie sich nicht in einem Webkontext und können SPContext nicht verwenden.Aktuell wie im obigen MSDN-Artikel erläutert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit sharepoint.stackexchange
scroll top