The blog of Wictor Wilén

  • Using SharePoint 2013 with Thinktecture IdentityServer 2

    Tags: SharePoint 2013, Claims

    Introduction

    SharePoint 2013 (and earlier versions) allows you to use alternative authentication “sources” than Windows. We can part from the different options with Windows login, use Forms Based Authentication (FBA) or use a federated/trusted identity provider. Forms based authentication is a good approach if you don’t want to manage your users in Active Directory or if you don’t want to use Windows Login. The downside with FBA is that you must manually do some web.config modifications, there isn’t any UI for managing the users (yes, I know you can use LDAP or just download something from the tubez, but you get my point). Using a federated approach is more interesting, that allows you to get the identity management and authentication away from your SharePoint farm (and this is a really good thing, SharePoint admins are generally not identity management people!). A trusted identity provider is a service such as Active Directory Federation Services (AD FS), Microsoft Azure Access Control Services (ACS) or any other SAML 1.1 compatible Identity Provider (IdP).

    I generally don’t like using FBA, due to the issues above. In this post I will show you how to do forms based authentication without using FBA, but instead using a trusted identity provider called Thinktecture IdentityServer 2. IdentityServer 2 is an awesome implementation of an identity provider and supports a plethora of standards. And it comes as open source, with a web based UI, is very configurable and is just one of the best options for you when you need to set up your SharePoint with users not in Active Directory.

    Thinktecture IdentityServer 2

    Without describing the Thinktecture IdentityServer 2 in my own words I think the official overview says enough:

    IdentityServer is a light-weight security token service built using .NET 4.5, ASP.NET MVC4, WCF and Web API. It has out-of-the-box support for user management using the ASP.NET membership and roles provider, but provides extensibility points to integrate arbitrary user databases. Futhermore almost any aspect of token issuance and data management can be customized using a plugin model.

    The really cool thing with it is that it supports SAML 1.1 and can be used as a SharePoint 2013 (or 2010) trusted identity provider with a few lines of PowerShell. Secondly if you already has SharePoint hooked up to AD FS (or another similar service) you can add IdentityServer 2 as Claims Provider Trust.

    Installing IdentityServer 2

    The first thing we should do is to get our hands on IdentityServer 2 and set it up in our environment. You have two options; either make a github clone if you need to modify the source (https://github.com/thinktecture/Thinktecture.IdentityServer.v2) or download it directly (http://thinktecture.github.io/Thinktecture.IdentityServer.v2/downloads/). In this post I assume you don’t want to do any development and do it the lazy way and just downloads it. Ok, the official link above will only give you a 404 when you click on the download link at the moment, so use this page instead to download the .zip file for version 2.2: https://github.com/thinktecture/Thinktecture.IdentityServer.v2/releases/v2.2.0.

    Now create a folder called IdSrv (or whatever you prefer) on one of your local disks, for instance d:\IdSrv\, and extract the ZIP file there. Next we need to create an IIS Web Site that uses this directory. Before proceeding with that we need to create a web server certificate – remember, always use certificates for these kind of services! You could use a self signed, but as always if you can use a domain/real CA that is preferred. Also you might need to set up a DNS entry, which is what I will use (idsrv.contoso.com). Once you have the certificate and hostname then you can proceed to the IIS configuring.

    We’ll create a new IIS site pointing at the folder we unpacked IdentityServer to. We also need to specify the binding to use https and select our certificate, image on the left below. When we click OK this will create a new application pool for us in IIS, for that application pool we need to switch the identity to use a domain account or if we’re doing a single server install use the Network Service, image on the right below.

    New IIS web site and bindings Change the app pool identity

    Since we now told IdentityServer to run as Network Service we also need to modify the folder permissions of the App_Data catalog and give the Network Service Modify permissions on that catalog. The App_Data catalog is where IdentityServer by default stores its database.

    Once we have done this we can browse to the binding specified in IIS and start using IdentityServer 2.

    Since this is a fresh installation and IdentityServer has no database we will be presented by a configuration screen. On that screen you should enter a site name, you must specify the Issuer URI (which uniquely identifies this issuer) as well as choose a signing certificate (this could be the one you created for the web site or a different one). Then you also need to specify an administrator username and password.

    Before you click save you must make sure that the account running the application pool (Network Service in this sample) has permissions to read the private key of the certificate that you use as signing certificate.

    Configuring IdentityServer

    Once you have done that you are all set to go!

    Users and roles

    To create users and roles you log in as the administrator and go to the administration menu and select users and/or roles. If you want to extend the user profile with more properties you need to modify the profile.config file under /Configuration in the IdentityServer folder. For this sample I add an additional property called “Title”, which I will use in a bit.

    Before proceeding create at least one user and add that user to the “IdentityServerUsers” role, that is by default the role that is needed to use IdentityServer for authentication federation.

    Final identity server tweaks

    Ok, now have an awesome identity system up and running. We need to tweak a few things in IdentityServer before doing the SharePoint stuff. We need to add a Relying Party (RP) to IdentityServer, and the Relying Party in this case is SharePoint. As the administrator in IdentityServer choose to add a new Relying Party. This RP needs a display name, a realm and a redirect URL. The display name is whatever you prefer, the realm must be a URI and the Redirect URL should be you SharePoint site with “/_trust/” appended, like in the screenshot below.

    Relying party in IdentityServer

    Another tweak we need to do is to tell identity server to use SAML 1.1 instead of SAML 2.0, since SharePoint does not support SAML 2.0. That is done under General Configuration of IdentityServer and the “Default WS* Token” property should be set to “urn:oasis:names:tc:SAML:1.0:assertion”.

    SNAGHTML10f558c

    Adding IdentityServer 2 as a trusted identity provider

    Now it is time to head on over to SharePoint and fire up a PowerShell prompt! The first thing we will do is to define a couple of properties:

    ## PROPERTIES
    $realm = "uri:identityserver:sp03"
    $signinurl = "https://idsrv.contoso.com/issue/wsfed"
    $description ="Provide description here"
    $url = "https://rootsite.sp03.contoso.com"
    $metadataurl = "https://idsrv.contoso.com/FederationMetadata/2007-06/FederationMetadata.xml"

    The realm must be the same realm that we configured in IdentityServer for the Relying Party. The signinurl can be found on the home page > application integration in IdentityServer and it’s the URL called WS-federation. Description is just some description that you provide and url is the URL to the Web Application where you want to add this identity provider. Finally metadataurl is the WS-federation metadata end-point for identity server and that URL can be found on the same page as where we located the sign in URL.

    We’ll use this WS-federation metadata end-point to do some discovery from the SharePoint side:

    ## LOAD FEDERATION METADATA
    $fedmd = Invoke-WebRequest -Uri $metadataurl
    $fedmdXml = New-Object Xml
    $fedmdXml.LoadXml($fedmd.Content)
    $base64 = $fedmdXml.EntityDescriptor.RoleDescriptor.KeyDescriptor.KeyInfo.X509Data.X509Certificate
    $base64| Out-File -FilePath temp.cer -Append:$false
    $cert = Get-PfxCertificate -FilePath temp.cer
    Remove-Item temp.cer
    

    By invoking the end-point we can retrieve the signing certificate, and other metadata. We grab that certificate and temporary stores it as a .cer file before loading it up in a certificate variable which will be used to install it in SharePoint.

    ## ADD TRUST IN SP
    asnp *sh*
    $name = $fedmdXml.EntityDescriptor.RoleDescriptor.GetAttribute("ServiceDescription")
    New-SPTrustedRootAuthority -Name $name -Certificate $cert | Out-Null
    

    We use the certificate variable to create a trust in SharePoint, together with the name of the service, retrieved from the metadata endpoint.

    Next up is to create some claims mappings and the trusted identity token issuer in SharePoint.

    ## CREATE TRUSTED IDENTITY TOKEN ISSUER
    $map1 = New-SPClaimTypeMapping "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" `
        -IncomingClaimTypeDisplayName "Email" –SameAsIncoming 
    $map2 = New-SPClaimTypeMapping "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" `
        -IncomingClaimTypeDisplayName "Role" -SameAsIncoming 
    $map3 = New-SPClaimTypeMapping "http://identityserver.thinktecture.com/claims/profileclaims/title" `
        -IncomingClaimTypeDisplayName "Title" -SameAsIncoming 
    $tit = New-SPTrustedIdentityTokenIssuer -Name $name -Description $description -Realm $realm `
        -ImportTrustCertificate $cert -ClaimsMappings $map1,$map2,$map3 -SignInUrl $signinurl `
        -IdentifierClaim $map1.InputClaimType
    

    We create three claims mappings in this case; the first one is the e-mail claim, the second one is a role claim and the third one is our custom claim using the user property Title we created. We can get the claims identifiers from the XML in the metadata endpoint. We’ll use the first claim, e-mail, as our identity claim when we finally create the trusted identity token issuer also passing in the realm and sign-in URL.

    Once this is done all we need to do is update our Web Application(s) to use this new identity provider. This can be done in the UI in Central Administration per Web Application or using PowerShell like this:

    ## UPDATE WEB APPLICATION WITH NEW IDP
    $wa = Get-SPWebApplication $url
    $ap = Get-SPAuthenticationProvider -WebApplication $wa -Zone Default
    if($ap.Count -eq 1) {
        $aps = New-Object System.Collections.ArrayList
        $aps.Add($ap) | Out-Null
    } 
    else {
        $aps = $ap
    }
    $ap = New-SPAuthenticationProvider -TrustedIdentityTokenIssuer $name
    $aps.Add($ap) | Out-Null
    Set-SPWebApplication -AuthenticationProvider $aps -Zone Default -Identity $wa
    

    First we retrieve the current authentication providers for the web application, then we create a new one from our just recently created trusted identity token issuer and then we add them all (as an array) to the web application.

    That’s it! Time for a test ride…

    Browse to a site on the web application where you enabled the IdentityServer authentication. You should be presented with the awesome standard SharePoint login selector page. In the drop down you will see two options; Windows Authentication and our IdentityServer option:

    Some sweet UI

    Select to log in using IdentityServer. This will take you to the log in page of identity server, where you present your credentials. If you log in using that user you created in identity server you will after a successful login see an access denied page from SharePoint. That’s because that user doesn’t have permissions yet.

    It is now we can take advantage of that we added the role or title claims. Open up a new browser and log in using Windows Authentication and give permissions to either a role or a title. Unfortunately the default claims people picker in SharePoint is a bit stupid when it comes to working with claims. You need to write the name of the group or title and then pick the correct claim. Hover the cursor over the alternatives to see which identity provider and which claim is which one. In this case we see three (our three different claims).

    Default Claims People Picker

    Once you have given permissions to a role, title or directly to the e-mail of the user, you should be able to log in properly and see the site.

    Summary

    In this post I’ve shown you how to use Thinktecture IdentityServer 2 as an identity provider to SharePoint 2013. IdentityServer is a great alternative to using FBA when you need a custom user and role store and it’s way easier and more manageable to set up, no fiddling with web.configs or installing full trust code you download from the interwebs in your SharePoint farm. Enjoy!

  • SharePoint 2013 with SAML Claims and Provider Hosted Apps

    Tags: SharePoint 2013, AD FS, Claims, Windows Server 2012 R2, Apps

    Introduction

    The other week I posted an article about how to use SharePoint Hosted Apps when using SAML Claims, I did not expect that amount of feedback I had on that blog post, in e-mail, comments, tweets etc. Some of that feedback was how do you do it with Provider Hosted apps. Well you’re about to find out. It took me a while to get it properly done and there are some things that you should be aware of. In this post I will walk you through the simplest scenario and you will notice that there are a couple of moving parts. But, since I am such an influencer I thought I should make it easier for you. I will show you how to do this without the minimal changes to your current provider hosted apps – you only have to add an extension file to your solution, make a small modification to the helper files that Visual Studio gives you and a couple of web.config modifications! All the code you need will be published in a Github repository (https://github.com/wictorwilen/SharePointContextSaml) for you to consume and do all the fancy gitty stuff that you code dweebs out there like.

    Let’s get started, bare with me this is a long post and for some of you the first parts might be just a repeat of what you’ve seen/done previously…

    Creating a Provider Hosted High Trust App

    The first thing we need is to create us a High Trust Provider Hosted App. That is an app that does not run in SharePoint and is using the Server to Server (S2S) protocol for authorization. In my case (and it should be yours as well if you want to use my helper code) is to use Visual Studio 2013 and create a SharePoint App, choose a provider hosted app using the ASP.NET MVC template. To create a High Trust App we then need to specify a certificate for the S2S trust. This is how you can create a cert using makecert.exe and some PowerShell. In the script below all you need to do is modify the four properties; domain, name and password of cert and the location where we will store the certificate files:

    #ALIASES
    set-alias makecert "C:\Program Files\Microsoft Office Servers\15.0\Tools\makecert.exe"
    
    # CREATE SELF SIGNED DEV CERTS
    $domain = "localhost"
    $certName = "HightTrustSAMLDemo" 
    $password = "Pass@word1"
    $dir = "c:\HighTrustCerts\"
    
    New-Item $dir -ItemType Directory -Force -Confirm:$false | Out-Null
    
    $publicPath = $dir + $certName + ".cer"
    $privatePath = $dir + $certName + ".pfx"
    
    makecert -r -pe -n "CN=$domain" -b 01/01/2012 -e 01/01/2022 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localMachine -sky exchange -sy 12 -sp "Microsoft RSA SChannel Cryptographic Provider" $publicPath 
    
    $publicCert = Get-PfxCertificate -FilePath $publicPath
    $publicThumbprint = $publicCert.Thumbprint
    
    Get-ChildItem Cert:\LocalMachine\My | 
        Where-Object {$_.Thumbprint -eq $publicThumbprint} | 
        ForEach-Object {
            $_.Export("PFX",$password) |Set-Content $privatePath -Encoding Byte        
        }

    Once we have the certificate we need to install the certificate in the SharePoint certificate store as well as register a Trusted Security Token Issuer. And to do this we need a Guid! You can use any preferred tool to generate your Guid or generate and register your very own unique Guid at www.vanityguid.com. Here’s a script the does the trick; give it your very own unique Guid/Issuer Id and a unique display name:

    $issuerId = '17721805-67c2-46ba-92d1-fd1fdf91bb01' # MUST BE UNIQUE
    $displayName = "High Trust SAML Demo" # MUST BE UNIQUE
    
    Add-PSSnapin Microsoft.SharePoint.PowerShell -EA 0
    $certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($publicCert)
    
    New-SPTrustedRootAuthority -Name $certName -Certificate $certificate
    $realm = Get-SPAuthenticationRealm
    $fullIssuerId = $issuerId + "@" + $realm
    
    New-SPTrustedSecurityTokenIssuer -Name $displayName -Certificate $certificate -RegisteredIssuerName $fullIssuerId –IsTrustBroker
    iisreset 

    Yes I trust Wictor!Ok, this was standard High Trust App procedure. Copy and paste the issuer Id into the Visual Studio wizard and enter the certificate details to complete the app creation. What you have right now is a standard High Trust app ready to work with Windows (claims) users. Before you start hacking in some code into this app – just make sure that it properly deploys and executes (ie press F5), so that you haven’t messed up any Guids or anything else. This app should now run using IISExpress and it uses Windows Authentication (remove http(s)://localhost from Local Intranet sites in Internet Explorer if you want to test different users).

    What about them SAML users?

    So let’s see what happens if we log into our SharePoint Developer site, where we deployed our High Trust app, as a SAML user (using for instance AD FS 3.0). Of course you need to setup a trusted identity token issuer before doing that, how that’s done is out of scope of this post. When logged in as a SAML user and I click on the High Trust App I either get logged into the app as the currently logged on Windows user or I get the Windows login dialog (if http(s)://localhost was removed from Local Intranet sites). So, it doesn’t really work! We don’t even get the chance of authentication with our AD FS (or similar federation service).

    Configuring the app for federated Authentication

    ASP.NET devs get all the new shiny stuffWhat we need to do is modify our web application (the provider hosted web) to use federated authentication. Unfortunately we are SharePoint developers, and are not given all the love that ordinary ASP.NET developers are from the Visual Studio team. When creating a standard ASP.NET project we get the really awesome option of specifying which authentication method we would like to use and we can point out our federation service and Visual Studio fixes everything for us.

    We can do this in two different ways. Either we add a new ASP.NET MVC project and remove the default web project and convert that ASP.NET MVC project into a SharePoint app project (which is the easiest way) or we start fiddling with web.config and configure it ourselves – which is exactly what we’re going to do here!

    The first thing we need to do is to use NuGet and add the Microsoft ASP.NET Identity Core package and the Microsoft Token Validation Extension for .NET 4.5. These package will give us all the assemblies and references we need to run the app.

    NuGet FTW!

    In your web application project open up web.config, now we’re going to do some copy-paste work! First of all we need to add a configSections element for the System.IdentityModel. Insert the snippet below directly after the configuration element:

    <configSections>
      <section name="system.identityModel" 
        type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
      <section name="system.identityModel.services" 
        type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
    </configSections>

    Then head on over to the system.web element and below the authorization element add the following.

    <authentication mode="None" />  

    This means that we’re not letting ASP.NET do the Authentication, but instead handling it over to a new module which we’re going to add. Directly after the system.web element copy and paste the following, which will add two new modules to the ASP.NET pipeline:

    <system.webServer>
      <modules>
        <add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
        <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
      </modules>
    </system.webServer>
    These two modules are called WSFAM and SAM (two more acronyms for you JB). WSFAM is responsible for the login/logout process and SAM takes care of session management by using cookies.

    Then we need to add the configuration for our Relying Party. This is done by adding the system.identityModel element after the system.serviceModel element. It’s a handful of configuration and we need to modify it in a few places to match our app and our federation service.

    <system.identityModel>
      <identityConfiguration>
        <audienceUris>
          <add value="uri:SharePoint:App:SAML" />
        </audienceUris>
        <securityTokenHandlers>
          <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
          <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        </securityTokenHandlers>
        <certificateValidation certificateValidationMode="None" />
        <issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
          <authority name="fs.contoso.com">
            <keys>
              <add thumbprint="EF66CEF27067637D296C403691DBBE2A8B5C7BAA" />
            </keys>
            <validIssuers>
              <add name="http://fs.contoso.com/adfs/services/trust" />
            </validIssuers>
          </authority>
        </issuerNameRegistry>
      </identityConfiguration>
    </system.identityModel>

    First of all on line #4 – that row must contain the relying party identifier for our app registered in AD FS. I prefer using a URI, since that makes it easier when I need to deploy this into production, but you could use the URL of your web application (https://localhost:44305/ for instance). I’ll show you in just a minute how to configure this in AD FS. Line 12 should contain the name of our authority and line 17 must have the Federation Service Identifier of AD FS (found under Federation Service Properties in the AD FS Console). On line 14 we need to specify the thumbprint of the AD FS Token-signing certificate (you’ll find that easy in the AD FS Console under Service/Certificates).

    Ok, only one more thing to fiddle with in the web.config.

    <system.identityModel.services>
      <federationConfiguration>
        <cookieHandler requireSsl="true" />
        <wsFederation passiveRedirectEnabled="true"
          issuer="https://fs.contoso.com/adfs/ls/"  
          realm="uri:SharePoint:App:SAML" 
          requireHttps="true" />
      </federationConfiguration>
    </system.identityModel.services>

    Here there are two things we need to modify. First of all we need to point to the SAM/WS-Federation endpoint of AD FS, the login page, that Url is set in the issuer property of the wsFederation element. Secondly we must add the realm of our app – which should be the same as the audienceUri specified above. As I said earlier, I use a URI instead of the web application Url.

    A quick note here as well, notice that I use HTTPS and SSL all the way. For my SharePoint web application and for my app web application. If you prefer to be sloppy you can still use HTTP but that requires some extra work in SharePoint and the app web application config.

    Let’s take our High Trust App for a ride! Press F5 to get the app up and running. Doesn’t work…well some of it do. You should now be taken to the AD FS login page, but that one will just tell you an error occurred and the details doesn’t give much of a hint. You have to take a look in the AD FS server and the event log for AD FS. The error message is pretty clear on what we haven’t done yet:

    MSIS7007: The requested relying party trust 'uri:SharePoint:App:SAML' is unspecified or unsupported. 
    If a relying party trust was specified, it is possible that you do not have permission to 
    access the trust relying party. 
    Contact your administrator for details.
    

    Yes, we haven’t created our Relying Party Trust yet.

    Creating the Relying Party Trust in AD FS

    Claims rulesNow we need to create our Relying Part Trust in AD FS, it’s pretty straightforward, but comes with a couple of caveats. Add a new Relying Party Trust and choose to enter data manually, then give the trust a display name (I prefer to use the realm here). Continue by choosing to use the AD FS Profile, skip the certificate page in the wizard, and then select to enable support for the WS-Federation Passive protocol and enter the URL of your App. On the next page add a new identifier and now use the realm of your app, then just keep on clicking Next until you’re done. Once you’re done with creating the Relying Party Trust a new dialog will open up in AD FS in which you need to create Claims Rules for this new trust. This is a very important step, you need to get the rules correct and include the correct claims. In this case I will add two claims. One which augments the E-Mail claim from Active Directory (LDAP) for my Active Directory users and one which will just pass through the E-Mail claim from my third party Identity Provider (Thinktecture Identity Server). You have to pass either E-Mail, SIP address or UPN to get this to work. SharePoint needs at least one of those claims to be able to rehydrate the user from the User Profile Service Application.

    Once that is done, go back to your App and start it again using F5. Now logon using one of the Active Directory, use some other account than the one you are currently logged on to your machine as (otherwise you’ll think you are home safe already). You should see the default ASP.NET MVC SharePoint App page which says “Welcome Someone”, where Someone is the name of the logged in user. But what! That’s not the name of the account you logged in using? You can easy check that you are actually properly logged in using AD FS by setting a break point in the HomeController.cs in the Index action and take a look at some watches. You can clearly see that we are authenticated through federation and you’ll see the e-mail claim for that user who authenticated through AD FS, but the identity shown is the wrong one!

    Visual Studio Baby!

    Well, it turns out that the SharePointContext.cs and TokenHelper.cs classes that the Visual Studio and Office Dev team so kindly wrote for us only works with Windows Claims for High Trust apps. Bummer!

    Steve Peschka to the rescue!

    I barely gave up when I hit this, but my Bing-fu found a single blog post by Steve Peschka (who knew!) called “Using SharePoint Apps with SAML and FBA Sites in SharePoint 2013” who solved my problems, almost. This post of Steve was written some time ago when the TokenHelper.cs class looked very different and it forced you to make modifications to your app to support federated users. So I took his example code and modified it to fit the new helper classes provided by Visual Studio 2013 and made them in such way that you do not have to re-write your apps and packaged it into a single .cs file; SharePointContextSaml.cs. I will NOT post the entire thing here, since it is a lot of code. But if you’re like me you should read through it, it gives you tons of knowledge on how the app authorization actually works beneath the hood.

    So you just download the .cs extension file and add to your app web application project and then you have to do a couple of tweaks to your app configuration and to the default TokenHelper.cs and SharePointContext.cs files. This is how you do it.

    1) After you copied the SharePointContextSaml.cs file into your project, modify the namespace of that file to match the namespace of your project.

    2) Modify the default TokenHelper.cs class declaration so that the TokenHelper class is a partial class declaration, we need this to be able to extend the TokenHelper class. (This declaration should have been there by default imho!)

    public static partial class TokenHelper {...}

    3) In the SharePointContext.cs file locate the static constructor for the SharePointContextProvider class and modify it so it looks like below. This is needed so that we can use our custom context provider if the user is authenticated through federation.

    static SharePointContextProvider()
    {
        if (!TokenHelper.IsHighTrustApp())
        {
            SharePointContextProvider.current = new SharePointAcsContextProvider();
        }
        else
        {
            if(HttpContext.Current.User.Identity.AuthenticationType == "Federation") {
                SharePointContextProvider.current = new SharePointHighTrustSamlContextProvider();
            } else {
                SharePointContextProvider.current = new SharePointHighTrustContextProvider();
            }
        }
    }

    4) Finally we need to add three entries to the appSettings in web.config:

    <add key="spsaml:ClaimProviderType" value="SAML"/>
    <add key="spsaml:TrustedProviderName" value="High Trust SAML Demo"/>
    <add key="spsaml:IdentityClaimType" value="SMTP"/>

    The first entry is used to tell our custom context provider that we use SAML claims (there is support for Forms based authentication, value = FBA, in the extensions that Steve originally wrote but I have not yet tested it at all in my edition, and personally I prefer using something like IdentityServer instead of FBA). The second entry must be the name of the Trusted Security Token Issuer that you created using PowerShell for your app. And finally we need to specify what claim we will extract and use as identity claim; possible values are SMTP (e-mail), SIP or UPN.

    Yet another hobbit e-mailLet’s try to run the app once again. Most likely you will be able to logon but then you get an exception in the HomeController, an access denied. Then you need to check two things. First make sure that the user that you’re logging in with have permissions on your site. Since we’re talking about SAML claims here the people picker behaves a bit differently, enter the e-mail address of the user and make sure to choose the e-mail claim name (hover the mouse over the suggested options to see the claim type). Secondly you must make sure that the user has the WorkEmail attribute in the user profile store populated. This can be done either by using the User Profile Synchronization, if you’re authenticating with an Active Directory or LDAP source. But if you’re using some other IdP, for instance IdentityServer that I use here, you must add the WorkEmail manually through PowerShell or some other method. Once that is done you should see a nice and warm welcome to your SAML claims user!

    That’s it! All you need to do to enable SAML Claims user for your SharePoint 2013 High Trust App.

    Show me the codez!

    I’ve created a Github repository to host the SharePointContextSaml.cs file, you can find it here: https://github.com/wictorwilen/SharePointContextSaml

    I’d really like to get feedback in form of features, bugs, fixes etc. Please use the issue feature on Github, instead of e-mailing me…

    Currently it is not documented at all, there are some comments; a mix of mine and Steves original ones.

    I’d like to maintain it as long as possible, but my hope is that the Office Dev Team picks this up and do some proper testing and then merges this with the default Visual Studio helper files. Well, one can at least wish!

    Summary

    Yet another long blog post. I really hope I didn’t miss anything, there’s quite a few step once you do this the first time. I’ve shown you the complete example here; how to create and register a high trust SharePoint 2013 app, how to convert the default MVC project to a Claims based web application, registering a Trusted Relying Party in AD FS and then finally adding the new SharePointContextSaml.cs file and enabling you to use federated users in your Provider hosted app. Good luck to you all and thanks Steve for doing all the hard work!

  • SharePoint 2013 with SAML Claims and SharePoint Hosted Apps

    Tags: SharePoint 2013, AD FS, Claims, Windows Server 2012 R2, Apps

    Introduction

    By now each and every SharePoint developer out there should spend their time building SharePoint Apps instead of the old trusted friend of ours; Full Trust Code. Ok, Apps doesn’t solve the equivalent of world hunger in SharePoint at the moment, but that’s a discussion for another time. I assume you get my point. We have two types of apps (we used to have three little monkeys jumping in the bed, but one just bumped his head); Provider hosted apps and SharePoint hosted apps. Without going into details, Provider hosted apps are the apps that are hosted outside of SharePoint on a specific location (URL) and SharePoint hosted apps are running on top of SharePoint (using JavaScript) on a “random” location. This location is called the App Web and is a SharePoint SPWeb with a specific randomly generated URL. That URL could look something like this:

    https://app-2d4f884a19b8e8.apps.sp03-apps.com/sites/dev/SharePointApp1

    In that URL the first part is something that is randomly generated for each and every instance and deployment of that App. That is why we are required to use a Web Application listening on all incoming host headers, SAN wildcard certificates and users are also required to log in if we’re using Windows Authentication and the base App URL isn’t in the Local Intranet Zone.

    There is also another interesting issue specifically when we are using SAML Claims Authentication. Originally this did not work at all with SharePoint and specifically not with AD FS 2.0. One of the requirements of running SharePoint hosted apps with SAML claims is that the identity provider, IdP. (AD FS for instance) supports a wildcard return URL and that it uses the wreply parameter [Source]. Whenever you are trying to authenticate with the app you have to visit the IdP to get your claims and then be redirected back to the app, which is on a “random” URL. Using AD FS 2.0 you have to add a relying party trust for each and every app instance (something your IT people really enjoy doing).

    Fortunately all this is resolved in AD FS 3.0 that is shipped with Windows Server 2012 R2! Let’s take a look on how to set it up!

    Configure AD FS 3.0

    The first thing we need to do is to configure our AD FS 3.0 service. I assume you already have set up and installed AD FS 3.0 on a Windows Server 2012 R2 and that you have Claims authentication working for normal SharePoint sites. If you haven’t come this far yet please take a look at Steve Peschkas end-to-end guide for this, its for SharePoint 2010 and AD FS 2.0 but everything is almost the same.

    Here’s our scenario: We’re having one Web Application hosting both the Intranet (intranet.sp03.contoso.com) and the My Site host (mysite.sp03.contoso.com). We would like users with Windows Claims and SAML Claims with users from Active Directory and a third party to be able to use SharePoint Hosted Apps.

    The traditional way of setting it up in AD FS is to create two Relying Party Trusts; one for the Intranet and one for the My Site, like this:

    AD FS Relying Party Trusts

    Each Relying Party Trust has its unique realm. In this case urn:sharepoint:contoso:sp03:intranet and urn:sharepoint:contoso:sp03:mysite. And on our Trusted Identity Token Issuer in SharePoint we specify an additional Realm for the My Site, which could look similar to below:

    $tit = Get-SPTrustedIdentityTokenIssuer fs.contoso.com
    $tit.ProviderRealms.Add( (New-Object System.Uri("https://mysite.sp03.contoso.com")), 
      "urn:sharepoint:contoso:sp03:mysite")
    $tit.Update()

    It’s a pretty straightforward approach and works fine.

    But there is a much better way. Let’s get rid of this additional Relying Party Trust in AD FS and remove the additional Realm on the Trusted Identity Token Issuer. Well that doesn’t work! Now we get “An error has occurred” when trying to log in to the My Site. Fortunately it is very easy to fix.

    First head on over to AD FS and your (now single) Relying Party Trust and choose to edit its Properties. In the properties dialog choose the Endpoints tab and then choose to add a new endpoint by clicking on “Add WS-Federation”. As the Trusted URL type in your My Site host URL and add /_trust/ at the end. Once you click OK it should look something similar to this.

    Relying Party Trust Properties

    Finish it all by clicking OK. If you now try to log you will still see the same error, and if you take a look at the URL you’re being redirected back to you will see that you are redirected to the Intranet URL, which is the Default endpoint for the Relying Party Trust. So we have to do one more thing to get it to work, and this time on the SharePoint side. We need to tell SharePoint to use the WS-Fed wreply parameter.

    From the WS-Fed specification: wreply: This optional parameter is the URL to which responses are directed. Note that this serves roughly the same purpose as the WS-Addressing <wsa:ReplyTo> header for the WS-Trust SOAP RST messages

    Use the following PowerShell script to modify the Trusted Identity Token Issuer to use the wreply parameter:

    $tit = Get-SPTrustedIdentityTokenIssuer fs.contoso.com
    $tit.UseWReplyParameter = $true
    $tit.Update()

    Now! Let’s try to log in to the My Site once again using one of the providers we have configured in AD FS. If you have given the correct permissions to the user on the My Site host you will actually see it load and you’re golden.

    What about them Apps?

    Ok, I know I told you that this post was about getting SharePoint hosted apps to work with SAML Claims and I’ve only shown you how to log on to the My Site. Well, you see if you get this to work there is very little extra you have to do to get the SharePoint Hosted Apps to work. If I now was logged in as a SAML Claims user on the My Site and decided to install an app onto My Site (or any site for that matter), once I try to open the app I will get “An error has occurred on the server” and I will be redirected to the Intranet site.

    Just as we did get redirected to the Intranet site when not having the additional Endpoint on the Relying Party trust the same will happen with SharePoint Hosted Apps. The SharePoint Hosted Apps lives in these “random” App URLs and AD FS has no idea on how to and where to redirect the user after trying to authenticate on one of those. Now we have two options; add an endpoint for each and every single instance of our SharePoint Hosted Apps or…in AD FS 3.0 use a wildcard endpoint! Let’s try that!

    Just as we added the My Site endpoint to the Relying Party Trust let’s add our App Domain as en endpoint. The URL we need to add as a passive endpoint is formatted like this (of course you should use the app domain that you have configured in your SharePoint environment):
    https://*.apps.sp03-apps.com/_trust

    Notice that I use a * (star) as the wildcard character at the position where the randomly generated app id is used. It is required that you already have configured the Trusted Identity Token Issuer to use the wreply parameter like we did above, without that you will still get redirected to the default endpoint.

    Once done your Relying Party Trust should look like this:

    The App wildcard Endpoint

    If you now install and/or browse to a SharePoint Hosted App within your environment you will get prompted to authenticate and once that is done you should see your app. The picture below shows a user, stored in a third party IdP federated with AD FS, that has installed the default Visual Studio demo SharePoint Hosted App onto his My Site.

    Just another crappy app

    Note: Not a single iisreset was required to set this up! That doesn’t happen often!

    Summary

    In this post I have shown you how to configure AD FS 3.0 in Windows Server 2012 R2 to use a wildcard redirection endpoint to support Claims users to use SharePoint Hosted Apps in SharePoint 2013. A combination of new features in AD FS 3.0 and correct configuration in SharePoint 2013 was all that was needed.

  • Announcing Azure Commander

    Tags: Windows Azure, Windows Phone 8, Windows 8, Microsoft Azure

    For no one out there, in the SharePoint space or any other space, Microsoft Azure has gone unnoticed. Microsoft Azure is a really great service, or rather set of services, that for a (Microsoft or SharePoint) developer or IT-Pro is something that they should use and embrace. Personally I’ve been using Azure since the dawn of the service and I’ve been using it more and more. I use it to host web sites, host SharePoint and Office Apps, Virtual Machines, Access Control and a lots of other things.

    Specifically I’ve been lately using it for work more and more, and my customers and company are seeing huge benefits from using Microsoft Azure. We’re using it to host our development machines, demo environments, hosting full SharePoint production environments (staging, CI etc etc) and we’re using it to host SharePoint and Office Apps.

    All these services and instances and configurations must be managed somehow. For that we have the Azure portal (new and old version) and PowerShell. None of them are optimal in my opinion and I needed something more agile, something I could use when on the run, something to start, stop or reset my environments before a meeting, on my way home etc. This so I can optimize my resource/cost usage for the services and to save time.

    Introducing Azure Commander

    For all these purposes and reasons I have created a brand new Universal App for Windows 8.1 and Windows Phone 8.1 called – Azure Commander. Using Azure Commander I never forget to shut down a Virtual Machine since I can do it while commuting home, I can easily restart any of my web sites, when something hits the fan and more.

    Azure Commander are in its initial release focused on maintenance tasks for Virtual Machines (IAAS), Web/Worker Roles (PAAS) and Azure Web Sites. But you will see more features being added continuously! I personally like the option of easily firing up the app, choose a virtual machine and start an instant RDP session to it – from my laptop or Surface 2. For full features head on over to the Azure Commander web site.

    The interface on Windows 8.1

    AZ-Screen-W8-1.1.1.2

    The interface on Windows Phone 8.1

    AZ-Screen-WP8-1.1.1.2

    The App is since a couple of hours back available in both the Windows and Windows Phone store. You can get the app for only $3.99 – which is something you save in an instant when you use the app to remember turning of a virtual machine or web site or service over the weekend. A good thing is that this is an Universal Windows App – which means that if you buy them on either platform you will get it for free on the other one.

    Windows 8.1

    Download it from the Windows Store!

    Windows Phone 8.1

    Download it from the Windows Phone Store!

    Summary

    I hope you will enjoy the App as much as I do (both using it and building it). If you like it, please review it and follow Azure Commander on Twitter (@AzureCommander) or like it on Facebook.

  • Renewed as Microsoft Most Valuable Professional for the fifth time

    Tags: MVP, SharePoint

    April 1st 2014, for many a day full of jokes, but for 966 individuals this is the day they either is being awarded the Microsoft Most Valuable Professional (MVP) award or being renewed as MVPs. I’m fortunate to be one of those this time, and now for my fifth year!

    This award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others. We appreciate your outstanding contributions in SharePoint Server technical communities during the past year.

    image

    Thank you everyone for your support!

  • Workflow Manager Disaster Recovery – Preparations

    Tags: Workflow Manager, Series, Service Bus

    Introduction

    This is the first “real” posts in the Workflow Manager Disaster Recovery series. In this post I will show you what you need to do to prepare for Disaster Recovery (DR) situations when working with Workflow Manager and Service Bus.

    The obvious

    Let’s start with the obvious pieces. You should run your Workflow Manager farm on three (3) servers (for more on this discussion see the SPC356 session). Running on three servers are important not just for high-availability it might save you from going into DR mode. DR should be considered as the last resort. You should also consider one or more SQL Server high-availability options, more on this later.

    Data tier preparations

    WFM/SB default databasesThe Data tier in the Workflow Manager (WFM) /Service Bus (SB) is the actual SQL Server databases deployed when setting it up. It’s a minimum of six (6) databases – three for WFM and three for SB. These databases should of course be backed up – all DR options for Workflow Manager requires that you have a database backup/replica to restore from. Configure a “good” backup schema with full, differential and transaction log backups according to your SLA. You should also keep these backups in “sync” – that is don’t do SB backups on odd weeks and WFM backups even weeks for instance. They are normally not that large databases and the backup process should be pretty fast.

    Secondly you must think of the high-availability (HA) options for these databases. As I said previously, this can save you from going into DR mode. Most SQL HA options can be used with Workflow Manager and Service Bus, for instance:

    • Mirroring
    • Always On Availability Groups with sync commit

     

    If you need to shorten your DR time/RTO (Recovery Time Objective) then you should also not only rely on SQL backups but implement some replication technique with SQL to replicate data to a secondary location. The following techniques works great:

    • Log Shipping
    • Always On Availability Groups with async commit

     

    Compute tier preparations

    Once you are in control of the databases, backups and optionally replicas you could also consider weather you would like to have a cold or warm standby. A warm standby will shorten your RTO compared to a cold standby. A hot stand by Workflow Manager farm is NOT supported (a hot standby is a secondary running instance).

    • Cold standby – when a disaster occurs you create a brand new Workflow Manager/Service Bus farm using scripts and restore data from backups or replicated data.
    • Warm standby – a secondary farm configured but all the nodes (WFM and SB) are turned off. Use scripts to resume the nodes. Once the nodes are resumed you need to run the consistency verification cmdlet (Invoke-WFConsistencyVerifier, more on this later in the series).

     

    The Symmetric Key is the key

    In order to be successful or succeed at all you must keep track of the Symmetric key of the Service Bus. Without the Symmetric Key you cannot restore the Service Bus and you will loose all of your data. Keep it in a safe place!

    You can find the Symmetric Key by running the following PowerShell command:

    Get-SBNamespace -Name WorkflowDefaultNamespace

    image

    Summary

    You’ve just read the first post of this series and you’ve learnt the basics in how to prepare for, and possibly avoid, a Disaster Recovery situation for Workflow Manager and Service Bus. In the following posts we will discuss what do do if and when the disaster happens…

  • Workflow Manager Disaster Recovery and Restore options series

    Tags: Workflow Manager, Service Bus, Series, SharePoint 2013

    Introduction

    Welcome to a new series of blog posts in which we will focus on the Disaster and Recovery (DR) routines for Workflow Manager 1.0 in combination with SharePoint 2013. During SharePoint Conference 2013 me and SharePoint sensei Spencer Harbar presented a session called “Designing, deploying, and managing Workflow Manager farms” (watch the video recording). During that session we discussed different DR options for Workflow Manager and the Service Bus and we got tons of questions on that specific topic. We did not have time to go into details and we did not show any of the necessary scripts/routines you need to do when restoring a Workflow Farm or Workflow Scopes, and there is very little information available on that topic on the interwebs – so that is why this new blog series is being posted.

    Index of posts

    This blog post is just the introductory post and will be used as a place holder for all the posts in the series. Instead of writing one behemoth post I will split them into multiple ones and that will be a little bit easier for you to consume as well.

    These are the planned/written/unwritten posts and will be linked to when posted.

    • Workflow Manager Disaster Recovery – Index post (this post)
    • Workflow Manager Disaster Recovery – Preparations
    • Workflow Manager Disaster Recovery – Recover a single Scope
    • Workflow Manager Disaster Recovery – Recover a single database
    • Workflow Manager Disaster Recovery – Recover a single machine
    • Workflow Manager Disaster Recovery – Recover a full farm

     

    If you have any ideas on what more options to cover then feel free to post a comment below.

    Note:All examples in this series uses Windows Server 2012 R2, SharePoint 2013 Service Pack 1 and Workflow Manager 1.0 Refresh (+ Service Bus 1.1).

    Further reading

    For proper configuration of the Workflow Manager Farm see the following posts by Spencer Harbar:

  • Issue when installing Workflow Manager 1.0 Refresh using PowerShell

    Tags: Workflow Manager, SharePoint 2013

    Introduction

    When using the Web Platform Installer to download and/or install Workflow Manager you can no longer download and install Workflow Manager 1.0 and Workflow Manager 1.0 CU1. The only option is to download Workflow Manager 1.0 Refresh (which essentially is CU2). So when installing a new Workflow Manager farm for SharePoint or just because you want to rock some workflows you have to use Workflow Manager (WFM) 1.0 Refresh. Unless you’ve been smart and previously downloaded and saved the original Workflow Manager. When using WFM 1.0 Refresh you also need to download Service Bus 1.1.

    webpicmd.exe listing of available components

    Trouble in paradise!

    Installing the bits works like a charm and if you configure the Workflow Manager farm and the Service Bus using the wizard everything is golden. But if you’re a real professional then you of course use a scripted and repeatable approach and use PowerShell to build out your Workflow Manager farm.

    Most of the PowerShell commands and steps works as expected when creating the Service Bus farm, the Workflow Manager Farm, adding the first Service Bus host and creating the Service Bus namespace. But when you try to add a Workflow Host to the machine, using the Add-WFHost cmdlet, and when it tries to connect to the Service Bus namespace you get an error like this:

    Add-WFHost : Cannot validate argument on parameter 'SBClientConfiguration'.
    Could not load file or assembly
    'Microsoft.ServiceBus, Version=1.8.0.0, Culture=neutral, 
    PublicKeyToken=31bf3856ad364e35' or one of its dependencies.
    The system cannot find the file specified.

    If we crack up the Microsoft.Workflow.Deployment.Commands.dll using our favorite tool of choice of disassembly we can see that it actually references version 1.8.0.0 of Microsoft.ServiceBus.dll. Obviously a bug in this release!

    Solve the problem using basic .NET features

    The easiest way to work around it is of course to use the wizard, which works, but that is for slackers. So let’s instead use some basic .NET framework knowledge and make an assembly redirection. Assembly redirection is a way to redirect one version of an assembly to another, so that when the .NET framework tries to load version 1.8.0.0 we ask it to load version 2.1.0.0 (which is the Service Bus 1.1 version number). There is a couple of ways to do this;

    • We can update the machine.config file and make a machine wide redirection – I do not recommend this approach for obvious reasons
    • We can update the PowerShell.exe.config file and make the redirection for all PowerShell sessions – not a good approach either
    • Or we can dynamically load the configuration data in our PowerShell session – Heureka, that’s the way to do it!

    In order to do the assembly redirection we need to create a .config file which tells the .NET framework how to do the redirection. This is how the .config file should look like, and in this case I named it wfm.config. If you want do dig deeper into Assembly Redirection there is of course documentation on MSDN.

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.ServiceBus"
              publicKeyToken="31bf3856ad364e35"
              culture="en-us" />
            <bindingRedirect oldVersion="1.8.0.0" newVersion="2.1.0.0" />
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
    </configuration>

    To load this configuration into the current AppDomain we use the SetData() method of the current AppDomain and pass in the path to the file like this:

    $filename = Resolve-Path .\wfm.config
    [System.AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", $filename.Path)

    As you can see from above, we create a variable with the path to the .config file and then grab the current AppDomain and invoke the SetData() method with the APP_CONFIG_FILE key and the filename as value.

    Once you have created the file and executed those two lines of PowerShell you can use the Add-WFHost once again and continue your Workflow Manager configuration.

    Summary

    In this post you’ve seen a (major) issue with the Workflow Manager 1.0 Refresh, where you cannot add new Workflow Hosts to your Workflow Manager farm, due to an invalid assembly reference. Using “basic” .NET framework knowledge we can “fix” this issue by using assembly redirection. Hopefully someone from the WFM team will pick this up and make a refresh of the refresh.

  • SPC14: Scripts for Mastering Office Web Apps 2013 operations and deployments

    Tags: Office Web Apps, Presentations, WAC Server, Exchange 2013, SharePoint 2013

    Here’s another post with scripts from my sessions at SharePoint Conference 2014 – this time from the Mastering Office Web Apps 2013 Operations and Deployments session (SPC383). To get a more in-depth explanation of all the details, please watch the recording at Channel 9.

    Let’s start…but first! OWA = Outlook Web App and WAC = Office Web Apps (Web Application Companion).

    Preparing the machine before installing Office Web Apps

    Before you install the Office Web Apps bits on the machine you need to install a set of Windows Features. The following script is the one you should use (not the one on TechNet) and it works for Windows Server 2012 and Windows Server 2012 R2.

    # WAC 2013 preparation for Windows Server 2012 (R2)
    Import-Module ServerManager
    
    # Required Features
    Add-WindowsFeature NET-Framework-45-Core,NET-Framework-45-ASPNET,`
        Web-Mgmt-Console,Web-Common-Http,Web-Default-Doc,Web-Static-Content,`
        Web-Filtering,Web-Windows-Auth,Web-Net-Ext45,Web-Asp-Net45,Web-ISAPI-Ext,`
        Web-ISAPI-Filter,Web-Includes,InkAndHandwritingServices,NET-WCF-HTTP-Activation45
    
    # Recommended Features
    Add-WindowsFeature Web-Stat-Compression,Web-Dyn-Compression
    
    # NLB
    Add-WindowsFeature NLB, RSAT-NLB
    
    
    Note, that I also add the NLB features here – it is not required if you use another load balancer.

    Starting a sysprepped WAC machine

    The following script is used when booting up a sysprepped machine that has all the Office Web App binaries installed (including patches and language packs), but no WAC configuration whatsoever. It will simply configure a NIC on the box and then join the machine to a domain and rename the machine. A very simple script that can be automated. Most of the scripts, just as this one, contains a set of variables in the beginning of the script. This makes it much more easier to modify and work with the scripts.

    $domain = "corp.local"
    $newName = "WACSPC2"
    $ou = "ou=WAC,dc=corp,dc=local"
    
    $ethernet = "Ethernet1"
    $ip = "172.17.100.96" 
    $prefix = 24
    $dns = "172.17.100.1"
    
    # Set IP
    Write-Host -ForegroundColor Green "Configuring NIC..."
    New-NetIPAddress -InterfaceAlias $ethernet -IPAddress $ip -AddressFamily IPv4 -PrefixLength $prefix 
    Set-DnsClientServerAddress -InterfaceAlias $ethernet -ServerAddresses $dns
    
    # Verify 
    ping 172.17.100.1
    
    # Get creds
    $credentials = Get-Credential -Message "Enter credentials with add computer to domain privilegies"
    
    # Join domain
    Write-Host -ForegroundColor Green "Joining domain..."
    Add-Computer -Credential $credentials -DN $domain -OUPath $ou 
    
    # rename
    Write-Host -ForegroundColor Green "Renaming machine..."
    Rename-Computer -NewName $newName
    
    # Reboot
    Write-Host -ForegroundColor Green "Restarting..."
    Restart-Computer

    Once this script is executed the machine should reboot and be joined to a domain.

    Configure a new Office Web Apps Farm

    Once the machine is joined to the domain it is time to configure Office Web Apps. If you want more information about the variables/parameters I use I recommend watching the session! These variables are solely for demo purposes and you should adapt them to your needs. Also this step requires that you have a valid certificate (pfx file) that conforms to the WAC certificate requirements.

    # New WAC Farm
    Import-Module OfficeWebApps
    
    $farmou = "WAC"                           # Note the format!!
    $internalurl = "https://wacspc.corp.local"
    $externalurl = "https://wacspc.corp.com"
    $cachelocation = "c:\WACCache\"           # %programdata%\Microsoft\OfficeWebApps\Working\d\
    $loglocation = "c:\WACLog\"               # %programdata%\Microsoft\OfficeWebApps\Data\Logs\ULS\
    $rendercache = "c:\WACRenderCache\"       # %programdata%\Microsoft\OfficeWebApps\Working\waccache
    $size = 5                                 # Default 15GB
    $docinfosize = 1000                       # Default 5000
    $maxmem = 512                             # Default 1024
    $cert = "wacspc.corp.local.pfx"              # File name
    $certname = "wacspc.corp.local"              # Friendly name
    
    
    $certificate = Import-PfxCertificate -FilePath (Resolve-Path $cert) -CertStoreLocation  Cert:\LocalMachine\My -ea SilentlyContinue 
    $certificate.DnsNameList | ft Unicode
    
    
    New-OfficeWebAppsFarm -FarmOU $farmou `
        -InternalURL $internalurl `
        -ExternalURL $externalurl `
        -OpenFromUrlEnabled `
        -OpenFromUncEnabled `
        -ClipartEnabled `
        -CacheLocation $cachelocation `
        -LogLocation $loglocation `
        -RenderingLocalCacheLocation $rendercache `
        -CacheSizeInGB $size `
        -DocumentInfoCacheSize $docinfosize `
        -MaxMemoryCacheSizeInMB $maxmem `
        -CertificateName $certname `
        -EditingEnabled `
        -Confirm:$false
        
        
    (Invoke-WebRequest https://wacspc1.corp.local/m/met/participant.svc/jsonAnonymous/BroadcastPing).Headers["X-OfficeVersion"]
    
    

    As a last step I do a verification of the local machine and retrieve the current Office Web Apps version.

    Create the NLB cluster

    In my session I used NLB for load balancing. The following scripts creates the cluster and adds the machine as the first node to that cluster. The script will also install the DNS RSAT feature and add two DNS A records for the internal and external names for the Office Web Apps Server. That step is not required and might/should be managed by your DNS operations team.

    # Create NLB Cluster
    $ip = "172.17.100.97"
    $interface = "Ethernet1"
    
    # New NLB Cluster
    New-NlbCluster -ClusterPrimaryIP $ip -InterfaceName $interface -ClusterName "SPCWACCluster" -OperationMode Unicast -Verbose
    
    # DNS Bonus
    Add-WindowsFeature  RSAT-DNS-Server  
    Import-Module DnsServer
    Add-DnsServerResourceRecordA -Name "wacspc" -ZoneName "corp.local" -IPv4Address $ip -ComputerName ( Get-DnsClientServerAddress $interface  -AddressFamily IPv4).ServerAddresses[0]
    ping wacspc.corp.local
    Add-DnsServerResourceRecordA -Name "wacspc" -ZoneName "corp.com" -IPv4Address $ip -ComputerName ( Get-DnsClientServerAddress $interface  -AddressFamily IPv4).ServerAddresses[0]
    ping wacspc.corp.com

    Adding additional machines to the WAC farm

    Adding additional machines to the WAC farm is easy, just make sure you have the certificate (pfx file) and use the following scripts on the additional machines:

    Import-Module OfficeWebApps
    
    $server = "wacspc1.corp.local"
    $cert = "wacspc.corp.local.pfx"  
    
    Import-PfxCertificate -FilePath (Resolve-Path $cert) -CertStoreLocation  Cert:\LocalMachine\My -ea SilentlyContinue 
    
    New-OfficeWebAppsMachine -MachineToJoin $server
    
    # Verify
    (Get-OfficeWebAppsFarm).Machines

    Configuring NLB on the additional WAC machines

    And of course you need to configure NLB and add the new WAC machines into your NLB cluster:

    $hostname = "WACSPC1"
    $interface = "Ethernet1"
    
    Get-NlbCluster -HostName $hostname | Add-NlbClusterNode -NewNodeName $env:COMPUTERNAME -NewNodeInterface $interface

    That is all of the scripts I used in the session to set up my WAC farm. All that is left is to connect SharePoint to your Office Web Apps farm

    Configure SharePoint 2013

    In SharePoint 2013 you need to add WOPI bindings to the Office Web Apps farm. The following script will add all the WOPI bindings and also start a full crawl (required for the search previews):

    The first part (commented out in this script) should only be used if your SharePoint farm is running over HTTP (which it shouldn’t of course!).

    asnp microsoft.sharepoint.powershell -ea 0
    
    # SharePoint using HTTPS?
    #(Get-SPSecurityTokenServiceConfig).AllowOAuthOverHttp
    #$config = Get-SPSecurityTokenServiceConfig
    #$config.AllowOAuthOverHttp = $true
    #$config.Update()
    #(Get-SPSecurityTokenServiceConfig).AllowOAuthOverHttp
    
    # Create New Binding
    New-SPWOPIBinding -ServerName wacspc.corp.local
    Get-SPWOPIBinding | Out-GridView
    
    # Check the WOPI Zone
    Get-SPWOPIZone
    
    # Start full crawl
    $scope = Get-SPEnterpriseSearchServiceApplication | 
        Get-SPEnterpriseSearchCrawlContentSource | 
        ?{$_.Name -eq "Local SharePoint Sites"}
    
    $scope.StartFullCrawl()
    
    # Wait for the crawl to finish...
    while($scope.CrawlStatus -ne [Microsoft.Office.Server.Search.Administration.CrawlStatus]::Idle) {
        Write-Host -ForegroundColor Yellow "." -NoNewline
        Sleep 5
    }
    Write-Host -ForegroundColor Yellow "."

    Connect Exchange 2013 to Office Web Apps

    In the session I also demoed how to connect Office Web Apps and Exchange 2013. The important things here to remember is that you need to specify the full URL to the discovery end-point and that you need to restart the OWA web application pools.

    # WAC Discovery Endpoint
    Set-OrganizationalConfig -WACDiscoveryEndpoint https://wacspc.corp.local/hosting/discovery
    
    # Recycle OWA App Pool
    Restart-WebAppPool -Name MSExchangeOWAAppPool
    
    # (Opt) Security settings
    Set-OwaVirtualDirectory "owa (Default Web Site)" -WacViewingOnPublicComputersEnabled $true -WacViewingOnPrivateComputersEnabled $true

    Summary

    I know I kept all the instructions in this blog post short. You really should watch the recording to get the full picture. Good luck!

  • SPC14: Scripts for Real-world SharePoint Architecture decisions

    Tags: Conferences, SharePoint 2013

    As promised I will hand out all the scripts I used in my SharePoint Conference 2014 sessions. The first set of scripts are from the demo used in the Real-world SharePoint Architecture decisions session (SPC334). This session only contained one demo in which I showed how to set up a Single Content Web Application and using Host Named Site Collections when creating Site Collections.

    Creating the Web Application and the Root Site Collection

    The first part of the script was to create the Web Application using SSL, configure the certificate in IIS and then create the Root Site Collection. The Web Application is created using the –Url parameter pointing to a FQDN, instead of using the server name (which is used in the TechNet documentation, and causes a dependency on that specific first server). Secondly the script assumes that the correct certificate is installed on the machine and we grab that certificate using the friendly name (yes, always have a friendly name on your certificates, it will make everything much easier for you). A new binding is then created in IIS using the certificate. Finally the Root Site Collection is created (it is a support requirement) – the Root Site Collection uses the same URL as the Web Application and we should not specify any template or anything. This will be a site collection that no end-user should ever use.

    asnp *sh*
    
    # New Web Application 
    $wa = New-SPWebApplication `
        -Url 'https://root.spc.corp.local/' `
        -SecureSocketsLayer `
        -Port 443 `
        -ApplicationPool 'Content Applications' `
        -ApplicationPoolAccount 'CORP\spcontent' `
        -Name "SP2013SPC Hosting Web App " `
        -AuthenticationProvider (New-SPAuthenticationProvider) `
        -DatabaseName 'SP2013SPC_WSS_Content_Hosting_1' `
        -DatabaseServer 'SharePointSql'
    
    
    # Get Certificate
    $certificate = Get-ChildItem cert:\LocalMachine\MY | 
        Where-Object {$_.FriendlyName -eq "spc.corp.local"} | 
        Select-Object -First 1
    $certificate.DnsNameList | ft Unicode
    
    
    # Add IIS Binding
    Import-Module WebAdministration
    $binding = "IIS:\SslBindings\0.0.0.0!443"
    Get-Item $binding -ea 0 
    $certificate | New-Item $binding
    
    
    # Root site
    New-SPSite `
        -Url https://root.spc.corp.local `
        -OwnerAlias CORP\spinstall
    

    Creating Host Named Site Collections

    Secondly we created a Host Named Site Collection (HNSC) in our Web Application. For HNSC this can only be done in PowerShell, and not in Central Administration, and we MUST use the –HostHeaderWebApplication parameter and it MUST have the value of the Web Application URL.

    New-SPSite `
        -Url https://teams.spc.corp.local `
        -Template STS#0 `
        -OwnerAlias CORP\Administrator `
        -HostHeaderWebApplication https://root.spc.corp.local
    

     

    My Site host and Personal Sites

    If you would like to have Personal Sites and the My Site Host in the same Web Application (which in many cases are a good approach) then you must make sure to have Self Service Site Creation enabled on the Web Application and then use the following scripts. The script will first create a Farm level Managed Path for the Web Application by using the –HostHeader parameter. Then we just create the My Site Host as a Host Named Site Collection.

    # Personal Sites
    New-SPManagedPath `
        -RelativeUrl 'Personal' `
        -HostHeader
    
    # My Site Host
    New-SPSite `
        -Url https://my.spc.corp.local `
        -Template SPSMSITEHOST#0 `
        -OwnerAlias CORP\Administrator `
        -HostHeaderWebApplication https://root.spc.corp.local
    

     

    Configure search

    In the session I also explained why you should have a dedicated Content Source for People Search (watch the session for more info). And using the following script we add the correct start addresses to the two content sources, based on the Site Collections created above:

    # Configure Search
    $ssa = Get-SPEnterpriseSearchServiceApplication
    
    # The root web application
    $cs = Get-SPEnterpriseSearchCrawlContentSource -SearchApplication $ssa -Identity "Local SharePoint sites"
    $cs.StartAddresses.Add("https://root.spc.corp.local")
    $cs.Update()
    
    # People search
    $cs = Get-SPEnterpriseSearchCrawlContentSource -SearchApplication $ssa -Identity "Local People Results"
    $cs.StartAddresses.Add("sps3s://my.spc.corp.local")
    $cs.Update()

    Once this is done, you just kick off a full crawl of the People Search and then wait for a couple of hours (so the Analytics engine does its job) before you start the crawl of the content.

    Summary

    This was all the scripts I used during the demo in the SPC334 session. It’s a proven method and I hope you can incorporate them into your deployment scripts.

About Wictor...

Wictor Wilén is a Director and SharePoint Architect working at Connecta AB. Wictor has achieved the Microsoft Certified Architect (MCA) - SharePoint 2010, Microsoft Certified Solutions Master (MCSM) - SharePoint  and Microsoft Certified Master (MCM) - SharePoint 2010 certifications. He has also been awarded Microsoft Most Valuable Professional (MVP) for four consecutive years.

And a word from our sponsors...

SharePoint 2010 Web Parts in Action