SharePoint 2013 Authentication – Forms Based

Sharepoint 2013

SharePoint 2013 Authentication – Forms Based

The following is the interaction between

  1. Client Computer
  2. SharePoint Server
  3. ASP.NET Membership provider

The Form Based Claims Authentication Process

  1. User does anonymous request to secured SharePoint Webpage
  2. SharePoint responds with form based login page
  3. User types in the credentials and sends back using the client computer
  4. SharePoint server then validates the credentials with membership provider
  5. SharePoint server then queries the roles provider for user’s associated roles
  6. This becomes the role claims for user’s account
  7. SharePoint then creates a claims based security token using Security Token Service
  8. Then SharePoint stores this security token with Distributed Cache Service on the farm
  9. SharePoint server then generates and sends the federated auth cookie back to client computer
  10. The fed auth cookie has encrypted key or index to security token
  11. This fed auth cookie is used by the computer for subsequent requests

The following Video will explain the Forms based authentication in SharePoint 2013. This video is part of the Authentication overview for SharePoint 2013 article located at https://technet.microsoft.com/en-us/library/jj219571.aspx

For more information on SharePoint Claims check out more articles at http://social.technet.microsoft.com/wiki/contents/articles/14214.sharepoint-2013-claims-based-authentication.aspx

SharePoint 2013 Authentication – Windows Claims

Sharepoint 2013

SharePoint 2013 – Windows Claims Authentication

The following is the interaction between

  1. Client Computer
  2. SharePoint Server
  3. Active Directory Domain Service

The Windows Claims Authentication Process

  1. User does anonymous request to secured SharePoint Webpage
  2. SharePoint requests back Windows Credentials (It can be a NTLM or Kerberos or basic)
  3. If user is in intranet zone, the browser sends back the logged in credentials to SharePoint, else user is prompted for credentials
  4. For both the cases the browser send back the credentials to SharePoint
  5. SharePoint then validates this credentials with Active Directory Domain Services (AD DS)
  6. AD DS then responds back to SharePoint with Windows Security Token
  7. SharePoint then checks, to which security groups the user belongs in AD DS
  8. SharePoint then creates a claims based security token using Security Token Service
  9. Then SharePoint stores this security token with Distributed Cache Service on the farm
  10. The IIS Server in SharePoint server then send the auth code to the user’s computer
  11. The client computer then uses this auth code for subsequent requests

The following Video will explain the Windows claims authentication in SharePoint 2013. This video is part of the Authentication overview for SharePoint 2013 article located at https://technet.microsoft.com/en-us/library/jj219571.aspx

For more information on SharePoint Claims check out more articles at http://social.technet.microsoft.com/wiki/contents/articles/14214.sharepoint-2013-claims-based-authentication.aspx

Execute Custom JavaScript code in SharePoint Content Editor webpart

When we try to execute a custom java script code in SharePoint content editor web part, it may not work. The reason behind is that, there might be a conflict occurring during load.

Microsoft provides ways to launch your function after full page load and following is one of the method.

<script type="text/javascript">
    _spBodyOnLoadFunctionNames.push("LaunchCustomCode");
    LaunchCustomCode = function() {
		ExecuteOrDelayUntilScriptLoaded(MyCode, "sp.js");
	}

	MyCode = function() {
	console.log('My Code Start');
        alert('MyCode Called');
        console.log('My Code Finish');
	}

</script>

Add count to drop down refiners in SharePoint search refinement webpart

While working on designing display template for drop down based refiners in SharePoint Search there was a requirement to show counts along with refiners in refiners list.

Following is the change which I made in the refiner’s display template.

Actual code

<option value='_#= onChangeOrClick =#_'>_#= $htmlEncode(refinementName) =#_</option>

 Updated Code

<option value='_#= onChangeOrClick =#_'>_#= $htmlEncode(refinementName)  =#_  (_#= refinementCount =#_)</option>

Hide Available Refiners in SharePoint search refinement panel

Recently one of the customer had a strange request where the customer wanted to Hide “Available Refiners” in SharePoint search refinement panel.

The “Available Refiners” is available in “Drop Down” type refinement panel.

SharePoint Refinement Panel

When the refinement panel is being loaded, SharePoint executes a JavaScript function named AddPostRenderCallback. This would be available in the Refinement Display Template located under MasterPage/Search Gallery. The actual method looks like below code which is taken from O365.

AddPostRenderCallback(ctx, function() {
    if (hasAnyFiltertokens) {
        // Get the hidden block
        var hiddenOptions = document.getElementById(hiddenBlockID).children;
        var unSelGroup = document.getElementById(unselDD);
        var selGroup = document.getElementById(selDD);
        // Clone all the elements from the hidden list to the unselected option group
        for (var i = 0; i < hiddenOptions.length; i++) {
            var selectedElm = GetAllElementsWithAttribute(selGroup, 'value', hiddenOptions[i].getAttribute('value').replace('updateRefinersJSON', 'removeRefinementFiltersJSON'));
            if (selectedElm === null || selectedElm.length <= 0) {
                var cloneElm = hiddenOptions[i].cloneNode(true);
                unSelGroup.appendChild(cloneElm);
            }
        }
    }
});

To the above original code I made a small change so that “Clone all the elements” code executes only when user has selected a refiner.

// Clone all the elements from the hidden list to the unselected option group
if(selectedFilters.length <= 0)
{
	for (var i = 0; i < hiddenOptions.length; i++) {
		var selectedElm = GetAllElementsWithAttribute(selGroup, 'value', hiddenOptions[i].getAttribute('value').replace('updateRefinersJSON', 'removeRefinementFiltersJSON'));
		if (selectedElm === null || selectedElm.length <= 0) {
			var cloneElm = hiddenOptions[i].cloneNode(true);
			unSelGroup.appendChild(cloneElm);
		}
	}
}

