Setup Details Post
Download the scripts referenced in this post via the attachment at the end.
-CERPath: A location to store the newly created self-signed certificate, in case it’s needed for other applications (e.g. AD FS). -PFXPath: A location for the new self-signed certificate together with its associated private key. -SPSTSCertName: The name to use for the subject and issuer name on the self-signed certificate. -RootAuthorityName: The name of the root authority to be provisioned to SharePoint. -CleanSTSSigningCerts: A switch parameter which, if specified, cleans old certificates with the same subject name from the local Certificates store. Useful if you are testing and creating a number of certificates and want to clean up after yourself. Be careful not to delete certificates that you still need.
SharePoint PowerShell Snapin New-SelfSignedCertificate and Grant-CertificateAccess (below). These are used to generate a self-signed certificate and grant access to its private key to the SharePoint farm account.
Creates a new self-signed certificate with subject and issuer name as specified by the SPSTSCertName parameter. This certificate is added to SharePoint as a trusted root authority, and then the signing certificate for SharePoint’s local STS is replaced by this certificate.
After replacing the local STS signing certificate, I’ve found it useful to restart the servers in the farm. Otherwise, you may encounter authentication problems while the various processes and services learn about the new certificate.
Replace-SPSTSSigningCertificate ` -SPSTSCertName 'CN=SharePoint Security Token Service, OU=SharePoint, O=Custom, C=US' ` -RootAuthorityName 'Self-Signed STS Signing Certificate' ` -CerPath 'C:\temp\SPSTS.cer' ` -PfxPath 'C:\temp\SPSTS.pfx' ` -CleanSTSSigningCerts ` -Verbose
-DN: The distinguished name to be used as both the subject and issuer of the self-signed certificate. -DaysValid: How many days the certificate should be valid for. Defaults to 365. -PfxPath: Where to store the PFX file associated with the certificate. PFX files contain both the certificate and the associated private key. Defaults to C:\temp\SelfSignedCert.pfx. -CerPath: Where to store the CER file associated with the certificate. CER files contain only the certificate, not the associated private key. Defaults to C:\temp\SelfSignedCert.cer.
Creates a new self-signed certificate with the specified Distinguished Name (DN). A copy of this certificate with a reference to its private key is stored in the LocalMachine\Personal store, and a PFX and CER file are stored at the designated paths.
-UserName: The Windows account (DOMAIN\username) which should be granted access to the private key of the certificate. -Thumbprint: The thumbprint of the certificate with private key for access.
Uses ICACLS.exe to set permissions on private key file.
-AADDomain: The fully-qualified domain name of the Azure Active Directory tenant. -SharePointWebUrl: The URL of the SharePoint web application to be associated with the SharePoint principal in Azure Active Directory. -O365Credentials: A PSCredential object to use for connecting to Azure Active Directory. If this isn’t specified, you’ll be prompted. -RemoveExistingACS: Clean up ACS proxies from the SharePoint farm. -RemoveExistingSTS: Clean up Trusted Security Token Service objects for ACS. -RemoveExistingAADCredentials: Clean up existing credentials associated with the SharePoint principal in AAD. Useful for keeping things tidy, but be careful not to delete credentials you need.
An existing Azure Active Directory tenant. MSOL PowerShell installed and configured. SharePoint PowerShell snapin.
The function starts out by declaring a few constants and gathering credentials. Metadata about the Azure Active Directory tenant is retrieved and used to associate the OnPrem SharePoint farm with the AAD realm. The Azure ACS service application proxy is configured, as well as a Trusted Security Token Service representing AAD. Next, a connection to AAD is made (using MSOL PowerShell) and the local STS signing certificate is associated with the well-known SharePoint principal. Finally, an SPN for the hostname of the URL specified in the SharePointWebUrl parameter is added to the list of known SPNs for the SharePoint principal.
Connect-SPFarmToAAD ` -AADDomain 'joshgav1.onmicrosoft.com' ` -SharePointWeb https://intranet.joshgav.com ` -RemoveExistingACS ` -RemoveExistingSTS ` -RemoveExistingAADCredentials
-DisplayName: A display name for the app principal in Azure AD. -RedirectUri: Endpoint URIs which tokens should be issued for. -HostUri: The hostname (including port number) of the endpoint. (This could be combined with RedirectUri eventually.) -ClientId: A GUID for the app principal’s ID. Autogenerated if not specified. -ClientSecret: A symmetric key secret for use with the client ID. Autogenerated if not specified. -O365Credentials: Credentials for the AAD tenant. -RemoveExistingWithSameDisplayName: Clean up existing service principals with the same display name. Careful not remove ones still in use.
An existing Azure Active Directory tenant. MSOL PowerShell installed and configured.
Begins with some setup: collect credentials to connect to AAD, create a client secret if one hasn’t been specified, and create an SPN to represent the location of the remote-hosted Web Application. Then the real work of connecting to AAD and creating a new service principal. The ClientSecret has to be associated with the service principal in several ways. Finally, the ClientID and ClientSecret that were used are output for further use.
Add-ServicePrincipalToAAD ` -DisplayName 'OnPremApp1' ` -RedirectUri 'https://localhost:44300' ` -HostUri 'localhost:44300' -O365Credentials $Credential ` -RemoveExistingWithSameDisplayName
-Web: A SharePoint web. This helps set the context for the operation; the app principal is available for use across the entire SharePoint tenancy. -ClientId: The client ID (a GUID) for this app principal. -ClientSecret: The Base64-encoded secret for this app principal. -DisplayName: Display name for the app principal. -HostUri: The hostname (including port) where the remote-hosted app is published. -RedirectUri: The HTTP/S endpoint where requests for apps associated with this app principal will be redirected.
SharePoint PowerShell snapin.
Using the specified parameters, creates an AppPrincipal in SharePoint to be associated with apps. Note the similarity between this function and the one for adding a service principal to AAD. Eventually, app principal registrations in SharePoint will automatically create a parallel registration in AAD. In the meantime, specify the same values for each function.
$AppPrincipal = Register-SPAppPrincipalEx ` -Web https://intranet.joshgav.com ` -ClientId $ClientInfo.ClientId ` -ClientSecret $ClientInfo.ClientSecret ` -HostUri 'localhost:44300' ` -RedirectUri 'https://localhost:44300' ` -DisplayName $ClientInfo.ClientDisplayName
-AppPrefix: The prefix placed before every AppWeb URL. -AppDomain: The domain which follows the AppWeb prefix. -ADDomain: The AD Domain in which the wildcard DNS entry for the AppDomain will be placed. -CanonicalName: The server to which the CNAME record for the wildcard DNS entry should point. -AddWildcardDNSEntry: Specify $false to not add the DNS entry. Defaults to true; use -AddWildcardDNDEntry:$false to specify false.
SharePoint PowerShell snapin
Sets up App Isolation for SharePoint.
Configure-SPFarmAppIsolation ` -AppPrefix 'apps' ` -AppDomain 'apps.intranet.joshgav.com' ` -ADDomain 'gavant.local' ` -CanonicalName 'intranet.joshgav.com' ` -AddWildcardDNSEntry
in New-SelfSignedCertificate DN should look like "CN=somename"
Sorry for the problem with the downloads - all scripts are now packaged up in the attached .zip file.
Let me know if you have problems and good luck!
Thanks for writing all this down, 1.5 years on this is still the only resource on the internet to seriously discuss registering app principals through PowerShell.
I've been attempting to port the code for 'Register-SPAppPrincipalEx' to the Client Object Model to facilitate Low Trust apps in SharePoint online. All the classes have a CSOM counterpart, so the coding part is not difficult. The only problem is getting the AppPrincipalManager (msdn.microsoft.com/.../microsoft.sharepoint.client.appprincipalmanager.getmanager.aspx).
When constructing this object, SharePoint performs the following two checks (visible when decompiling the SharePoint dll):
if (SPAppRequestContext.Current == null)
Of course there is no app request context present, the whole point of the scripting I'm trying to create is to register apps in new tenants, so there is no app yet to use the context from. As a result, an access denied error is thrown.
A lot of exposition, I know. The question I'm getting to is:
Do you now of a way to get an AppPrincipalManager from CSOM? Or even the reasoning behind restricting access to this part of the API requests performed from apps? Or who else to ask :)
Thanks for any kind of answer you can provide.