Showing posts with label security. Show all posts
Showing posts with label security. Show all posts

Friday, July 11, 2014

PowerShell Script: Add a Trusted Security Token Issuer and Principal Permissions

Topic:Configuration
Level:Advanced
Intended Audience:Administrator, Architect, and IT Professional


If you read my recent post on how to use PowerShell to remove a Trusted Security Token Issuer and Principal Permissions, you will love this post in which I show you have to add a Trusted Security Token Issuer as well as a App Principal Permission.

Just save the following into a .PS1 file. You just need to provide the app display name, Issuer ID (or leave it blank for a random GUID), SSL certificate location, SharePoint site URL, the scope for which the app's principal should be registered (Site, SiteCollection, or SiteSubscription), and the permission that the application should have (Read, Write, Manage, or FullControl). Again, it is that easy.

if((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
{
    Add-PsSnapin Microsoft.SharePoint.PowerShell
}

# Stop if there is a problem with this cmdlet
$ErrorActionPreference = "Stop"

# Set our required variables
$appDisplayName = Read-Host "What is your app's display name?"
$issuerID = Read-Host "What is the Issuer ID? Leave blank to auto generate a GUID. Must be unique to the site.”
if ($issuerID -eq "") { $issuerID = [guid]::NewGuid() }
$publicCertPath = Read-Host "Please type in the .CER path location. For example, C:\mycertificate.cer"
$siteUrl = Read-Host "Please type in the SharePoint site URL. For example, https://sp2013.myspsite.com”
$site = Get-SPSite $siteUrl
$appScope = Read-Host "What scope should this application have access too? [Site] [SiteCollection] [SiteSubscription]"
$appPerm = Read-Host "What permission should this application have? [Read] [Write] [Manage] [FullControl]"

# Get our full application identifier
$web = Get-SPWeb $siteUrl
$certificate = Get-PfxCertificate $publicCertPath
$realm = Get-SPAuthenticationRealm -ServiceContext $web.Site
$fullAppIdentifier = $issuerId + '@' + $realm

# Add the trusted root authority, security token issuer, register the app principal, and set app permissions
New-SPTrustedRootAuthority -Name $appDisplayName -Certificate $certificate
New-SPTrustedSecurityTokenIssuer -Name $appDisplayName -Certificate $certificate -RegisteredIssuerName $fullAppIdentifier
Register-SPAppPrincipal -NameIdentifier $fullAppIdentifier -Site $web -DisplayName $appDisplayName
$appPrincipal = Get-SPAppPrincipal -NameIdentifier $fullAppIdentifier -Site $site.RootWeb
Set-SPAppPrincipalPermission -Site $site.RootWeb -AppPrincipal $appPrincipal -Scope $appScope -Right $appPerm

iisreset

Tuesday, June 3, 2014

My First SharePoint 2013 Timer Job - App Project

Topic:Programming
Level:Advanced
Intended Audience:Architect and Developer

Welcome back. This is part two of my series on creating a SharePoint 2013 Timer job. Specifically I am going to cover the high-trust provider-hosted app project inside of Visual Studio. And, how to configure this app to use a App Only policy. So this part of the series is a little more tailored towards the developer and not so much the admin / IT professional.

I will warn that these instructions are really meant for a Development or Test server type scenario. For Production there are several changes that I am hoping common sense would dictate you change. For example, you would not use a password of password in a Production environment. Nor would you store your .PFX on the local machine you are doing development on. Use your own discretion and work closely with your admins / IT professionals in a Production scenario.

So what is the difference between high, low, and full trust?


A high-trust app is a provider-hosted app that uses digital certificates to establish trust between the remote web application (your app server) and SharePoint (your SharePoint server). The high-trust app can take over the identity of any user without knowing the user's password. SharePoint will then allow the app to work on the behalf of that user. This does not imply that the app can take over an administrator's account and have access to everything they have. The app has a specific manifest file that dictates the permissions it has. And, the user has to be okay with this when the app is being instantiated inside of SharePoint. So it is not a full fledged take over of that user's account.

Now, a high-trust application is not the same as a full-trust solution. A high-trust app must still make app permission requests as I explained. The full-trust solution scenario has the same permissions as the SharePoint environment itself. Meaning that the solution is installed and ran on the SharePoint server itself like you used to do in SharePoint 2010 (e.g., good ole WSP packages). The high-trust app should be installed on it's own isolated server and not on the SharePoint server itself.

A low-trust app uses a trust broker, such as Microsoft Azure Access Control Services (ACS), to act as a token issurer between SharePoint and the application. Low-trust applications can not "impersonate" or do actions on the behalf of other users like a high-trust application can. The low-trust app uses it's own app identity when communicating with the server and when requesting a token. This makes low-trust a great option for Office 365. It should also be noted that this low-trust scenario utilizes OAuth.

What are app authorization policies?


SharePoint has three types of authorization policies. User-only, User and App, and App-only.

The user-only policy is the policy that was always applied in SharePoint 2010. This policy takes into account only the user identity. In example, when a user is accessing resources directly without using an app at all they are using the user-only policy for authorization checks.

The user and app policy takes into account both the user identity and the app identity. When authorization is occurring this policy checks to see if both the current user and the app have permission to perform the action being requested. This is useful when the app does not run on the SharePoint server and whats to act on the behalf of the user to get access to the user's specific resources.

The app-only policy only takes into account the app identity. When authorization occurs SharePoint checks to see if the app has permission to perform the action in question regardless of what access the current user or any user might have. In example, the person who installs the app has the rights that the app needs and gives permission for the app to perform those actions for users even though those users might not have permission themselves to directly act. I should note that certain APIs require user context. Thus, they can not be executed with an app-only policy alone. For example, there are many APIs for interacting with Project Server 2013 and for performing search that an app-only policy may not be the appropriate policy choice for your app.


Setting Up Your Solution in Visual Studio 2013

These next steps assume that you have successfully completed the steps found in my previous article of this series.

  1. Open Visual Studio 2013 and click on Start | New Project... or File | New | Project....
  2. Select the App for SharePoint option under the Office/SharePoint menu.

  3. You will be asked to specify a site that you want to use for debugging your app. This is a site collection that is using the Developer Site template. You can have your administrator do this by going through Central Administration | Application Management | Create site collections. If you have already done this point the wizard to that location. Also make sure that Provider-hosted is selected. Click Next.

  4. Specify the ASP.NET Web Forms Application as the type of project you want to create.

  5. On the Configure authentication settings screen you will select the Use a certificate (for SharePoint on-premises apps using high-trust) option. In the appropriate fields you will enter some of the settings set from the previous blog article:

    Certificate location: C:\Certs\HighTrustApps.pfx
    Password: password
    Issuer ID: You can open the .CER file in C:\Certs and use the Issued By name.

  6. Click Finish.

You have just created your first high-trust provider-hosted app! You will need to configure SharePoint 2013 to use the certificate and configure it to trust your app. Again, I warn that this instruction is really only for Development purposes. To package and publish high-trust apps for SharePoint 2013 in Production read this article instead.

Enter the following PowerShell commands:


$publicCertPath = "C:\Certs\HighTrustAppsCert.cer"

$certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($publicCertPath)

New-SPTrustedRootAuthority -Name "HighTrustAppsCert" -Certificate $certificate

$realm = Get-SPAuthenticationRealm

Next, you need to run this command. Your app will use an access token to get access to SharePoint data. This must be issued by a token issuer that SharePoint trusts. In this case, and for all high-trust apps, the certificate IS the token issuer. This command constructs an issuer ID in the format that SharePoint requires:

$specificIssuerId = "I used my Issued By name here"

$fullIssuerIdentifier = $specificIssuerId + '@' + $realm

In Production the $specificIssuerId must be a GUID because in Production each certificate must have a unique issuer. However, for development purposes you can hard code the value in like I have done.

Continue you along by entering the following:

New-SPTrustedSecurityTokenIssuer -Name "High Trust Apps Cert" -Certificate $certificate -RegisteredIssuerName $fullIssuerIdentifier -IsTrustBroker

The following commands are only ran in the Development scenario. If you do not run this you will get 403 Forbidden errors.

$serviceConfig = Get-SPSecurityTokenServiceConfig

$serviceConfig.AllowOAuthOverHttp = $true

$serviceConfig.Update()

You can save all of those commands into a file called HighTrustConfig-ForDebugOnly.ps1 and later run it again using the ./HighTrustConfig-ForDebugOnly.ps1 command inside the SharePoint Management Shell.

Test your application inside of Visual Studio by hitting your F5 key. If you are presented with the following messages...
































...just click Yes and continue.

You should then see a web page being hosted by localhost (Visual Studio in this case via virtual directory) that contains the name of your Developer Site.

Congratulations! You should see a blank screen with the title of the SharePoint site you are running this app against. If everything is successful, continue now with the instructions on making your app use an App Only policy.

The first step is adding the AllowAppOnlyPolicy to the app's manifest. In Visual Studio this is found under the App Project. You will see two files initially. An AppIcon.png and a AppManifest.xml. You want to open the code for the app's manifest.



















You will add the following code directly above the </app> closing tag.

<AppPermissionRequests AllowAppOnlyPolicy="true" >
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Read" >
        <Property Name="BaseTemplateId" Value="101" />
    </AppPermissionRequest>
</AppPermissionRequests>

Or you can do this through the GUI just by double-clicking on AppManifest.xml. Then go to the Permissions tab.











NOTE: The BaseTemplateId property you see listed in the example really applies to Lists. If the identifier is not set it means your app will have that permission level on all types of Lists. The 101 listed there means, for example, that the app only has Read to Document Libraries. You can view the full list by visiting http://msdn.microsoft.com/en-us/library/office/ms415091(v=office.15).aspx and looking at the Type attribute.

Last, but not least, how do you use the TokenHelper to utilize the S2S protocol? Open your TokenHelper.cs file in the AppWeb part of the Visual Studio project to look at some of the code there. Specifically take a look at the GetS2SAccessTokenWithWindowsIdentity and the GetClientContextWithAccessToken methods. In your application you would pass a null for the WindowsIdentity parameter to get back a valid OAuth access token

string appOnlyAccessToken = TokenHelper.GetS2SAccessTokenWithWindowsIdentity(_hostWeb, null);

You can then obtain the Client Side Object Model (CSOM) client context to perform actions on the behalf of the user.

using (ClientContext clientContext = 
    TokenHelper.GetClientContextWithAccessToken (_hostWeb.ToString(), appOnlyAccessToken))
{
    List list = clientContext.Web.Lists.GetByTitle("Announcements");
    ListItemCreationInformation info = new ListItemCreationInformation();
    Microsoft.SharePoint.Client.ListItem item = list.AddItem(info):
    item["Title"] = "Created via CSOM";
    item["Body"] = "Created via CSOM on " + DateTime.Now.ToLongTimeString();

    item.Update();
    clientContext.Load(item);
    clientContext.ExecuteQuery();
}

Then to test just deploy your app and log on as a user who only has read permissions to the list. Execute the code and a new item will be created using the application's permissions. If you had included a user identity instead of a null you would see a message stating "...by Application on behalf of User".

In my next article I will explain the process of creating a Windows Service solution that will be used to handle the timing / schedule part of our application.

Sources:
http://msdn.microsoft.com/en-us/library/office/dn268593(v=office.15).aspx

Tuesday, February 19, 2013

Building custom SharePoint 2010 Site Pages using Visual Studio (Part II)

Hello again. In my previous post I showed you how to create customized Site Pages using Visual Studio (VS) instead of being limited by SharePoint Designer (SPD). Now I am going to explain how to instruct SharePoint that it is alright to allow code-behind for these Site Pages. Which by default, is not allowed.

NOTE: You will absolutely want to configure your event handler to undo these changes when appropriate and to make these changes when appropriate. This way you can be sure that when the feature is activated / deactivated.... you get the drift. My recommendation would be to create a separate feature just for this security change. My previous feature was called CustomPages so I will name this one CustomPages Security.

  1. Add SafeControls
    • Click on your module (SitePages from my last post) and open your properties window.
    • Under the SafeControls section add a new SafeControl.
      • Assembly = $SharePoint.Project.AssemblyFullName$
      • Namespace = CustomPages
      • TypeName = MyCustomPageTemplate
      • Safe = true
      • SafeAgainstScript = false
  2. What happens to my web.config?
    • What is getting added to the web.config is the following:

      <SafeMode MaxControls="200"
                         
      CallStack
      ="false"
                         
      DirectFileDependencies
      ="10"
                         
      TotalFileDependencies
      ="50"
                         
      AllowPageLevelTrace="false">
          <PageParserPaths>
              <PageParserPath VirtualPath="/SitePages/MyCustomPage.aspx*"
                                          CompilationMode="Always"
                                          AllowServerSideScript="true"
                                          IncludeSubFolders="true" />
          </PageParserPaths>
      </SafeMode>
    • Create a new feature and add an event receiver to it. This feature's scope also needs to be WebApplication (you can check by double-clicking the feature to bring up designer view).
    • Add the following code and change as is appropriate for your needs. This is the sample and shouldn't be used as a straight copy / paste.

      using System;
      using System.Collections.ObjectModel;
      using System.Runtime.InteropServices;
      using System.Security.Permissions;
      using Microsoft.SharePoint;
      using Microsoft.SharePoint.Security;
      using Microsoft.SharePoint.Administration;

      namespace CustomPages.Features.CustomPages_Security
      {
          /// <summary>
          /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
          /// </summary>
          /// <remarks>
          /// The GUID attached to this class may be used during packaging and should not be modified.
          /// </remarks>

          [Guid("674c2a19-9913-4465-af57-198bd0416b49")]
          public class CustomPages_SecurityEventReceiver : SPFeatureReceiver
          {       
              public override void FeatureActivated(SPFeatureReceiverProperties properties)
              {
                  SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;

                  SPSecurity.RunWithElevatedPrivileges(delegate()
                  {
                      SPWebConfigModification wcMod = new SPWebConfigModification();

                      wcMod.Path = "configuration/SharePoint/SafeMode/PageParserPaths";
                      wcMod.Name = "PageParserPath[@VirtualPath='/SitePages/MyCustomPage.aspx']";
                      wcMod.Owner = "CustomPages";
                      wcMod.Sequence = 0;
                      wcMod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
                      wcMod.Value = "<PageParserPath VirtualPath='/SitePages/MyCustomPage.aspx' CompilationMode='Always' AllowServerSideScript='true' />";

                      webApp.WebConfigModifications.Add(wcMod);
                      webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
                      webApp.Update();
                  });

              }

              public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
              {
                  SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;

                  SPSecurity.RunWithElevatedPrivileges(delegate()
                  {
                      Collection<SPWebConfigModification> wcMods = webApp.WebConfigModifications;
                      int initialModificationsCount = wcMods .Count;

                      for (int i = initialModificationsCount - 1; i >= 0; i--)
                      {
                          if (wcMods [i].Owner == "CustomPages")
                          {
                              SPWebConfigModification modToRemove = wcMods[i];
                              wcMods.Remove(modToRemove);
                          }
                      }

                      if (initialModificationsCount > wcMods.Count)
                      {
                          webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
                          webApp.Update();
                      }

                  });
              }

          }
      }
There you have it. Not only do you have a customized Site Page from Visual Studio but, it also is allowed to use code-behind. I hope this helps you.

Tuesday, February 5, 2013

How to install a self-signed certificate as a Trusted Root CA

I'm sure there are other sources on the Internet for this task but, I wanted to provide what worked for me. Here are the basic instructions for installing a self-signed certificate into your trusted root Certification Authority (CA). These instructions were designed with Windows Vista or higher in mind. But, should suffice as a basic guideline for lower versions of Windows. Be absolutely sure you trust this certificate before doing this.

  1. When you get the security alert that "The identity of this web site or the integrity of this connection cannot be verified" you should see an option to View Certificate. Click on that.
  2. Next, click on Install Certificate....



  3. Under the Certificate Import Wizard choose the option "Place all certificates in the following store" and select browse.


  4. Select Trusted Root Certification Authorities and click OK.


  5. Select Local Computer (some cases you have to select Show Physical Stores here). Click OK.


  6. Click Finish on the Completing the Certificate Import Wizard screen.


  7. Click yes on the warning message to install the certificate.


  8. Done!
You shouldn't be pestered by the alerts any longer for the certificate that you just installed. Remember though that these are only valid for the domain you are installing on. You can follow the same instructions for other domains though if needed.

Tuesday, November 29, 2011

Making your Apache Web Server more secure

I just wanted to post a few tips that you can use on your Apache 2.2 web server to help make your server a little more secure.  This isn't a list of every security measure you can take but, just a few tips.

One of the first things you should do to secure your Apache installation is to configure Apache file permissions.  This will help mitigate access to primary systems if someone is able to hack into your server through Apache. You can do this by performing the following steps (there are a few, fair warning):
  1. After Apache Web server has been installed open the "Computer Management" console by doing the following:
    1. Click on "Start"
    2. Go to "Administrative Tools"
    3. Click on "Computer Management"
  2. In the "Computer Management" window, expand the "Local Users and Groups" section.  Click on "Users" to see a list of the current users for your system.
  3. Right-click on "Users" and select the "New User" option.
  4. Enter the following information for the new user:
    1. User name
      1. apacheservice
    2. Password
      1. adminpw123 <put something secure here>
    3. Confirm Password
      1. adminpw123 <reminder, change this to something secure>
    4. Clear the "User must change password" check box
    5. Select the "User cannot change password" check box
    6. Select the "Password never expires" check box
  5. Click the "Create" button and then click "Close" to close the "New User" dialog.
  6. Right-click the "apacheservice" user you just created and select "Properties". Click the "Member Of" tab.
  7. Make sure the "apacheservice" user is a "Member Of" the "Users" group.  Click "Cancel" to close the properties window.
  8. Exit out of the "Computer Management" console.
  9. Open the "Services" console by doing the following:
    1. Click on "Start"
    2. Go to "Administrative Tools"
    3. Click on "Services"
  10. Right-click the "Apache2" service and select "Stop".
  11. Open Windows Explorer (not Internet Explorer) and navigate to the following:
    1. C:\Program Files\Apache Software Foundation\Apache2.2
  12. Right-click the "Apache2.2" folder, select "Properties" and then select the "Security" tab.
  13. Make sure that only READ and EXECUTE permissions are granted to the Users group.
  14. No changes should be necessary so just click "Cancel".
  15. Using Windows Explorer, review the permissions for the following:
    1. C:\Program Files\Apache Software Foundation\Apache2.2\logs
  16. Now, we do want to change permissions on the "logs" directory.  To do that do the following:
    1. In the logs Properties dialog's Security tab, click the "Advanced" button.
    2. Clear the "Allow inheritable permissions from the parent" check box.
    3. Click "Remove" in the security window.
    4. Select the "Replace permissions on all child objects" check box and click the "Add" button.
    5. In the "Enter the object name to select" field, type the username "administrator" and click OK.
    6. Under "Allow", select the check box for "Full Control" and click OK.
    7. Click the "Add" button again and in the "Enter the object name to select" field, type the username "apacheservice" and click OK.
    8. Select the following check boxes under Allow:
      1. List Folder/Read Data
      2. Read Attributes
      3. Read Extended Attributes
      4. Create Files/Write Data
      5. Create Folder/Append Data
      6. Write Attributes
      7. Write Extended Attributes
      8. Read Permissions
    9. Click OK when done.
  17. Click OK to close the "Advanced Security Settings" window and again, click OK when asked to continue.
  18. If you check permissions for the "apacheservice" user in the logs Properties dialog's Security tab, you will find we should now have read / write access only.
  19. Click OK to exit out of the logs Properties window.
  20. Now view the security permissions of your web root.  By default, this is the "htdocs" folder found under your Apache2.2 installation.
  21. Click the "Advanced" button under the "Security" tab.
  22. In the "Advanced Security Settings" dialog, clear the "Allow inheritable permissions from the parent" check box.
  23. Click "Copy" in the security window.
  24. Click the OK button to dismiss the Advanced Security Settings.
  25. Select the "Users" group and click Remove.
  26. Select the "SYSTEM" group and click Remove.
  27. Click the Add button and in the "Enter the object name to select" field type the username "apacheservice" and click OK.
  28. In the "Permissions for apacheservice" section, change the permission to Allow Read and Deny Write. Clear any other check box that may be selected.
  29. Click OK to close "WebRootFolder Properties" and click Yes when asked to continue.
    1. Those last steps will ensure that the "apacheservice" user will only ever be able to read, never write, to the root Web document folder.
  30. Switch back to the Services console, or open it again by select Start -> Administrative Tools -> Services.
  31. Right-click the "Apache2" service and select "Properties".
  32. In the properties window, select the "Log On" tab and perform the following steps:
    1. Select the "This account" radio button and type the user name "apacheservice".
    2. Enter the password and confirm the password for the account.
    3. Click the "Apply" button.
      1. You should see a message indicating the account has been granted the "Log On As A Service" right.  This is fine, click OK to dismiss.
    4. Click OK to close the Apache2 properties window.
    5. Right-click the "Apache2" service in the Services console and select "Start".
      1. If you see an error when restarting Apache, then there is a problem with the permissions of the apacheservice user.  Verify your steps by checking permissions (see the instructions leading up to this step).
  33. The last step is simple... When the server comes back up just surf to the URL and ensure it is working.

Now, lets add a few tweaks to our server config file. In the "httpd.conf" file that is located in the "conf" directory of your server you can add the following:
#
# Controls who can get stuff from this server.
#
<Limit GET HEAD POST>
    order deny,allow
    allow from {%}
    deny from all
</Limit>
This configuration is added under your <Directory> for your document root. Replace the {%} token above with any IP address or IP block.  For example you can use the site County IP Blocks to generate a block of IP addresses only from a particular country (such as the USA).  Anyone coming from an IP address not in your block would be denied access.  Or you can do the following...
allow from 127.0.0.1
...to ensure only local access to the Web server.
#
# Limit to POST and GET commands only.
#
<LimitExcept POST GET>
    Require valid-user
</LimitExcept>
This should also be added under your <Directory> root. This configuration will prevent other un-secure commands from being accessed by a user.  POST and GET are really all you should be allowing on your Web server anyway.
#
# Hide server details from the HTTP response header
#
ServerSignature off
ServerTokens prod
This configuration (added at the end of your conf file) hides detailed server information from your HTTP response headers (such as Apache version) from potential attackers.  Attackers use information like that to coordinate attacks on your server.

And, of course you should always follow the security tips provided by Apache.  Those can be located here:

http://httpd.apache.org/docs/2.2/misc/security_tips.html

I hope some of these tips can help you to make sure your Web Server is more secure.  I will likely post more in the future and will also try to include application servers (Tomcat) and even IIS.