To the above orignal code I added the following code to hide the “Available Refiners” option.

if(selectedFilters.length > 0)
{
	if(unSelGroup!=null)
	{
		unSelGroup.style.display = 'none';
	}
}

The above code will hide the “unSelGroup”‘s “Option Group” HTML to hide the Options for “Available Refiners”.

Final code would look like below.

AddPostRenderCallback(ctx, function() {
    if (hasAnyFiltertokens) {
        // Get the hidden block
        var hiddenOptions = document.getElementById(hiddenBlockID).children;
        var unSelGroup = document.getElementById(unselDD);
        var selGroup = document.getElementById(selDD);
        // Clone all the elements from the hidden list to the unselected option group
        if(selectedFilters.length <= 0)
        {
            for (var i = 0; i < hiddenOptions.length; i++) {
                var selectedElm = GetAllElementsWithAttribute(selGroup, 'value', hiddenOptions[i].getAttribute('value').replace('updateRefinersJSON', 'removeRefinementFiltersJSON'));
                if (selectedElm === null || selectedElm.length <= 0) {
                    var cloneElm = hiddenOptions[i].cloneNode(true);
                    unSelGroup.appendChild(cloneElm);
                }
            }
        }
        //Added for Gold Asset requirement where once a refiner is selected the "Avaialble Refiners" item should be made hidden
        if(selectedFilters.length > 0)
        {
            if(unSelGroup!=null)
            {
                unSelGroup.style.display = 'none';
            }
        }
        
        var refinerUpArrow = document.getElementById('refinerExpandCollapseArrow');
        if(refinerUpArrow!=null)
        {
            refinerUpArrow.style.display = 'none';
        }
        
    }
});

End Result is following
Hidden Available Refiners Option Group

Clear SharePoint Search Results

SharePoint Clear SharePoint Search Results

Recently I had a requirement for OOTB search Box + Result where the customer wanted to clear the search results regardless of any refinement selected or not.

Clear SharePoint Search Results

To implement this, in the display template HTML the following was added.

Do note that if refinements are there, the commented single line of code didn’t work and I had to replace the entire # as blank. Do check the original source (mentioned below) for more information.

<!--#_
    clearSearchResults = function()
    {
        var hash = window.location.hash;
        if( hash.indexOf('Default') == 1 ) {
            hash = unescape(hash);
            var kIdx = hash.indexOf('"k":'); 
            var rIdx = hash.indexOf('","'); 
            var query = hash.substring(kIdx+5,rIdx);
            query = query.replace(/\\/g, '');
            //window.location.href = window.location.pathname + window.location.search + '#k=' + escape(query);
            window.location.href = window.location.pathname + window.location.search + '#';
        } else {
            window.location.href = window.location.pathname + window.location.search + "#";
        }                    
    }
_#-->
<div id="ClearSearch" class="ms-alignCenter">
    <h2><a onclick="clearSearchResults();"  style="cursor:pointer">Clear/Reset All</a></h2>
</div>

The source for the above code is Add a “Clear Filters” link to your search page in SharePoint 2013

SharePoint JavaScript Error Script5009 ‘type’ is undefined sp.js

When we add the sp.js link to the SharePoint Webpart Page or simple ASPX Page and when the page loads we get the following error.

script5009 ‘type’ is undefined sp.js

The solution I saw in the web for this is, add Micrsofot Ajax script.

<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js"></script>

Do note that this resolves the similar error which occurs when we add other SharePoint js files as well.

Setting up Provider Hosted App

There are many articles which explain how to setup the Remote Web & SharePoint On-Prem. The following articles explains everything end to end.
http://blogs.msdn.com/b/russmax/archive/2014/06/23/part-1-intro-to-provider-hosted-apps-setup-the-infrastructure.aspx
http://blogs.msdn.com/b/russmax/archive/2014/06/26/part-2-intro-to-provider-hosted-apps-develop-package-and-deploy.aspx

Get People Picker Field Value from SharePoint List – JSOM

Following is the JSOM code which will help in getting single or multiple items from a SharePoint’s People Picker Field.

function GetPeoplePickerFieldValue(currentListItem, internalFieldName) {
    if (currentListItem.get_item(internalFieldName) !== 'undefined' && currentListItem.get_item(internalFieldName) !== null) {
        if (currentListItem.get_item(internalFieldName).length > 0) {
            var _user = "";
            //If field has only one item
            if (currentListItem.get_item(internalFieldName).length == 1) {
                _user = currentListItem.get_item(internalFieldName)[0].get_lookupValue();
                if (_user == null)
                    _user = "";
            }
            //If field has multiple item
            if (currentListItem.get_item(internalFieldName).length > 1) {
                for (var i = 0; i < currentListItem.get_item(internalFieldName).length; i++) {
                    //Append all User names with a semi colon separator
                    _user = _user + currentListItem.get_item(internalFieldName)[i].get_lookupValue() + "; ";
                }
                _user.trim;
                if (_user == null)
                    _user = "";
            }
        }
        return _user;
    }
}

Source: Microsoft TechNet Forum

Copy current item ID to clipboard using SharePoint custom action

Recently I had a requirement where the user needed to copy an item’s URL to clipboard in SharePoint.

Using the SharePoint designer, I created a Custom Action and in the “Navigate to URL” action type I set the following.

javascript:clipboardData.setData("Text", window.location.protocol+'//'+window.location.hostname+':'+window.location.port +'/sites//Lists//DispForm.aspx?ID='+'{ItemId}');alert('Item URL \"'+window.location.protocol+'//'+window.location.hostname+':'+window.location.port +'/sites//Lists//DispForm.aspx?ID='+'{ItemId}'+'\" copied to clipboard');