Domanda

.

trovato la soluzione

La soluzione è stata aggiungere una raccolta del sito root (poiché il codice era in esecuzione in un sito secondario, senza un sito root).

Vedi Questa soluzione


.
.

Aggiornamento importante ( in base al feedback ricevuto così lontano )

Non ho Visual Studio installato sul server SharePoint 2013. Tutto il codice è compilato in Visual Studio 2012 utilizzando remoto i riferimenti alle DLL di SharePoint 2013 richieste e firmato digitalmente in modo da poter essere distribuito nella cache di assembly globale sul server SharePoint 2013.

al livello più elementare questa affermazione fallisce al punto di generazione Page_Load();

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

Poiché SPContext.Current è Sempre null.

Sfondo

Il client ha bisogno del sito di SharePoint per essere accessibile utilizzando l'autenticazione basata su moduli per gli utenti esterni e l'autenticazione di Windows per gli utenti interni (Corporate). Sono passati e hanno configurato entrambi i fornitori di autenticazione e ora ottengono il segno predefinito.

Accedi

Sebbene tutto ciò che funzioni autenticazione di Windows visualizza ancora la schermata di selezione del provider quando il client desidera che l'autenticazione di Windows passasse automaticamente e visualizzare una schermata di accesso di autenticazione basata su moduli se ciò non riesce.

Stato in difficoltà con questo per giorni dopo aver esaminato vari blog e articoli che sento che non sono più avanti e che è deprimente. Al momento non posso allenarti se mi manca qualcosa di veramente fondamentale.

Accedi personalizzati nella pagina

La pagina si basa su un'amaliazione di;

    .
  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

    Questo è solo un primo tentativo e realizzato che non avrà bisogno di tutti questi controlli alla fine, volevo solo vedere come le cose appendono insieme.

    .

    MycustomsigninModule Assembly
    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;
            }
        }
    }
    
    .

    Il processo

    Ho un'istanza di SharePoint di test in esecuzione sulla VM ma non è stato installato Visual Studio poiché tutto lo sviluppo è fatto da remoto. Il processo corrente che seguo;

      .
    1. Build C # Library Class (questo sarà MyCustomSignInModule.Dll)
    2. Iscriviti MyCustomSignInModule.Dll in modo che possa essere posizionato nel VM GAC.
    3. Registrati MyCustomSignInModule.Dll nel GAC sull'istanza VM.
    4. Salva SignInForm.aspx nel %CommonProgramFiles%\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ che è l'equivalente della directory virtuale <SharePointSiteRoot>/_layouts/ in IIS.
    5. Nel sito di Amministrazione centrale SharePoint Impostare il registro personalizzato nella pagina sulla mia pagina ~/_layouts/SignInForm.aspx.
    6. Reset IIS usando iisreset.
    7. Test Accesso al sito di SharePoint (è qui che cade).

      il problema

      Accedi Errore

      Se non è chiaro che l'errore è;

      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) 
      
      .

      spontext.current è nullo perché?

      Il NullReferenceException viene causato da SPContext.Current essendo nullo, ma non posso allenarmi perché è nullo e nessuna quantità di articoli che ho guardato che hanno portato finora per aiutarmi a risolvermi questo. Spero postare il mio intero processo qui qualcuno potrebbe essere in grado di indicarmi quello che mi manca o sbagliata.

È stato utile?

Soluzione

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.

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a sharepoint.stackexchange
scroll top