Sécurité

[SP2013] – Accéder aux données du Secure Store Service en C#

Posted on Updated on

Bonjour à tous,

Aujourd’hui un article technique pour vous montrer comment accéder aux données stockées dans le Secure Store Service de SharePoint Server 2013.

A quoi sert ce service ? Il suffit de suivre le lien : https://technet.microsoft.com/fr-fr/library/Ee806866.aspx

1/ Contexte général

Le but étant de stocker des données de type login, mot de passe, domaine, Pin, etc. afin d’accéder à des systèmes externe à SharePoint.

Habituellement, on utilise le Secure Store Service (SSS) de SharePoint pour enregistrer les credentials utilisés pour la mise en œuvre de listes externes dans SharePoint par le biais du Business Connectivity Service (BCS, ex-BDC). imaginons le cas où l’on souhaite afficher dans SharePoint une base de clients/fournisseurs qui provient d’une base de données SQL Server. Cette base peut utiliser un mode d’authentification SQL (et non Annuaire AD) et il faut donc envoyer un login/mot de passe pour pouvoir se connecter et requêter la base depuis SharePoint. C’est donc un SSO (Single Sign-On) mais Inter-Domaine (Cross-Domain) que nous propose Microsoft. Les données de cette base d’identifiants sont chiffrées via une clé générée par SharePoint lui-même (à partir d’une phrase secrète qu’il ne faut pas perdre !).

Dans le cas présent, le but est d’accéder à ce Secure Store Service afin de stocker, lire, mettre à jour les données d’un utilisateur, et proposer par exemple un formulaire de connexion, de mise à jour de ces données directement depuis un portail SharePoint.

2/ Architecture du service

Le Secure Store Service est une Application de Service proposée par SharePoint Server 2013 (Standard ou Enterprise). Elle peut se déployer par la console d’administration centrale ou PowerShell (voir l’article Technet précédent).

La clé de chiffrement permet de chiffrer les données stockées dans la base de données associée à l’application de service.

Les données sont stockées dans des Target Applications (Applications cibles). Chaque Target application stocke les données pour 1 application, par exemple :

  • Une Target Application pour la connexion à une base SQL Server
  • Une Target Application pour la connexion à une ferme Dynamics CRM
  • Une Target Application pour la connexion à SAP
  • Une Target Application pour la connexion à une base Oracle

Chacune de ces Target Application est définie par l’administrateur SharePoint où il doit fournir :

  1. ID de l’application cible : identifiant unique de la Target Application
  2. Nom complet : nom d’affichage de la Target Application
  3. Messagerie de contact : adresse e-mail de contact pour l’administrateur de cette Target Application
  4. Url de la page d’application cible : voir article Technet
  5. Type d’application cible : il s’agit ici d’indiquer si chaque utilisateur aura sa propre identification ou si l’on va définir une identification pour tout un groupe de personnes (individual ou group).

Ensuite vous devrez spécifier les champs que vous souhaitez enregistrer : champs d’identification Windows, champs d’identification standards (login/mot de passe), code Pin, domaine, etc.

Et enfin les administrateurs de la Target Application. Bref, tout cela est plutôt bien défini dans l’article Technet.

3/ Lire des credentials depuis mon code en C#

Voici enfin le cœur du problème. Comment accéder aux données stockées dans le SSS depuis mon code ?

J’ai tout d’abord défini une classe métier pour stocker quelques informations : Login, password, Login SharePoint, Nom Complet et E-mail de l’utilisateur :


namespace MonDev.LogMe.Utils
{
   public class SSSCredentials
   {
      public string Login { get; set; }
      public string Password { get; set; }
      public string SPLogin { get; set; }
      public string SPFullName { get; set; }
      public string SPEmail { get; set; }
   }
}

