How to Use A Custom Authentication Provider For The SharePoint 2010 BCS Administration Object Model

The SharePoint 2010 Business Connectivity Services (BCS) are providing an Administration Object Model to manage all kind of BCS objects. You can use the an Administration Object Model to programmatically create BDC models, LOB system and instances, Entities and Methods. The Microsoft SharePoint Designer is using the object model itself to let you generate External Content Types (ECT).

The sample code is this blog entry is a WPF client application which will read all BDC model names and display them in a ListView control. The application allows the user to enter credentials other than the current Windows user:

The starting point to access the BCS data is the AdministrationMetadataCatalog class. This class is part of the Microsoft.SharePoint.BusinessData.Administration.Client.dll library and namespace. You also need a reference to the Microsoft.BusinessData.dll library.

In order to create an instance of the AdministrationMetadataCatalog class with custom credentials we have to call the GetCatalog method. We need to pass a custom authentication provider as parameter to GetCatalog. A custom authentication provider is a class which implements the ILobiAuthenticationProvider interface. The interface is quite simple, it just asks you to return the user ID (including the domain name) and the according password.

Here the code of your custom authentication provider:

1 internal class SharePointConnection : ILobiAuthenticationProvider
2 {
3 // . . .
4
5 public SharePointConnection(string userId, string password)
6 {
7 UserId = userId;
8 Password = password;
9 }
10
11 public AuthenticationScheme GetAuthenticationScheme(string server, string serverUrl)
12 {
13 return AuthenticationScheme.RunAs;
14 }
15
16 public string GetCookie(string server, string serverUrl)
17 {
18 return "BCSCustomAuthenticationProvider";
19 }
20
21 public string GetUserId(string server, string serverUrl)
22 {
23 return UserId;
24 }
25
26 public string GetPassword(string server, string serverUrl)
27 {
28 return Password;
29 }
30 }
Here the sample on how to use the provider:
1 // Create instance of custom authentication provider
2 SharePointConnection spc = new SharePointConnection(UserIdText.Text, PasswordText.Text);
3
4 // Create catalog instance using the custom authentication provider
5 AdministrationMetadataCatalog catalog = AdministrationMetadataCatalog.GetCatalog(SiteURLText.Text, spc);
6
7 ModelsListView.ItemsSource = catalog.GetModels("*").Select(m => m.Name);

Important: If you create your own WPF application using the BCS Administration Object Model and reference the Microsoft.SharePoint.BusinessData.Administration.Client.dll library, you need to set the Platform Target to "Any CPU" in the application settings page, otherwise the project will not compile.

Download Source-Code



