Saturday, August 27, 2016

One issue with custom login page with claims-based authentication in Sharepoint

One of our sites was migrated from Sharepoint 2007 to Sharepoint 2013. In 2007 it used FBA with custom login page. After migration user noticed strange behavior: sometime Sharepoint returned empty page or HTTP 500 Internal server error. During checking Sharepoint logs the following error was found there:

Exception of type 'System.ArgumentException' was thrown.  Parameter name: encodedValue 
at Microsoft.SharePoint.Administration.Claims.SPClaimEncodingManager.DecodeClaimFromFormsSuffix(String encodedValue)   
at Microsoft.SharePoint.Administration.Claims.SPClaimProviderManager.GetProviderUserKey(IClaimsIdentity claimsIdentity, String encodedIdentityClaimSuffix)   
at Microsoft.SharePoint.Administration.Claims.SPClaimProviderManager.GetProviderUserKey(String encodedIdentityClaimSuffix)   
at Microsoft.SharePoint.Utilities.SPUtility.GetFullUserKeyFromLoginName(String loginName)   
at Microsoft.SharePoint.SPGlobal.CreateSPRequestAndSetIdentity(SPSite site, String name, Boolean bNotGlobalAdminCode, String strUrl, Boolean bNotAddToContext, Byte[] UserToken, SPAppPrincipalToken appPrincipalToken, String userName, Boolean bIgnoreTokenTimeout, Boolean bAsAnonymous)   
at Microsoft.SharePoint.SPWeb.InitializeSPRequest()   
at Microsoft.SharePoint.SPWeb.EnsureSPRequest()   
at Microsoft.SharePoint.WebControls.SPControl.EnsureSPWebRequest(SPWeb web)   
at Microsoft.SharePoint.WebControls.SPControl.SPWebEnsureSPControl(HttpContext context)   
at Microsoft.SharePoint.ApplicationRuntime.BaseApplication.Application_PreRequestHandlerExecute(Object sender, EventArgs e)   
at Microsoft.SharePoint.ApplicationRuntime.SPRequestModule.PreRequestExecuteAppHandler(Object oSender, EventArgs ea)   
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()   
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

When web application was migrated to 2013 it started to use claims-based authentication. Custom login page was re-implemented using the following authentication logic (there are many examples of custom login page for FBA when claims-based authentication is used. Most of them use more or less the same logic):

   1: var formsAuthOption = SPFormsAuthenticationOption.None;
   2: var tokenType = SPSessionTokenWriteType.WriteSessionCookie;
   3: if (rememberMe)
   4: {
   5:     formsAuthOption = SPFormsAuthenticationOption.PersistentSignInRequest;
   6:     tokenType = SPSessionTokenWriteType.WritePersistentCookie;
   7: }
   8:  
   9: var settings = site.WebApplication.IisSettings[SPContext.Current.Site.Zone];
  10: var authProvider = settings.FormsClaimsAuthenticationProvider;
  11: var securityToken =
  12:     SPSecurityContext.SecurityTokenForFormsAuthentication(
  13:     context,
  14:     authProvider.MembershipProvider,
  15:     authProvider.RoleProvider,
  16:     username,
  17:     pwd,
  18:     formsAuthOption);
  19:  
  20: var fam = SPFederationAuthenticationModule.Current;
  21: fam.SetPrincipalAndWriteSessionToken(securityToken, tokenType);
  22:  
  23: FormsAuthentication.SetAuthCookie(username, false);

On lines 9-21 we authenticate user via FBA claims authentication provider (SPIisSettings.FormsClaimsAuthenticationProvider). If provided user credentials are incorrect, call to SPSecurityContext.SecurityTokenForFormsAuthentication() method will throw exception. If credentials are correct it will set FedAuth authentication cookies.

On line 23 there is call to FormsAuthentication.SetAuthCookie() method which sets previously used .ASPXAUTH cookies used by ASP.Net FBA authentication. Developer who implemented login page told that it was left there for backward compatibility, but was not able to remember which exact components required this cookies.

And as it turned out presence of both FedAuth and .ASPXAUTH cookies caused mentioned exception in SPClaimEncodingManager.DecodeClaimFromFormsSuffix(). When call to FormsAuthentication.SetAuthCookie() was removed, error disappeared. Hope that information will help someone.

Wednesday, June 29, 2016

Show Created date from Sharepoint document library via Word Quick parts

In Word it is possible to add Sharepoint metadata fields directly to the document: Insert > Quick parts > Document properties. The problem however is that we can’t show value of OTB Created field which contains datetime when document was added to the document library (don’t mix it with file created datetime which is shown when we check file properties in Windows explorer):

Fortunately there is workaround which can be used for achieving the same result. The idea is that we will create new custom field CreatedQP and will copy value from Created field to it. The question is how exactly values will be copied. First approach which comes to the mind is to created calculated field which will just copy value from Created field:

However if we will check available document properties in quick parts we will see that newly created calculated field is not shown there as well. So the only option is to create regular DateTime field and then copy value from Created field to it whether by using workflow or event receiver. In this article I will show how to do it via workflow.

So first of all we need to create new field:

After that we open parent site in Sharepoint Designer and create new List workflow for our document library:

Add new action “Update List Item” and configure it to copy value from Created field of current list item to CreatedQP field:

and finish workflow:

After that we configure workflow to start automatically when new document is added to the document library:

and publish workflow.

Now if we will add new document to the document library, open it in Word and add CreatedQP via Quick parts > Document properties:

created datetime from Sharepoint doclib will be shown in the document:

The drawback of this approach is that users will be able to change value of CreatedQP field via Quick part control. One possible way to avoid it is to try to make CreatedQP field readonly, but I didn’t test this approach by myself.