Ensuite, voici le code de la méthode GetCredentials que j’utilise. Les paramètres attendus sont :

  • site : collection de sites courante
  • applicationID : identifiant (interne) de la Target Application

   /// Get credentials for current connected user from Secure Store Service.
   /// current site collection, associated to a Secure Store Service at Web Application Level
   /// Target Application ID in Secure Store Service
   /// Returns Credentials if found, null otherwise.
   public static SSSCredentials GetCredentials(SPSite site, string applicationID)
   {
      //Initialize new Credentials structure
      SSSCredentials credentials = new SSSCredentials();
      credentials.SPEmail = site.RootWeb.CurrentUser.Email;
      credentials.SPFullName = !string.IsNullOrEmpty(site.RootWeb.CurrentUser.Name) ? site.RootWeb.CurrentUser.Name : site.RootWeb.CurrentUser.LoginName;
      credentials.SPLogin = site.RootWeb.CurrentUser.LoginName;

      //new SPSite is not mandatory, but it seems to be more efficient than use SPSite from parameters.
      using (SPSite currentSite = new SPSite(site.ID))
      {
         //Initialize a new SecureProvider to access to data into SSS
         ISecureStoreProvider provider = SecureStoreProviderFactory.Create();
         if (provider == null)
            throw new InvalidOperationException("Unable to get an ISecureStoreProvider");

         ISecureStoreServiceContext providerContext = provider as ISecureStoreServiceContext;
         providerContext.Context = SPServiceContext.GetContext(currentSite);

         try
         {
            using (SecureStoreCredentialCollection creds = provider.GetCredentials(applicationID))
            {
               if (creds != null)
               {
                  foreach (SecureStoreCredential cred in creds)
                  {
                     if (cred == null)
                        continue;

                     switch (cred.CredentialType)
                     {
                        case SecureStoreCredentialType.UserName:
                           credentials.Login = GetStringFromSecureString(cred.Credential);
                           break;
                        case SecureStoreCredentialType.Password:
                           credentials.Password = GetStringFromSecureString(cred.Credential);
                           break;
                        default:
                           break;
                     }
                  }
               }
            }
         }
         catch (SecureStoreException)
         {
            //No credentials are found into SSS, so return null
            return null;
         }
         catch (Exception e)
         {
            throw new Exception("A general error occured. Please contact your administrator. Error : " + e.Message);
         }
      }
      return credentials;
   }

La méthode doit être appelée comme suit :


private const string TargetApplicationID = "MaTargetApplication";
SSSCredentials credentials = SSSUtils.GetCredentials(SPContext.Current.Site, TargetApplicationID);

Rien de très compliqué toutefois je suis tombé sur quelques exemples de codes et aucun n’a fonctionné chez moi. A noter ici, pas besoin d’impersonation ou de SPSecurity.RunWithElevatedPrivileges(), bien au contraire. Il faut se connecter au provider avec les identifiants de l’utilisateur connecté au portail pour pouvoir récupérer ses identifiants !

 

4/ Ecrire dans le Secure Store Service

Si nous avons lu, il faut bien parvenir à écrire dans le SSS. Ici la méthode est la même pour l’ajout ou la modification de credentials dans le magasin du Secure Store Service. Les paramètres attendus sont :

  • site : collection de sites courante
  • applicationID : identifiant unique (interne) de la Target Application
  • windowslogin : login Windows ou identifiant de l’utilisateur dans le portail SharePoint
  • userName : nom d’utilisateur à stocker dans le Secure Store Service, dans la Target Application
  • userPassword : mot de passe à stocker dans le Secure Store Service, dans la Target Application

 


public static void SetCredentials(SPSite site, string applicationID, string windowslogin, string userName, string userPassword)
   {
      SPClaim claim = SPClaimProviderManager.CreateUserClaim(windowslogin, SPOriginalIssuerType.Windows);
      SecureStoreServiceClaim ssClaim = new SecureStoreServiceClaim(claim);

      SPServiceContext context = SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);

      SecureStoreServiceProxy ssp = new SecureStoreServiceProxy();
      ISecureStore iss = ssp.GetSecureStore(context);

      IList applicationFields = iss.GetUserApplicationFields(applicationID);

      IList creds = new List(applicationFields.Count);

      using (SecureStoreCredentialCollection credentials = new SecureStoreCredentialCollection(creds))
      {
         foreach (TargetApplicationField field in applicationFields)
         {
            switch (field.CredentialType)
            {
               case SecureStoreCredentialType.UserName:
                  creds.Add(new SecureStoreCredential(GetSecureStringFromString(userName), SecureStoreCredentialType.UserName));
                  break;
               case SecureStoreCredentialType.Password:
                  creds.Add(new SecureStoreCredential(GetSecureStringFromString(userPassword), SecureStoreCredentialType.Password));
                  break;
               default:
                  break;
            }
         }
         iss.SetCredentials(applicationID, credentials);
      }
   }