Integrate SAP Business Data Into SharePoint 2010 Using Business Connectivity Services and LINQ to SAP

  • Download demo - 13.56 KB
  • Introduction

    One of the core concepts of Business Connectivity Services (BCS) for SharePoint 2010 are the external content types. They are reusable metadata descriptions of connectivity information and behaviours (stereotyped operations) applied to external data. SharePoint offers developers several ways to create external content types and integrate them into the platform. The SharePoint Designer 2010, for instance, allows you to create and manage external content types that are stored in supported external systems. Such an external system could be SQL Server, WCF Data Service, or a .NET Assembly Connector.

    This article shows you how to create an external content type for SharePoint named Customer based on given SAP customer data. The definition of the content type will be provided as a .NET assembly, and the data are displayed in an external list in SharePoint.

    The SAP customer data are retrieved from the function module SD_RFC_CUSTOMER_GET. In general, function modules in a SAP R/3 system are comparable with public and static C# class methods, and can be accessed from outside of SAP via RFC (Remote Function Call). Fortunately, we do not need to program RFC calls manually. We will use the very handy ERPConnect library from Theobald Software. The library includes a LINQ to SAP provider and designer that makes our lives easier.

    .NET Assembly Connector for SAP

    The first step in providing a custom connector for SAP is to create a SharePoint project with the SharePoint 2010 Developer Tools for Visual Studio 2010. Those tools are part of Visual Studio 2010. We will use the Business Data Connectivity Model project template to create our project:

    After defining the Visual Studio solution name and clicking the OK button, the project wizard will ask what kind of SharePoint 2010 solution you want to create. The solution must be deployed as a farm solution, not as a sandboxed solution. Visual Studio is now creating a new SharePoint project with a default BDC model (BdcModel1). You can also create an empty SharePoint project and add a Business Data Connectivity Model project item manually afterwards. This will also generate a new node to the Visual Studio Solution Explorer called BdcModel1. The node contains a couple of project files: The BDC model file (file extension bdcm), and the Entity1.cs and EntityService.cs class files.

    Next, we add a LINQ to SAP file to handle the SAP data access logic by selecting the LINQ to ERP item from the Add New Item dialog in Visual Studio. This will add a file called LINQtoERP1.erp to our project. The LINQ to SAP provider is internally called LINQ to ERP. Double click LINQtoERP1.erp to open the designer. Now, drag the Function object from the designer toolbox onto the design surface. This will open the SAP connection dialog since no connection data has been defined so far:

    Enter the SAP connection data and your credentials. Click the Test Connection button to test the connectivity. If you could successfully connect to your SAP system, click the OK button to open the function module search dialog. Now search for SD_RFC_CUSTOMER_GET, then select the found item, and click OK to open the RFC Function Module /BAPI dialog:

    BCS12.png

    The dialog provides you the option to define the method name and parameters you want to use in your SAP context class. The context class is automatically generated by the LINQ to SAP designer including all SAP objects defined. Those objects are either C# (or VB.NET) class methods and/or additional object classes used by the methods.

    For our project, we need to select the export parameters KUNNR and NAME1 by clicking the checkboxes in the Pass column. These two parameters become our input parameters in the generated context class method named SD_RFC_CUSTOMER_GET. We also need to return the customer list for the given input selection. Therefore, we select the table parameter CUSTOMER_T on the Tables tab and change the structure name to Customer. Then, click the OK button on the dialog, and the new objects get added to the designer surface.

    IMPORTANT: The flag "Create Objects Outside Of Context Class" must be set to TRUE in the property editor of the LINQ designer, otherwise LINQ to SAP generates the Customer class as nested class of the SAP context class. This feature and flag is only available in LINQ to SAP for Visual Studio 2010.

    The LINQ designer has also automatically generated a class called Customer within the LINQtoERP1.Designer.cs file. This class will become our BDC model entity or external content type. But first, we need to adjust and rename our BDC model that was created by default from Visual Studio. Currently, the BDC model looks like this:

    Rename the BdcModel1 node and file into CustomerModel. Since we already have an entity class (Customer), delete the file Entity1.cs and rename the EntityService.cs file to CustomerService.cs. Next, open the CustomerModel file and rename the designer object Entity1. Then, change the entity identifier name from Identifier1 to KUNNR. You can also use the BDC Explorer for renaming. The final adjustment result should look as follows:

    BCS4.png

    The last step we need to do in our Visual Studio project is to change the code in the CustomerService class. The BDC model methods ReadItem and ReadList must be implemented using the automatically generated LINQ to SAP code. First of all, take a look at the code:

    BCS6.png

    As you can see, we basically have just a few lines of code. All of the SAP data access logic is encapsulated within the SAP context class (see the LINQtoERP1.Designer.cs file). The CustomerService class just implements a static constructor to set the ERPConnect license key and to initialize the static variable _sc with the SAP credentials as well as the two BDC model methods.

    The ReadItem method, BCS stereotyped operation SpecificFinder, is called by BCS to fetch a specific item defined by the identifier KUNNR. In this case, we just call the SD_RFC_CUSTOMER_GET context method with the passed identifier (variable id) and return the first customer object we get from SAP.

    The ReadList method, BCS stereotyped operation Finder, is called by BCS to return all entities. In this case, we just return all customer objects the SD_RFC_CUSTOMER_GET context method returns. The returned result is already of type IEnumerable<Customer>.

    The final step is to deploy the SharePoint solution. Right-click on the project node in Visual Studio Solution Explorer and select Deploy. This will install and deploy the SharePoint solution on the server. You can also debug your code by just setting a breakpoint in the CustomerService class and executing the project with F5.

    That's all we have to do!

    Now, start the SharePoint Central Administration panel and follow the link "Manage Service Applications", or navigate directly to the URL http://<SERVERNAME>/_admin/ServiceApplications.aspx. Click on Business Data Connectivity Service to show all the available external content types:

    On this page, we find our deployed BDC model including the Customer entity. You can click on the name to retrieve more details about the entity. Right now, there is just one issue open. We need to set permissions!

    Mark the checkbox for our entity and click on Set Object Permissions in the Ribbon menu bar. Now, define the permissions for the users you want to allow to access the entity, and click the OK button. In the screen shown above, the user administrator has all the permissions possible.

    In the next and final step, we will create an external list based on our entity. To do this, we open SharePoint Designer 2010 and connect us with the SharePoint website.

    Click on External Content Types in the Site Objects panel to display all the content types (see above). Double click on the Customer entity to open the details. The SharePoint Designer is reading all the information available by BCS.

    In order to create an external list for our entity, click on Create Lists & Form on the Ribbon menu bar (see screenshot below) and enter CustomerList as the name for the external list.

    OK, now we are done!

    Open the list, and you should get the following result:

    The external list shows all the defined fields for our entity, even though our Customer class, automatically generated by the LINQ to SAP, has more than those four fields. This means you can only display a subset of the information for your entity.

    Another option is to just select those fields required within the LINQ to SAP designer. With the LINQ designer, you can access not just the SAP function modules. You can integrate other SAP objects, like tables, BW cubes, SAP Query, or IDOCs. A demo version of the ERPConnect library can be downloaded from the Theobald Software homepage.

    If you click the associated link of one of the customer numbers in the column KUNNR (see screenshot above), SharePoint will open the details view:

    BCS10.png

    Summary

    This article has shown how easy and simple it is to integrate business data from SAP into the SharePoint platform using standard tools. Combing the powerful Microsoft Visual Studio 2010 with its SharePoint development tools and the handy LINQ to SAP provider tool from Theobald Software, and you just need to write a couple of code lines to stick together all the logic we need to create an external list in SharePoint 2010 and BCS.



    Use SharePoint 2010 Secure Store As Single Sign-On Service For SAP Applications Using ERPConnect

    The Secure Store Service in SharePoint 2010 replaces the Single Sign-on Shared Service of MOSS 2007 and provides an easy way to map user credentials of external resources like SAP systems to Windows users. During the process of developing SAP interfaces using the very handy ERPConnect library from Theobald Software you have to open a R3 connection with the SAP system using SAP account credentials (username and password).

    In most cases you will use a so called technical user with limited access rights to execute or query objects in SAP, but a SAP system saves a lot of sensitive data which cannot all be shown to all users. So, creating a new secure store in SharePoint 2010 to save the SAP user credentials will be the solution. Accessing the secure store from program code is quite simple.

    A trail version of the ERPConnect library can be downloaded at www.theobald-software.com.

    Secure Store Configuration

    The Secure Store Service will be managed by the Central Administration (CA) of SharePoint 2010 under Application Management > Manage service applications > Secure Store Service:

    Screenshot1_thumb3

    As the screenshot above shows is it possible to create multiple target applications within one Secure Store Service.

    Clicking the New button will open the Create New Secure Store Target Application page. In this dialog you have to enter the new Target Application ID, a display name, a contact email address and other application related details (see screenshot below).

    Screenshot2_thumb1

    Next, the application fields must be defined:

    Screenshot3_thumb1

    It's important to select the field type User Name and Password, because our implementation later on will check the target application for those two field types.

    In the last dialog step the application administrator must be defined. After defining the administrator and clicking the Ok button SharePoint is creating a new secure store:

    Screenshot5_thumb1

    Next, the Windows users must be mapped to the SAP user credentails. Therefore mark the checkbox for the newly created secure store SAPCredentialsStore and click the Set button in the toolbar. This opens the following dialog:

    Screenshot6_thumb1

    The Credential Owner is the Windows user for whom the SAP user credentials will be set. Enter the SAP username and password and click the Ok button to save them.

    That's it !

    Secure Store Programming

    Accessing the secure store by code is simple. We implement a SecureStore class which will encapsulate all the access logic. A second class called SecureStoreCredentials contains the retrieved user credentials returned by the method GetCurrentCredentials of the SecureStore class.

    But first, we need to create a Visual Studio 2010 SharePoint project and reference a couple of assemblies. You can directly enter the file paths in the Reference dialog (Browse tab) to add the assemblies:

    Microsoft.BusinessData.dll
    C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.BusinessData.dll

    Microsoft.Office.SecureStoreService.dll
    C:\Windows\assembly\GAC_MSIL\Microsoft.Office.SecureStoreService\14.0.0.0__71e9bce111e9429c\Microsoft.Office.SecureStoreService.dll

    The following code shows the SecureStore class implementation:

    internal class SecureStore {   public string ApplicationId { get; private set; }    public SecureStore(string applicationId)   {     if(string.IsNullOrEmpty(applicationId))       throw new ArgumentNullException("applicationId");     if(!IsApplicationValid(applicationId))       throw new ArgumentException(string.Format("Target application with ID '{0}' is not defined.", applicationId));      ApplicationId = applicationId;   }    public SecureStoreCredentials GetCurrentCredentials()   {     SecureStoreProvider provider = new SecureStoreProvider { Context = SPServiceContext.Current };     string userName = string.Empty;     string password = string.Empty;      using(SecureStoreCredentialCollection data = provider.GetCredentials(ApplicationId))     {       foreach(ISecureStoreCredential c in data)       {         if(c != null)         {           if(c.CredentialType == SecureStoreCredentialType.UserName)             userName = GetDecryptedCredentialString(c.Credential);           else if(c.CredentialType == SecureStoreCredentialType.Password)             password = GetDecryptedCredentialString(c.Credential);         }       }     }      if(string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))       throw new SecureStoreException("Credentials for the current Windows user are not valid or not defined.");      return new SecureStoreCredentials(userName, password);   }    public static bool IsApplicationValid(string applicationId)   {     if(string.IsNullOrEmpty(applicationId))       throw new ArgumentNullException("applicationId");      SecureStoreProvider provider = new SecureStoreProvider { Context = SPServiceContext.Current };      foreach(TargetApplication application in provider.GetTargetApplications())     {       if(application.ApplicationId == applicationId)       {         ReadOnlyCollection<ITargetApplicationField> fields = provider.GetTargetApplicationFields(applicationId);         bool existsUserNameDefinition = false;         bool existsPasswordDefinition = false;          foreach(TargetApplicationField field in fields)         {           if(field.CredentialType == SecureStoreCredentialType.UserName)             existsUserNameDefinition = true;           else if(field.CredentialType == SecureStoreCredentialType.Password)             existsPasswordDefinition = true;         }          if(existsUserNameDefinition && existsPasswordDefinition)           return true;       }     }      return false;   }    public static string GetDecryptedCredentialString(SecureString secureString)   {     IntPtr p = Marshal.SecureStringToBSTR(secureString);      try     {       return Marshal.PtrToStringUni(p);     }     finally     {       if(p != IntPtr.Zero)         Marshal.FreeBSTR(p);     }   } }

    The constructor checks if an application ID is passed and if it's valid by calling the static method IsApplicationValid. In first place, the IsApplicationValid method is creating an instance of the SecureStoreProvider class to get access to Secure Store Service. The SecureStoreProvider class provides all methods to talk to the SharePoint service. Then, the method queries for all target applications and checks for the given application. If the application has been created and can be found, the method will analyse the application field definitions. The IsApplicationValid method then looks for two fields of type User Name and Password (see above).

    The GetCurrentCredentials method is actually trying to get the SAP user credentials from the store. The method is creating an instance of the SecureStoreProvider class to get access to service and then calls the GetCredentials method of the provider class. If credentials are available the method decrypt the username and password from type SecureString using the internal method GetDecryptedCredentialString. It then will wrap and return the data into an instance of the SecureStoreCredentails class.

    For more details of the implementation see the source code.

    Accessing SAP Using The Secure Store Credentials

    The sample and test code calls the SAP function module SD_RFC_CUSTOMER_GET to retrieve all customer data that match certain criteria (where NAME1 starts with Te*):

    Screenshot7_thumb1

    The following code shows the implementation of the Test button click event:

    protected void OnTestButtonClick(object sender, EventArgs e) {   string licenseKey = "<LICENSEKEY>";   string connectionStringFormat = "CLIENT=800 LANG=EN USER={0} PASSWD={1} ASHOST=HAMLET ...";    R3Connection connection = null;    try   {     LIC.SetLic(licenseKey);      ...      SecureStoreCredentials credentials =       new SecureStore(ApplicationID.Text).GetCurrentCredentials();     string connectionstring =       string.Format(connectionStringFormat, credentials.UserName, credentials.Password);      connection = new R3Connection(connectionstring);     connection.Open();      RFCFunction function = connection.CreateFunction("SD_RFC_CUSTOMER_GET");     function.Exports["NAME1"].ParamValue = "Te*";     function.Execute();      ResultGrid.DataSource = function.Tables["CUSTOMER_T"].ToADOTable();     ResultGrid.DataBind();      OutputLabel.Text = string.Format("The test called...",       ApplicationID.Text, Web.CurrentUser.Name, Web.CurrentUser.LoginName,       credentials.UserName);   }   catch(Exception ex)   {     WriteErrorMessage(ex.Message);   }   finally   {     if(connection != null && connection.Ping())       connection.Close();   } }

    The interesting part is the retrieval of the SAP user credentials from the secure store defined in the text box named ApplicationID. The application ID will be passed as parameter to the constructor of the SecureStore class. After creating the instance the method GetCurrentCredentials will be called to ask the store for the credentials of the current Windows user.

    After the user credential query has been successfully executed the SAP connection string will be constructed. Then the connection string will then be used to create an instance of the R3Connection class to connect with the SAP system. The remaining code is just calling the function module SD_RFC_CUSTOMER_GET and binding the result to the SPGridView.

    Download Source Code | Download Article (PDF)



    How to Custom Master Pages and Dialog Boxes

    So you have a nice custom master page and you are applying it all over your new SharePoint 2010 site, what happens when one of the new dialog boxes is loaded on the page (like when you click to edit a list item)? Guess what… your branded master page with logo and footer and everything will also apply to the much smaller modal dialog box that SharePoint pops up, see the screenshot for an example:
    
    How do we fix this? Microsoft had the good sense to give us an easy CSS class to add to our html elements that we don’t want showing in dialog boxes, simply add s4-notdlg to the class, like this:
    <div class="customFooter"> would become <div class="customFooter s4-notdlg">
    For my design, I added this to the top, header, navigation, and footer div’s in my master page, and BAZINGA I get dialog boxes that have only a hint of my custom branding:
    
    How to Custom Master Pages and Dialog Boxes

    How to Delete all items from lists of SharePoint 2010/2007

    Scenario:
    Often during data migration we need to do clean up list data. I had something similar but there were multiple lists and each list with 5000-10000 records.

    Solution:
    Quick console application did the trick of cleaning all the lists.
    >> Create a new console application and add reference to Microsoft.SharePoint.dll
    >> Use the below code.

    Code: [ Applies To : WSS3.0 / Sharepoint 2010 Foundation ]

    using System; using Microsoft.SharePoint; using System.Collections.Generic; using System.Text;  namespace SKN.CleanSPLists {     class Program     {         static void Main (string[] args)         {             string webUrl = "http://ws2003";             bool deleteFromRecycleBin = true;             List<string> listNames = new List<string>();             listNames.Add("List Title 1");             listNames.Add("List Title 2");             listNames.Add("List Title 3");             listNames.Add("List Title 4");              using (SPSite site = new SPSite(webUrl))             {                 using (SPWeb web = site.OpenWeb())                 {                     foreach (var listName in listNames)                     {                         SPList list = web.Lists[listName];                          Console.WriteLine("Purging list: " + list.Title);                         Console.WriteLine("Base Type: " + list.BaseType.ToString());                                                   StringBuilder sbDelete = BuildBatchDeleteCommand(list);                         web.ProcessBatchData(sbDelete.ToString());                          Console.WriteLine("Done cleaning list : Presss a key to continue with next list.");  Console.WriteLine("");                         Console.ReadKey();                     }                             if (deleteFromRecycleBin)                     {                        Console.WriteLine("Cleaning Recycle bin");    web.RecycleBin.DeleteAll();                         site.RecycleBin.DeleteAll();                       Console.WriteLine("Done cleaning Recycle bin");                       Console.ReadKey();                     }                                  }             }         }                 /// <summary>         /// Builds a batch string with a list of all the items that are to be deleted.         /// </summary>         /// <param name="spList"></param>         /// <returns></returns>         private static StringBuilder BuildBatchDeleteCommand (SPList spList)         {             StringBuilder sbDelete = new StringBuilder();             sbDelete.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");             string command = "<Method><SetList Scope=\"Request\">" + spList.ID +                 "</SetList><SetVar Name=\"ID\">{0}</SetVar><SetVar Name=\"Cmd\">Delete</SetVar></Method>";              foreach (SPListItem item in spList.Items)             {                 sbDelete.Append(string.Format(command, item.ID.ToString()));             }             sbDelete.Append("</Batch>");             return sbDelete;         }     } }


    How to Hide ribbon except for admin in SharePoint 2010


    Scenario:
    Client wanted to hide the ribbon from everyone except admin.

    Solution:
    1) Open your SharePoint master page
    2) Add the following style in head section

    <style type="text/css"> #s4-ribbonrow { display : none; }  </style>
    3) Now find the start of the "s4-ribbonrow" tag and add following block before this:
    <Sharepoint:SPSecurityTrimmedControl ID="SPSecurityTrimmedControl2" runat="server" PermissionsString="AddAndCustomizePages">     <style type="text/css">         #s4-ribbonrow { display : block; }     </script> </Sharepoint:SPSecurityTrimmedControl>
    4) Save the new master page and publish it.


    Retrieving Credentials from Secure Store Service in SharePoint 2010

    Microsoft has replaced the Single Sign-On service in SharePoint 2007 with the Secure Store Service (SSS) in SharePoint 2010. With this change also comes a pretty big overhaul of the API set. If you have written any custom applications, web parts or utilities that used the SSO service in 2007 you may be required to rewrite or update your code to reflect these changes. Currently there is very little information on the Secure Store Service API outside of the list of classes on MSDN. I have, however, managed to write a simple sample console application that can retrieve the credentials of the currently logged in user for an application configured in SSS.

    To use the following sample code you will need to add a reference to the following assemblies:

    • Microsoft.BusinessData
    • System.Web
    • System.Web.DataVisualization
    • Microsoft.Office.SecureStoreService.Server
    • Microsoft.SharePoint

    The Microsoft.Office.SecureStoreService.Server assembly was not immediately available on my SharePoint 2010 beta installation. After much searching I located it in a CAB file and had to extract it out in order to use it. On my server it was located in C:Program Files (x86)MSECacheoserver2010GlobalSearchosrchwfe.cab. Most of the other assemblies can be found in either the .NET tab of the references dialog box in Visual Studio or by browsing to c:program filescommon filesmicrosoft sharedweb server extensions14ISAPI.

    Update (6/4/2010): Microsoft has posted a KB article explaining how to reference the Microsoft.Office.SercureStoreService.dll file from the GAC. http://support.microsoft.com/kb/982263

    Before using this code you will need to configure the Secure Store Service on SharePoint 2010 with at least one application. To retrieve credentials you will also need to have set the credentials for the specified application and associate it with a user account that will be running this sample code.

    Before running the sample code replace SERVERNAME with your own SharePoint 2010 server URL and APPLICATIONID with an application ID stored in SSS. Also ensure that you have the target framework set to 3.5 and the platform target set to Any CPU in Visual Studio.

     ===========================================================

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.SharePoint;
    using Microsoft.Office.SecureStoreService.Server;
    using Microsoft.BusinessData.Infrastructure.SecureStore;

    namespace SSSTEST
    {
    class Program
    {
    static void Main(string[] args)
    {
    //Retrieves the current users application username and password.
    SecureStoreProvider prov = new SecureStoreProvider();
    using(SPSite site = new SPSite(http://SERVERNAME))
    {
    Console.WriteLine(site.RootWeb.CurrentUser.Name);
    SPServiceContext context = SPServiceContext.GetContext(site);
    prov.Context = context;
    string appID = "APPLICATIONID";
    try
    {
    SecureStoreCredentialCollection cc = prov.GetCredentials(appID);
    foreach (SecureStoreCredential c in cc)
    {
    IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(c.Credential);
    string sDecrypString = System.Runtime.InteropServices.Marshal.PtrToStringUni(ptr);
    Console.WriteLine(sDecrypString);
    }
    }
    catch(Exceptionex)
    {
    Console.WriteLine("Unable to get credentials for application "+ appID);
    Console.WriteLine(ex.Message);
    }
    Console.ReadLine();
    }
    }
    }
    }



    SharePoint 2010: Programatically Retrieve Credentials from the Secure Store Service

    SharePoint 2010′s Secure Store Service provides a way to map credentials and delegate access to remote resources. You may already be familiar with the MOSS 2007 Single Sign-on Shared Service, which was the former equivalent. The Secure Store Service integrates seemlessly with Business Connectivity Services (BCS), but it also features an API that can be taken advantage of within custom development projects. This makes the service an attractive option for storing sensitive configuration data such as connection strings, Web service credentials, etc.

    The Secure Store Service allows us to create Target Applications which house sets of credentials. The two main types are Individual and Group applications, Individual meaning credentials are mapped to individual users, and Group meaning all users share the same set of credentials.

    While the raw API isn't very intuitive, its design was likely intentional (additional security by obfuscation). With a little marshalling help from our interop library friends, we are able to retrieve credentials (provided the appropriate permissions to the target application).

    To begin, we need to reference a couple of assemblies.

    Microsoft.BusinessData.dll

    C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.BusinessData.dll

    Microsoft.Office.SecureStoreService.dll

    C:\Windows\assembly\GAC_MSIL\Microsoft.Office.SecureStoreService\14.0.0.0__71e9bce111e9429c\Microsoft.Office.SecureStoreService.dll

    And now for the reason you came to this post … the code

    using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Security; using Microsoft.BusinessData.Infrastructure.SecureStore; using Microsoft.Office.SecureStoreService.Server; using Microsoft.SharePoint;   namespace Trentacular.SharePoint.Util {     public static class SecureStoreUtils     {         public static Dictionary<string, string> GetCredentials(string applicationID)         {             var serviceContext = SPServiceContext.Current;             var secureStoreProvider = new SecureStoreProvider { Context = serviceContext };             var credentialMap = new Dictionary<string, string>();               using (var credentials = secureStoreProvider.GetCredentials(applicationID))             {                 var fields = secureStoreProvider.GetTargetApplicationFields(applicationID);                 for (var i = 0; i < fields.Count; i++)                 {                     var field = fields[i];                     var credential = credentials[i];                     var decryptedCredential = ToClrString(credential.Credential);                       credentialMap.Add(field.Name, decryptedCredential);                 }             }               return credentialMap;         }           public static string ToClrString(this SecureString secureString)         {             var ptr = Marshal.SecureStringToBSTR(secureString);               try             {                 return Marshal.PtrToStringBSTR(ptr);             }             finally             {                 Marshal.FreeBSTR(ptr);             }         }     } }
     

    How to Hide the SharePoint 2010 Ribbon

    If you're creating a Web site and using SharePoint 2010 as a Content Management System platform, perhaps your first challenege as a designer is what to do with that ribbon that is smack-dab in the way of your nice custom layout? At first it seems to be a challenge: For unauthenticated users the ribbon makes no sense and is irrelevant. Your first thought may be to get rid of it entirely. But then, we still need the functionality for users who are authenticated (in order to edit their content) – so we can't get rid of it. What do we do?
     
    There is a solution that fits the needs of designers, developers, their clients and their end-users: Enter the SP2010 Ribbon Toggler! Toggle it with a keystroke, querystring, or a button. Let's implement it:
     
    How to do it
     
    1. Open an editor of your choice to create a new .js file and paste the following code into it:
     function ShowRibbon() {
    $('#s4-ribbonrow').show();
    $('#s4-workspace').height($(document).height() – $('#s4-ribbonrow').height() * 2);
    }

    function HideRibbon() {
    $('#s4-ribbonrow').hide();
    var newHeight = $(document).height();
    if ($.browser.msie) { newHeight = newHeight – 3; }
    $('#s4-workspace').height(newHeight);
    }

     

    2. Save your .js file as SP2010_RibbonToggler.js.
    3. Open up SharePoint Designer and browse to your root site.
    4. In the left tool pane called "Site Objects" click on "Site Assets."
    5. In the top tool bar, select "Import Files" and import the .js file you created. (If you'd like to create a separate "scripts" folder within Site Assets, or organize it in any way you'd like, now's the time.)
    6. In the left tool pane again select "Master Pages."
    7. Open the Master Page that you're using for your Site. In most cases you're probably using v4.master.
    8. In the HTML markup, find the section and place the following JavaScript references within the head section:

     

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    < script type="text/javascript" src="/SiteAssets/SP2010_RibbonToggler.js"></script>

     

    Note: We're first here referencing the jQuery framework. Our code uses this framework to easily and quickly access the Document Object across differing browers. We then reference our SP2010_RibbonToggler.js file. Remember to change the reference path if you put your SP2010_RibbonToggler.js file in a different location than instructed to at the beginning of this tutorial.

    We now have two functions in our SharePoint site for turning on and off the ribbon! Now we just need to implement some Javascript code to use these functions. The sky's the limit for how you want to accomplish this. At Concurrency, we like to use a keystroke combination (ctrl+shift+r) to pop up the ribbon. Here's how to do that:

    In your SP2010_RibbonToggler.js file, at the following code to it:

    $(document).keydown(function (e) {
    if (e.keyCode == 17) { ks = "a"; return false; }
    if (e.keyCode == 16) { if (ks == "a") { ks = ks + "b"; return false; } }
    if (e.keyCode == 82) {
    if (ks == "ab") {
    ks = "";
    if($('#s4-ribbonrow').css('display')=="none") {
    //show
    ShowRibbon();
    } else {
    //hide
    HideRibbon();
    }
    return false;
    }
    }
    return true;
    });

     

    Additional ways to toggle

    Another way to turn on and off the ribbon now is by passing a query string to the page. If we append ?ribn=1 to our site address at any time, the ribbon will show. This is how to do that:

    In your SP2010_RibbonToggler.js file, at the following code to it:

    $(document).ready(function(){
    if(getParameterByName('ribn')=="1″) {
    ShowRibbon();
    } else {
    HideRibbon();
    }
    });

    function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regexS = "[\\?&]" + name + "=([^&#]*)";
    var regex = new RegExp(regexS);
    var results = regex.exec(window.location.href);
    if (results == null)
    return "";
    else
    return decodeURIComponent(results[1].replace(/\+/g, " "));
    }

     

    Or perhaps you only want to show the ribbon if the user has authenticated to SharePoint? Here's how to do that:

    In your SP2010_RibbonToggler.js file, at the following code to it:

     

    $(document).ready(function(){
    if (typeof _spUserId == "undefined") {
    HideRibbon();
    }else {
    ShowRibbon();
    }
    });

     

    In fact, you can add all of these examples to your SP2010_RibbonToggler.js file and they will all work together for you. Wouldn't if be nice if you could download a fully functional .js file with all this working? It would…

    Custom List Forms and Redirecting after Update in SharePoint 2010/2007

    One of my clients required a custom edit form for their editing screen where it would show certain fields and then redirect to a new page after the OK button was clicked. I had done this before at another client except i'd never found a way to actually redirect the page after the save. Here is an article on how to do that to.

    1. In Sharepoint Designer take your EditForm.aspx and copy it.
    2. Rename it
    3. Open this new form and click on the PlaceHolderMain (leave your ListFormWebPart on the page)
    4. In the ListFormWebPart scroll down the properties in the xml which describes the webpart and change to false. For some reason the form will not work unless you leave the original on the page.
    4. Click on Insert->Sharepoint Controls->Custom List Form
    5. Choose the appropriate List and select Edit Form
    6. Sharepoint generates the form for you.

    To customize the save button, find the following control on the page Sharepoint:SaveButton

    1. Delete the SaveButton
    2. Add

    input type="button" value="Save" name="btnSave" onclick="javascript: {ddwrt:GenFireServerEvent('__commit;__redirect={}')}"

    instead
    3. This button allows the form to be saved and redirects to back to that page. See this article for more info

    Hope it helps!

    UPDATE:

    If you wish to update after redirecting this is how i did it:

    add in

    ParameterBinding Name="Source" Location="QueryString(Source)"

    to your paramterbindings list then add

    xsl:param name="Source">0 /xsl:param>
    xsl:variable name="RedirectLoc"> xsl:value-of select="$Source"/> /xsl:variable>

    to your stylesheet

    then the button should be:

    input type="button" value="Save" name="btnTopSave" onclick="javascript: {ddwrt:GenFireServerEvent(concat('__commit;__redirect={',$RedirectLoc,'}'))}"/>