Tuesday, June 28, 2016

Problem with Azure Media Player and html5 video preload in Chrome

In one of Sharepoint Online site we are working over Azure Media Player was used for playing the html5 videos on the page. This player works on top of standard html5 <video> tag and has a lot of additional features comparing with basic html5 video player built in to browsers. Performance audit made for pages where it is used showed that browser downloads the whole video mp4 file on page load. Video files took Mbs of data and were the biggest part of overall recourses size being downloaded.

Html5 video tag has special preload attribute using which we can control video preloading behavior:

Value Description
auto

The author thinks that the browser should load the entire video when the page loads

metadata The author thinks that the browser should load only metadata when the page loads
none The author thinks that the browser should NOT load the video when the page loads

However after setting preload to none, Azure Media Player (we used latest version 1.6.1) stopped working in Chrome (in IE and FF it worked): it showed video download progress indicator infinitely and when you clicked on the video thumbnail nothing happened:

So for now we decided to switch to the basic html5 video player which doesn’t have this issue and works in all browsers (also tried http://videojs.com, but didn’t find significant value which it adds comparing with basic html5 player). Although preload attribute itself is not supported in Edge, but this is different story).

Tuesday, June 21, 2016

Disappeared permissions for “Everyone except external users” in Sharepoint Online

Recently we faced with interesting issue in Sharepoint Online: for some parts of the intranet unique permissions were used. And for these securable objects we used special Sharepoint “group” (which is actually not real Sharepoint group) – Everyone except external users. One the same securable objects there were also permissions assigned to normal Sharepoint groups. After some time without any actions from our side permissions assigned to “Everyone except external users” group disappeared, but permissions assigned to normal Sharepoint groups not.

For now we solved it by using new Sharepoint group which has other AD group which in turn has all users in organizations and new employees are added there automatically (fortunately customer’s administrator had this group), but anyway this is quite interesting problem. So if you will face with the same issue or will find reason of this behavior please share it in comments.

Thursday, June 2, 2016

Remove duplicates in calendar overlays in Sharepoint

In Sharepoint calendar it is possible to have events of different categories and create separate views for each category. Also it is possible to create calendar overlays, i.e. combine these views to the single view where events from different categories will be displayed using different colors. However there is a problem with this approach that events in overlay will be duplicated by default. In this article I will show how to create these overlays and how to fix issue with duplicated events.

Let’s start from creating calendar overlays. At first we need to define event categories in List settings > Category field (choice) > specify needed categories. In our example we will use the following categories:

  • Meeting
  • Work hours
  • Business

After that create view for each category from the list ribbon Create view. For each view we create filter on Category field like shown on the following picture and use category as view name:

and repeat this step for each category. After that we can create calendar overlay. It is done also from ribbon Calendars overlay button which opens the following page:

As you can see by default it doesn’t contain any calendars. Click New calendar link here and specify Name, Color and View for the new layer in the calendar overlay. In order to populate calendar list and all created views we will need to create Resolve button first. Also it is good practice to use the same name for the overlay as view name (and as category name):

Also repeat this step for each category. After that our default calendar view will look like this:

Now let’s create one test event e.g. for Meeting category. It will look like this:

As you can see created event is duplicated in the view. In order to solve this issue we need to edit default calendar view as well and specify filter for Category field. We can set filter there that only events which don’t belong to any category should be shown there (Category is equal to “” (empty string)) or we may apply more complex filter and show only those events which don’t correspond to any mentioned categories. In last case if new category will be added in future events which correspond to this category will be displayed in the default view (unless separate view won’t be created and added to overlay. In this case you will need to add it to the filter of default view as well in order to not get duplicates again):

or

At the end calendar will look like this:

and as you can see there are no duplicates anymore.

Friday, May 20, 2016

One reason for The request uses too many resources error when create sub site in Sharepoint Online

Recently we faced with the following issue: when users with standard Manage hierarchy permission level (according to description of this permission level, user with these permissions “can create sites and edit pages, list items, and documents”) tried to create sub site in Sharepoint Online the following exception was thrown:

ServerException: Provisioning did not succeed. Details: Failed to initialize some site properties for Web at Url: 'http://example.com' OriginalException: The request uses too many resources.

StackTrace: at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream responseStream) at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse() at Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryToServer(ChunkStringBuilder sb) at Microsoft.SharePoint.Client.ClientRequest.ExecuteQuery() at Microsoft.SharePoint.Client.ClientRuntimeContext.ExecuteQuery() at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery() at Microsoft.SharePoint.Client.ClientContextExtensions.ExecuteQueryImplementation(ClientRuntimeContext clientContext, Int32 retryCount, Int32 delay)

We tried to increase server resource quota, but it didn’t help. The problem existed both for sites created from custom SP app and for standard site templates.

In order to avoid this error the following steps can be done: go to Site settings > Site permissions > Permission levels > Manage hierarchy and check the following permissions (by default they are unchecked for Manage hierarchy permission level):

  • Apply Themes and Borders – Apply a theme or borders to the entire Web site
  • Apply Style Sheets – Apply a style sheet (.CSS file) to the Web site

So they will look like this:

After that hierarchy managers should be able to create sub sites.

Tuesday, May 10, 2016

How to set author displayed in Mercurial commits on Windows

Note for readers: in this article I will show how to configure author name on Windows PC for future Mercurial commits. It won’t contain information how to change author for commits which were already done.

If you work with different repositories sometime it may be necessary to change Author field displayed in commits history. On Windows PCs in order to do that go to C:\Users\{username} and edit mercurial.ini file:

[ui]
username = developer

In this example “developer” is the user name which will be displayed in Author field. If you will now open TortoiseHG Workbench tool new user name should be displayed in Author column.