La méthode doit être appelée comme suit :


SSSUtils.SetCredentials(SPContext.Current.Site, TargetApplicationID, SPContext.Current.Site.RootWeb.CurrentUser.LoginName, "LOGIN_A_STOCKER", "PASSWORD_A_STOCKER");

A savoir, il est important d’exécuter le code avec le compte de l’utilisateur connecté à SharePoint afin de pouvoir lire ses credentials ou écrire/mettre à jour ses credentials. Lorsque j’essayais d’écrire le code pour faire ces manipulations, je suis tombé sur pas mal de bouts de code où ils essayaient d’exécuter cela avec le compte système via de l’impersonation ou bien SPSecurity.RunWithElevatedPrivileges(). Cela n’a pas marché pour moi !

5/ Fonctions annexes

Dans les extraits de codes précédents, j’ai utilisé quelques méthodes supplémentaire pour encoder/décoder les chaines de caractères envoyées ou reçues depuis le Secure Store Service. Pour être totalement complet, les voici.

Cette première méthode permet de décoder une chaine encodée (SecureString) dans une chaine standard (String)


internal static string GetStringFromSecureString(SecureString secStr)
{
   if (secStr == null)
      return null;

   IntPtr pPlainText = IntPtr.Zero;
   try
   {
      pPlainText = Marshal.SecureStringToBSTR(secStr);
      return Marshal.PtrToStringBSTR(pPlainText);
   }
   finally
   {
      if (pPlainText != IntPtr.Zero)
         Marshal.FreeBSTR(pPlainText);
   }
}

Et bien sûr la méthode effectuant la manipulation inverse :


internal static SecureString GetSecureStringFromString(string str)
{
   if (str == null)
      return null;
   var str2 = new SecureString();
   char[] chArray = str.ToCharArray();
   for (int i = 0; i < chArray.Length; i++)
   {
      str2.AppendChar(chArray[i]);
      chArray[i] = '0';
   }
   return str2;
}

6/ Usings…

J’ai un peu oublié d’en parler au début, mais certains peuvent avoir des difficultés pour inclure les bonnes références et using nécessaires au projet (je ne parlerai pas des assemblies standards…).

Références :

  1. Microsoft.BusinessData (à aller cherche dans) : C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.BusinessData.dll
  2. Microsoft.Office.SecureStoreService (à aller rechercher dans le GAC) : C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.Office.SecureStoreService\v4.0_15.0.0.0__71e9bce111e9429c\Microsoft.Office.SecureStoreService.dll
  3. Microsoft.Office.SecureStoreService.Server.Security (à aller cherche dans) : C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.Office.SecureStoreService.Server.Security.dll

Il ne nous reste plus qu’à trouver un usage à tout ceci ! 🙂

Florent.

[SharePoint 2010 – 2013] – Créer une Target Application sans le Secure Store Service en PowerShell

Posted on Updated on

 

Bonjour à tous,

Cela faisait un petit moment que je n’avais pas publié. Un petit post aujourd’hui pour vous montrer comment ajouter une TargetApplication dans le Secure Store Service de SharePoint. Allons-y !

 

1/ Secure… quoi ?

Le Secure Store Service, appelé Banque d’Informations Sécurisées en français), est une application de service de SharePoint 2010 et 2013 qui vous permet de stocker des couples d’identifiants login/password dans une base encryptée. Ces couples d’identifiants sont destinés à l’usage d’autres applications de services : Business Connectivity Service, PowerPivot, Excel Services, etc. afin qu’ils soient en capacité à se connecter à des sources de données par exemple, avec des identifiants différents de ceux de l’utilisateur connecté, du pool d’application, du compte administrateur.

Dans mon cas, il s’agit de stocker des identifiants afin qu’une application personnalisée puisse se connecter à un serveur Exchange 2010 via ses WebServices. Je ne voulais pas stocker ces informations dans SharePoint ou dans un fichier de configuration par exemple. L’avantage étant que ces paramètres sont cryptés et modifiables par l’administrateur de la ferme.

 

2/ Prérequis

En prérequis, il faut bien sûr déployer cette application de service qui sera disponible pour :

  • · SharePoint Server 2010 Standard
  • · SharePoint Server 2010 Enterprise
  • · SharePoint Server 2013 Standard
  • · SharePoint Server 2013 Enterprise

Point sur n’importe laquelle des versions Foundation ni SharePoint 2007 donc.

Pour déployer et configurer cette application de service, je vous invite à lire : http://technet.microsoft.com/fr-fr/library/ee806866(v=office.15).aspx

 

3/ Un peu de PowerShell

Cette démo sera réalisée avec SharePoint Server 2010 Enterprise.

Pour commencer, nous allons lancer le Management Shell de SharePoint (PowerShell avec les assemblies/cmdlets nécessaires à l’utilisation avec SharePoint). Pour cela, vous trouverez le raccourci dans Démarrer > Tous les Programmes > Microsoft SharePoint 2010 Products > SharePoint 2010 Management Shell

image

 

Nous allons commencer par renseigner quelques variables nécessaires :

  • $siteurl = ” http://sp2010-dev:82/sites/florent&#8221; ==> Url d’un site pour récupérer le ServiceContext (L’application de service Secure Store Service doit être associée à cette WebApplication !)
  • $ta_name = “ExchangeWS” ==> Nom de ma Target Application
  • $ta_friendlyName = “ExchangeWS for DEMO” ==> Nom “Friendly” de ma Target Application
  • $ta_contactEmail = “admin@sp2010.local” ==> Adresse e-mail de contact
  • $ta_owner = “DEMO\spadmin” ==> Propriétaire de la Target Application
  • $ta_userName = “DEMO\exchangeuser” ==> Login à stocker
  • $ta_password = “P@ssw0rd” ==> Password à stocker

image

Puis on créé la Target Application :

$target = New-SPSecureStoreTargetApplication -Name $ta_name -FriendlyName $ta_friendlyName -ContactEmail $ta_contactEmail -ApplicationType Group

clip_image002

Puis on créé les champs Login et password à stocker :

$usernameField = New-SPSecureStoreApplicationField -name “Exchange Username” -Type WindowsUserName -Masked:$false

$passwordField = New-SPSecureStoreApplicationField -name “Exchange Password” -Type WindowsPassword -Masked:$true

$fields = $usernameField,$passwordField

clip_image004

Puis nous allons créer 2 claims pour l’administrateur et pour le propriétaire :

$adminClaims = New-SPClaimsPrincipal -Identity $a_owner -IdentityType 1

$ownerClaims = New-SPClaimsPrincipal -Identity $a_owner -IdentityType 1

clip_image006

Puis créer la nouvelle Target Application :

New-SPSecureStoreApplication -ServiceContext $contextUrl -TargetApplication $ta -Fields $fields -Administrator $adminClaims -CredentialsOwnerGroup $ownerClaims

$ssa = Get-SPSecureStoreApplication -ServiceContext $contextUrl -Name $ta.Name

clip_image008

Puis on charge les identifiants :

$user = ConvertTo-SecureString $ta_userName -AsPlainText -Force

$password = ConvertTo-SecureString $ta_password -AsPlainText -Force

$credentials = $user,$password

Update-SPSecureStoreGroupCredentialMapping -Identity $ssa -Values $credentials

clip_image010

On peut verifier dans l’administration centrale, la Target Application est bien créée :

clip_image012

clip_image014

clip_image016

On voit ici que les Members (utilisateurs ayant accès à la Target Application) contiennent seulement SPADMIN. Pour ajouter des utilisateurs, on peut modifier les Owner Claims…

clip_image018

Par contre, impossible de valider graphiquement si le login/password est bien ajouté, la fenêtre ne charge pas les valeurs chargées (formulaire vide par défaut). Il faut donc tester… et chez moi ça marche 😉

A bientôt !

Florent.

[eBooks] – Collection d’ebooks gratuits

Posted on Updated on

Bonjour à tous.

 

Aujourd’hui, pas d’article technique mais une collection d’ebooks gratuits à télécharger (en anglais) de tous types :

  • Office & Office 365
  • SharePoint
  • SQL Server
  • System Center
  • Visual Studio
  • Web development
  • Windows
  • Windows Azure

Et en plusieurs formats pour la plupart : PDF, EPUB, MOBI. On ne va pas se priver !

Ca se passe par ici : http://blogs.msdn.com/b/mssmallbiz/archive/2013/06/18/huge-collection-of-free-microsoft-ebooks-for-you-including-office-office-365-sharepoint-sql-server-system-center-visual-studio-web-development-windows-windows-azure-and-windows-server.aspx

 

Bonne lecture !

[SharePoint 2013] – Configurer SSL pour SharePoint 2013

Posted on Updated on

 

Bonjour à tous.

Aujourd’hui un article pour vous montrer comment configurer SSL pour utiliser SharePoint 2013 avec des url https et sécuriser l’accès à vos contenus.

Je précise que dans mon cas, je vais utiliser un certificat de type “Self Signed” et donc à utiliser exclusivement pour des plateformes de développement. Pour les environnements de production, il faudra utiliser un certificat “commercial” acquis par exemple auprès de Verisign ou un autre organisme.

Dans ma configuration, j’ai un serveur d’annuaire (Windows Server 2008 avec le Rôle Active Directory) et mon serveur SharePoint (Windows Server 2008R2 SP1, SQL Server 2012 et SharePoint Server 2013 Enterprise).

Voici comment faire pour configurer les différents éléments :

 

1/ Créer un certificat Self Signed & l’exporter

 

Pour cela, nous allons utiliser une fonctionnalité de IIS (7 dans mon cas) permettant de générer des certificats auto-signés.

Nous allons commencer par lancer la console d’administration de IIS (sur le serveur SharePoint), soit en explorant le menu démarrer, soit en exécutant la commande “inetmgr”. Pennons le second cas : cliquer sur “Démarrer > Exécuter > inetmgr” :

image

Puis nous allons cliquer sur le nœud dans l’arborescence portant le nom du serveur SharePoint (SP2013-DEV dans mon cas), et enfin double-cliquer sur l’icône “Server Certificates” dans la zone centrale :

image

 

Sur cet écran, nous allons cliquer sur “Create Self-Signed Certificate…” :

image

 

Dans l’écran suivant, nous allons donner un nom à notre certificat, ici “SharePointCertificate” et cliquer sur OK :

image

Le certificat est maintenant créé. Nous allons maintenant l’exporter dans un fichier. Pour cela, on double-clique sur le nouveau certificat dans la zone centrale :

image

 

Nous allons cliquer sur l’onglet “Details” :

image

 

Et cliquer sur le bouton “Copy To File…” en bas :

image

L’écran d’accueil apparait. On clique sur “Next” :

image

 

Dans l’écran suivant, on conserve le paramètre “No, do not export the private key” et on clique sur “Next” :

image

Ici encore on conserve le paramètre par défaut “DER encoded binary X.509 (.CER)” et on clique sur “Next” :

image

Nous allons ensuite indiquer le chemin où sauvegarder le fichier généré. Dans mon cas je le place sur le Bureau, dans un répertoire nommé “SharePoint Certificate” et le fichier sera nommé “SharePointCertificate.cer”. On clique sur “Next” :

image

 

L’assistant nous affiche le récapitulatif. On clique sur “Finish” :

image

 

L’export est terminé :

image

 

2/ Importer le certificat dans le magasin

 

L’étape suivante consiste à importer le certificat tout juste exporté dans le magasin de certificats du serveur SharePoint.

Pour cela, nous allons lancer une nouvelle console pour les Snap-ins de Windows Server 2008R2 : “Démarrer > Exécuter”. Taper “mmc” et cliquer sur “OK” :

image

La console se lance. Dans “File”, sélectionner “Add/Remove Snap-in…” :

image

Dans la fenêtre apparaissant, sélectionner “Certificates”, et cliquer sur “Add >” :

image

Une fenêtre se lance, sélectionnez “Computer Account” et cliquer sur “Next” :

image

 

Dans l’écran suivant, conserver les paramètres et cliquer sur “Finish” :

image

 

Le Snap-in est bien ajouté, on clique sur “OK” :

image

 

On navigue ensuite dans l’arborescence : Certificates > SharePoint > Certificates :

image

On sélectionne le nœud “Certificates”, clic-droit > All Tasks > Import… :

image

L’assistant se lance, on clique sur “Next” :

image

 

On sélectionne le certificat exporté à l’étape précédente et on clique sur “Next” :

image

 

On conserve les paramètres (vérifier que l’on ait bien “SharePoint” dans le champ “Certificate Store”), “Next” :

image

 

On termine l’import “Finish” :

image

image

On peut maintenant fermer cette console.

 

 

3/ Ajouter le certificat dans l’administration centrale de SharePoint

 

NB : Dans le cas d’un serveur unique, cette étape n’est pas requise.

Nous allons maintenant charger le certificat dans la console d’administration centrale de SharePoint. SharePoint va principalement utiliser ce certificat afin de crypter et signer les échanges entre les serveurs de la ferme (sinon vous aurez des erreurs dans les logs SharePoint).

 

On lance donc le site dans le navigateur et on se rend sur la page : “Security > Manage Trust” :

image

 

Dans la page suivante, on retrouve le certificat utilisé nativement par SharePoint, nous allons ajouter notre certificat en cliquant sur “New” dans le ruban :

image

 

Nous allons ici renseigner le nom (dans mon cas j’ai choisi “SharePointCertificate”) et parcourir le disque local pour retrouver le certificat exporté dans la première étape :

image

On valide le formulaire et le certificat est ajouté :

image

Vous pouvez également automatiser cette configuration avec PowerShell (Management Shell pour SharePoint) :

  • $certificate = new-object system.security.cryptography.x509certificates.x509certificate2(“C:\\User\………\SharePointCertificate.cer”)
  • New-SPtrustedrootauthority –name “SharePointCertificate” –certificate $certificate

 

Etape suivante, configurer les bindings dans IIS

 

4/ Configurer les bindings dans IIS 7

 

Nous allons maintenant indiquer à IIS qu’il doit utiliser un binding https sur l’application Web SharePoint. J’ai bien sûr créé au préalable une Application Web sur le port 80 et une collection de sites.

Nous reprenons donc la console d’administration IIS (inetmgr) et on se rend sur l’application Web du port 80, et on clique sur “Bindings” dans la zone de droite :

image

La fenêtre des Bindings apparait, on clique sur “Add…” :

image

 

Nous allons ajouter un binding en https sur le port 443 (par défaut) et utilisant notre certificat. On clique sur “OK” :

image

Le nouveau binding est ajouté :

image

On ferme la fenêtre avec le bouton “Close”.

 

Dernière étape, configurer les Alternate Access Mapping (Mappage d’Accès de Substitution) dans l’administration centrale de SharePoint.

 

 

5/ Configurer les Alternate Access Mappings

 

Pour configurer ces AAM, on se rend dans la console d’administration centrale de SharePoint, sur la page d’accueil sur “Configure Alternate Access Mapping” :

image

La liste des AAM apparait. On utilise le contrôle permettant de sélectionner une Web Application sur la droite et on choisit celle sur le port 80 :

image

image

On clique ensuite sur “Add Internal Urls” et on ajoute notre url en https, sur la zone default (dans mon cas https://sp2013-dev) et on valide :

image

image

NB : Les deux urls : http et https cohabitent sur la même zone, cela nous permettra d’accéder en http au contenu depuis le réseau local (LAN) et en https depuis l’extérieur (WAN) moyennant d’avoir configurer le reverse proxy (ForeFront Threat Management Gateway, ISA, F5, etc.)… mais ça c’est une autre histoire !

Si vous n’avez qu’un mode d’accès souhaité (https pour tout le monde, vous pouvez ajouter l’url en https dans les Public Urls, sur la zone Extranet par exemple.

 

 

6/ Tests !

 

Nous allons maintenant tester notre configuration. Pour cela, j’utilise un navigateur en entrant l’adresse en https de ma collection de site : https://sp2013-dev :

image

Non ce n’est pas une erreur ! En effet, nous utilisons un certificat Self-Signed, et le navigateur ne fait pas l’approbation par défaut. On clique sur “Continue to this website…” dans le centre de la page :

image

Voila ça fonctionne !