CHAPTER 4

image

Authenticating Yammer Users

Pathik Rawal

In the previous chapter, you learned Yammer App basics, including the registration and configuration processes of Yammer apps. In this chapter, we outline the Yammer authentication process. You will become familiar with the OAuth protocol and its server-side and client-side flows. You’ll also learn to tackle Yammer authentication in the exercise section of this chapter using both client-side OAuth flow and server-side OAuth flow.

In this chapter, we will cover following points

  • Understand Yammer authentication
  • Understand OAuth 2.0
  • Understand OAuth flows
  • Learn and implement server-side flow
  • Learn and implement client-side flow

Understanding Yammer Authentication

The last chapter explained how to register your Yammer apps. Once your Yammer app is registered, you can implement Yammer authentication to connect your line-of-business applications with Yammer using user’s Yammer credential. Yammer uses OAuth 2.0 protocol to authorize business applications in order to access its REST APIs on behalf of a user.

Yammer app authentication using OAuth 2.0 is a three-legged OAuth authorization process, as shown in Figure 4-1. In the first step, user authentication happens to ensure that the user who is accessing your application is valid. In the second step, the app authorization happens, which ensures that users allow your app to access their data. In the final step, the app authentication happens, which ensures that users are sharing their data with an authentic app and not a dubious one.

9781484209448_Fig04-01.jpg

Figure 4-1. The Yammer app authentication flow

Once the Yammer app authentication flow is complete, your application will have all the required permissions (in the form of an access token) to update or retrieve data to Yammer on behalf of the user. If the user has admin privileges, your application can also perform administrative functionalities, such as delete a user, and so on.

What Is OAuth 2.0

The OAuth web site defines OAuth as “An open protocol that allows secure API authorization in a simple and standard method from desktop and web applications.” OAuth (Open Authorization) 2.0 is the next evolution of the open authorization protocol, which was originally created in late 2006.

OAuth 2.0 enables an external application to gain access to another application/service on behalf of a user by organizing an approval flow between users and host application/services or by allowing the external application to retrieve access on its own.

Image Note  OAuth 2.0 requires HTTPS.

OAuth Roles

From a developer perspective, it is important to understand the different OAuth roles that are part of the Yammer’s OAuth authentication process and understand how every role acts in the overall process of authentication. The four important roles are listed and described in Table 4-1.

Table 4-1. OAuth Role Names and Descriptions

Role

Description

Resource Owner

The Yammer user who is granting access to their Yammer profile.

Client Application

An external business application, such as the SPDS University web application or a Windows mobile app.

Resource Server

A server that hosts the resources and responds to the requests of the client applications. The client application will need to present an access token to the resource server to access the resources on Yammer.

Authorization Server

A server that issues the access tokens to the client application. The access token is generated by the authorization server after successfully authenticating the resource owner.

As illustrated in Figure 4-2, multiple parties act during the Yammer OAuth authentication process. The first main role is the resource owner, which, in the Yammer world, represents a user named “Alex Darrow”. Alex Darrow has a valid Yammer account. The second role is the Client Application role, which is the SPDS University web application hosted on SPDS’s web server. To allow users to log in to the SPDS University web application using their Yammer account, the client application needs to implement Yammer’s OAuth flow by implementing the “Sign In with Yammer” button on the web application login page. The third role is the Resource Server which hosts the user’s data and enables REST APIs to access user’s data. In our case, it is the Yammer server. The last role (but not the least) is the Authorization Server which issues access tokens to the client for accessing Alex’s Yammer profile and the data hosted on the resource server.

9781484209448_Fig04-02.jpg

Figure 4-2. OAuth roles

In the next section, you will explore the benefits of OAuth 2.0. Later in this chapter, you will learn about the role of the OAuth 2.0 protocol in Yammer with different authentication flows.

Authentication on Yammer Using OAuth 2.0

The OAuth allows the developer to implement the authentication mechanism within their application in order to authenticate Yammer users. The best thing about OAuth is that it does not require users of the Yammer app to share their passwords with the Yammer app’s developer. Instead using OAuth, users allow/provide external application permission to access their Yammer accounts. Yammer then provides an access token to the business application, which is used to interact with Yammer on behalf of the user(s). The access token never expires and can only be revoked by the users. You can store the access token and use it to make subsequent calls to Yammer until the user revokes the access token. Once the user revokes the access token, you need to use the OAuth flow again to obtain a new one.

OAuth is designed to use two sets of credentials, as listed in Table 4-2.

Table 4-2. OAuth’s Credential Types

Credential Type

Description

A “client” token and secret

Authenticates an application to the provider

An “access” token and secret

Authorizes the application to access a particular set of data

When the user clicks on the “Sign In with Yammer” button in your line-of-business application page, the OAuth 2.0 authentication flow is initiated. As illustrated in Figure 4-3, an ASP.NET web application uses the “Sign In with Yammer” button. By implementing the “Sign In with Yammer” OAuth authentication in your business application, your application allows users of your application to sign in using user’s Yammer credentials rather than creating/managing a new set of credential separately. In the exercise sections of this chapter, you will learn to implement the “Sign In with Yammer” button on an Microsoft ASP.NET and Microsoft SharePoint-hosted app.

9781484209448_Fig04-03.jpg

Figure 4-3. The “Sign In with Yammer” button initiates the OAuth flow

In the next section, you’ll learn the different OAuth flows provided by OAuth authentication. Yammer supports two main OAuth flows—server-side flow and client-side flow.

PROTECTING ACCESS TOKENS

The access tokens are generated for individual users in Yammer and given to client applications when requested. The client token is generated for an indefinite time and never expires. It is recommended that the client application store the access token for each user. It is recommended that developers strongly protect the access token like any other security key or password. Developers should implement encryption in the client application to protect the access token.

Yammer Authentication Flows

The Yammer authentication that uses OAuth 2.0 involves a series of automated steps and mainly provides two different types of OAuth authentication flows, as listed in Table 4-3. In this section, we outline both flows in detail with an exercise of each flow so that you can learn to implement both OAuth flows in your line-of-business applications.

Table 4-3. The OAuth Flows Supported by the OAuth 2.0 Protocol

Flow

Description

Server-side

Developers can leverage the server-side flow, which is also referred to as an “authorization code grant,” from line-of-business applications developed using server technologies like ASP.NET web applications.

Client-side

Developers can leverage the client-side flow, which is also referred to as an “implicit grant,” from line-of-business applications developed using client-side technologies like JavaScript and HTML.

Both flows require user authentication, app authorization, and app authentication, as described in Figure 4-1. Let’s explore both authentication flows and review the steps involved in both flows.

Server-Side Flow

The Yammer OAuth 2.0 endpoint supports web server applications that use programming languages and frameworks such as PHP, Java, Python, Ruby, and C#. The server-side flow requires the client application to secure the “client secret” value.

The “Sign In with Yammer” button is the simplest way to integrate an application with a Yammer app using OAuth 2.0. If your application is a web application like an ASP.NET custom web application or Microsoft SharePoint site, you can add the “Sign In with Yammer” button in HTML/ASPX code and implement redirection to the Yammer OAuth URL for authentication by using the HTML hyperlink tag or handling the Login button event in the code-behind. Later in this chapter, you’ll read a step-by-step guide for implementing OAuth authentication in a SPDS University training application.

The server-side flow, also known as “authorization code grant type,” is the most commonly used because it is optimized for server-side applications, where source code is compiled and assemblies are deployed to the web server, and client secret confidentiality can be maintained. In the entire OAuth 2.0 flow, multiple redirection happens between the client application, the resource server, and the authorization server. So it is essential that the client application handle the redirection and communicate with the user-agent (i.e. the user’s web browser).

Each step involved in the authorization code grant or server-side flow is explained in Table 4-4.

Table 4-4. Steps Invloved in Server-Side Flow

Step

Name

Description

#1

Application Request Authentication

The OAuth 2.0 authentication is initiated as soon as the user (resource owner) clicks on the “Sign In with Yammer” button. Here, the user is redirected to the OAuth 2.0 authorization endpoint.

#2

Yammer Request Credentials

Yammer then prompts the user with a login page.

#3

Yammer Request App Authorization

The OAuth process prompts the user to authorize the Yammer app.

#4

Application Receives Authorization Code

Yammer redirects the user to the app’s Redirect URI with an authorization code.

#5

Application Request Access Token

The client requests a token by using client_id, Client_Secretkey, and the code.

#6

Application Receives Access Token

Based on the client app received by Yammer, Yammer sends the access token to the client application.

#7

Application makes further calls to Yammer

Using the access token, the client application can make additional calls to Yammer on behalf of the user who authorized it.

Let’s explore these steps in Figure 4-4. We have three entities here and those are the end users, the external application, and Yammer. The end user is resource owner who first accesses the external application and clicks on the “Sign In with Yammer” button. Yammer then prompts the user with a login page.

9781484209448_Fig04-04.jpg

Figure 4-4. Steps invloved in server-side OAuth flow

Let’s look at each of these steps in detail and explore how those parameters are passed between the client applications and Yammer’s OAuth provider.

Step #1: Application Request Authentication

The authorization sequence begins when your application redirects the browser to the Yammer OAuth URL; the URL includes query parameters that indicate the type of access being requested. First, you must form the Yammer OAuth URL to initiate the flow.

Your application should redirect the user to the Yammer OAuth URL along with the Yammer app’s ClientID and redirect_uri as per configuration. The OAuth URL is

https://www.yammer.com/dialog/oauth?client_id=[:client_id]&redirect_uri=[:redirect_uri]

Table 4-5 lists the query string parameters used in the Yammer OAuth URL.

Table 4-5. Yammer OAuth URL’s Query String Parameters

Parameter

Description

client_id

Obtain the Client_Id for your Yammer app using the Yammer UI. Use the Https://Www.Yammer.Com/Client_Applications link for a list of registered client IDs.

redirect_uri

The redirect_uri should match the redirect_uri configured for your app in the Yammer platform.

For example, the OAuth URL for the SPDS University web application is:

https://www.yammer.com/dialog/oauth?client_id=9aax1mFox7yMVBS2LpIJQ&redirect_uri=http://localhost:54173/Default.aspx

To obtain the client_id and redirect_uri, navigate to your SPDS University registered app in Yammer, as illustrated in Figure 4-5.

9781484209448_Fig04-05.jpg

Figure 4-5. SPDS University app

Image Note  If your redirect_uri does not match the configuration of your application, then Yammer will throw an error with the description “Invalid URI”.

Step #2: Server Request Credentials

The OAuth process will prompt the user with the Yammer login page, as illustrated in Figure 4-6.

9781484209448_Fig04-06.jpg

Figure 4-6. Yammer login page

This is the standard Yammer’s login page. The user enters the credentials and submits the request. As you notice in Figure 4-6, the Yammer’s login page displays the Yammer app name as “SPDS University” and the network name on which the Yammer is registered as “SPDS”.

Step #3: Server Request App Authorization

In this step, the OAuth 2.0 authentication process shows an App Authorization screen. If the user allows your Yammer app, the app will be authorized and an authorization code will be generated for the user, as shown in Figure 4-7.

9781484209448_Fig04-07.jpg

Figure 4-7. App authorization

Step #4: Application Receives Authorization Code

The response will be sent to redirect_uri, as specified in the request URL. If the user approves the access request, the response contains an authorization code. If the user does not approve the request, the response contains an error message. The redirect URL’s parameters will be different when the user allows the Yammer app than when they deny it access. Let’s look at the redirect URL’s parameters in each case.

Redirect URL’s Parameters When the User Allows the Yammer App

In this case, the user allows the Yammer custom app to get authorization to Yammer on behalf of the user, so Yammer will redirect the user to your Yammer app’s redirect URL. The code appears at the end of URL as a query string, as shown in Figure 4-8. The following is the complete URL format:

http://[:redirect_uri]?code=[:code]

9781484209448_Fig04-08.jpg

Figure 4-8. Redirect URL when user “allows” the Yammer app

Table 4-6 describes the query string parameter.

Table 4-6. Redirect URL’s Query String Parameter

Parameter

Description

Code

Yammer-generated authorization code that’s used to obtain an access token.

You can retrieve the code parameter from the redirect URL and store it in your application. The code will be used in further steps to retrieve the access token.

Redirect URL’s Parameters When the User Denies the Yammer App

In this case, the user denies authorization to Yammer, so Yammer will redirect the user to your Yammer app’s redirect URL with error information at the end of the URL. It’s a query string, as listed in Table 4-7 and shown in Figure 4-9.

http://localhost:54173/Default.aspx?error=access_denied&error_description=the%20user%20denied%20your%20request

Table 4-7. Redirect URL’s Query String Parameters When the User Denies Access

Parameter

Description

Error

This contains an actual error, for example “Access Denied”.

error_description

The description of the error, for example “The user denied your request”.

invalid redirect_uri

If redirect_uri does not match your Yammer app configuration, you get the “Invalid Redirect_uri” error.

9781484209448_Fig04-09.jpg

Figure 4-9. Redirect URL when the user denies the Yammer app

So it’s easy for your application to understand the action taken by the users. Based on the parameters, you can implement the logic to make further calls to Yammer APIs. The best way to do this is to implement the response handler code based on the user’s action and then make further calls. You’ll learn more about this in the exercise section of this chapter.

Step #5: Application Request Access Token

Once the application receives the authorization code from Yammer, it may exchange the authorization code for an access token and a refresh token. This request is an HTTPS POST. Table 4-8 provides the endpoint details, and the endpoint includes the parameters listed in Table 4-9.

Table 4-8. Endpoint to Retrieve the Access Token

Endpoint

Description

https://www.yammer.com/oauth2/access_token.json?client_id=[:client_id]&client_secret=[:client_secret]&code=[:code]

The endpoint to obtain the access token from Yammer.

Table 4-9. The Parameters Used with the Access Token Endpoint

Parameter

Description

Client_id

An unique ID generated by Yammer for your app.

Client_secret

An unique ID generated by Yammer for your app.

Code

The authorization code you receive after the Yammer app is authorized.

The code parameter was obtained in a previous step and the client_id and client_secret code can be configured in your application. You’ll learn in the exercise of this chapter that if your line-of-business application is an ASP.NET web application, you can use Web.Config to store these IDs.

Step #6: Application Receives Access Token

Yammer’s response contains an access token. The access token includes the user profile information, which can be parsed out. Developers can also store the “token,” which can be used to make further calls to Yammer on behalf of the user.

The following code snippet shows the JSON response string, which contains three objects—user, access_token, and network.

{
  "user":
  {
    "timezone": "Hawaii",
    "interests": null,
    "type": "user",
    "mugshot_url": "https://www.yammer.com/yamage-backstage/photos/...",
    "kids_names": null,
    "settings": {
      "xdr_proxy": "https://stagexdrproxy.yammer.com"
    },
    "schools": [],
    "verified_admin": "false",
    "birth_date": "",
    "expertise": null,
    "job_title": "",
    "state": "active",
    "contact": {
      "phone_numbers": [],
      "im": {
        "provider": "",
        "username": ""
      },
      "email_addresses": [
        {
          "type": "primary",
          "address": "[email protected]"
        }
      ]
    },
    "location": null,
    "previous_companies": [],
    "hire_date": null,
    "admin": "false",
    "full_name": "TestAccount",
    "network_id": 155465488,
    "stats": {
      "updates": 2,
      "followers": 0,
      "following": 0
    },
    "can_broadcast": "false",
    "summary": null,
    "external_urls": [],
    "name": "clientappstest",
    "network_domains": [
      "yammer-inc.com"
    ],
    "network_name": "Yammer",
    "significant_other": null,
    "id": 1014216,
    "web_url": "https://www.yammer.com/yammer-inc.com/users/...",
    "url": "https://www.yammer.com/api/v1/users/101416",
    "guid": null
  },
  "access_token": {
    "view_subscriptions": true,
    "expires_at": null,
    "authorized_at": "2011/04/06 16:25:46 +0000",
    "modify_subscriptions": true,
    "modify_messages": true,
    "network_permalink": "yammer-inc.com",
    "view_members": true,
    "view_tags": true,
    "network_id": 155465488,
    "user_id": 1014216,
    "view_groups": true,
    "token": "ajsdfiasd7f6asdf8o",
    "network_name": "Yammer",
    "view_messages": true,
    "created_at": "2011/04/06 16:25:46 +0000"
  },
  "network": {
    "type": "network",
    "header_background_color": "#0092bc",
    "community": false,
    "navigation_background_color": "#3f5f9e",
    "navigation_text_color": "#ffffff",
    "permalink": "yammer-inc.com",
    "paid": true,
    "show_upgrade_banner": false,
    "name": "Yammer",
    "is_org_chart_enabled": true,
    "id": 155465488,
    "header_text_color": "#000000",
    "web_url": "https://www.yammer.com/yammer-inc.com"
  }
}

The access token received from Yammer contains three main objects as listed in Table 4-10. These objects are user, network, and access token.

Table 4-10. The Response Object Contains Three Main Objects

Object

Description

User

Contains the user profile information like time zone, interest, job title, birth date, and so on.

Network

Information about the network on which your Yammer app is deployed.

Access Token

Contains the token with the network ID and user ID to which the token belongs.

Logically, step #6 is the end of the server-side authentication flow. You’ll need to store the OAuth’s access token for each user of your application and use that access token to make further calls on behalf of users to Yammer using REST APIs.

Step #7: Application Makes Further Calls to Yammer

In step #1, you learned how to obtain the access token. Once you obtain the access token, you can store it in secure manner and use it to make further calls. In Chapter 5, you’ll learn how to use Open Graph to read and write data to Yammer using the access token. In Chapter 6, you’ll learn to read and write data into Yammer using the Yammer REST APIs. In Chapter 7, you’ll learn to read and write data into Yammer using Yammer SDKs. Given that you need an access token to make further calls to Yammer, it’s very important to do Exercises 4-1 and 4-2 to obtain the access token. Exercises 4-1 and 4-2 will be used as a base for exercises you see in Chapters 5, 6, and 7.

Implementing Server-Side Flow in an ASP.NET Web Application

In the following exercise, we will implement Yammer authentication using server-side flow in an ASP.NET web application. You need to have Microsoft Visual Studio 2012 Professional, Premium, or Ultimate installed on your local computer.

EXERCISE 4-1: IMPLEMENTING SERVER-SIDE OAUTH FLOW IN AN ASP.NET WEB APPLICATION

In this exercise, we will demonstrate how to implement server-side OAuth flow in an ASP.NET web application called SPDS University Training Application. We will create an ASP.NET web application and implement OAuth authentication using the Yammer app called “SPDS University” that you created in Chapter 3.

Create New Project

  1. Launch Microsoft Visual Studio.
  2. The first screen presented to you is the Visual Studio Start page, as illustrated in Figure 4-10.

    9781484209448_Fig04-10.jpg

    Figure 4-10. The Visual Studio Start page offers a quick way to get started

  3. On the left side of the start page, on the navigation pane, choose new project. Alternatively, you can use the File image New Project command.
  4. This brings up the New Project window. Select ASP.NET Web Forms Application. Then select Web image Visual Studio 2012 image ASP.NET Web Forms Application, as shown in Figure 4-11.

    9781484209448_Fig04-11.jpg

    Figure 4-11. Select the ASP.NET web application template for the new project

  5. Enter the name as “SPDS UniversityWebApplication”.
  6. Click OK.
  7. Visual studio will create a new ASP.NET project with the Web.config file as part of the project, as illustrated in Figure 4-12.

    9781484209448_Fig04-12.jpg

    Figure 4-12. The ASP.NET web site structure

    Add the yammer_signin.png and SPDS-Uni.png files to the Images folder (the yammer_signin.png file can be downloaded from Yammer’s site and SPDS-Uni.png is available from the Source Code/Download area of the Apress web site at http://www.apress.com/9781484209448).

  8. Right-click on the Images folder and then choose Add image Existing Items. Find both images and click OK.

    9781484209448_Fig04-13.jpg

    Figure 4-13. The Yammer_signin.png and SPDS-Uni.Png files added to the Images folder

  9. Open the Site.Master file.
  10. Replace this text in line 7:
    <title><%: Page.Title %> - My ASP.NET Application</title>

    with:

    <title><%: Page.Title %> - SPDS University</title>
  11. Replace the text in line #43:
    <a runat="server" href="~/">your logo here</a>

    with

    <a runat="server" href="~/"><img src="Images/SPDS-Uni.png" /></a>

    Configuration Values in Web.config

    We will use the Web.config file to configure the Yammer App configuration values like client_id, client_secret key, and redirect_uri. These parameters are required in order to call the OAuth URLs from your ASP.NET web application. The best place to configure those parameters is in the <AppSettings> section within Web.Config.

  12. Add the following code to your Web.Config file (add the code at end of the file just above </Configuration>):
    <appSettings>
      <add key="client_id" value="Fmi5JYfF5jqMLCcydqkJWQ" />
      <add key="client_secret" value="GBE5vp3mOUZuRVKqFPsXOA6eOLro95DOFVP5PPgSII0" />
      <add key="redirect_uri" value="http://localhost:54173/Default.aspx" />
      <add key="OAuthURL" value="https://www.yammer.com/dialog/oauth?client_id=" />
    <add key="AccessTokenURL" value="https://www.yammer.com/oauth2/access_token.json?" />
    </appSettings>

    Table 4-11 provides details about each key-value pair used in the previous code.

    Table 4-11. Key-Value Pairs Configured in Web.config

    Key

    Value

    client_id

    Replace value with “SPDS University” Yammer app’s client_id.

    client_secret

    Replace value with “SPDS University” Yammer app’s client_secret.

    redirect_uri

    Replace value with “SPDS University” Yammer app’s redirect_uri.

    OAuthURL

    https://www.yammer.com/dialog/oauth?client_id=, we will form the complete URL in the code

    AccessTokenURL

    https://www.yammer.com/oauth2/access_token.json?, the OAuth’s access token URL

    Image Note  When you use the Microsoft Visual Studio Development Server to run a file system web application project, by default, the development server is invoked on a randomly selected port for the localhost. You can change the port number using the project property windows in Visual Studio.

  13. Navigate to https://www.yammer.com/client_applications, click on your Yammer app, and then click on the Basic Info section. You will see a screen as shown in Figure 4-14. Ensure that the redirect URI has the same value as configured in the previous Web.config file.

    9781484209448_Fig04-14.jpg

    Figure 4-14. Ensure that redirect URI is the same as the value in web.config

    Application’s Home Page

  14. To start designing the default.aspx file as the home page of your application, add the following code to default.aspx by opening it in the source view of Visual Studio. You need to replace the following markup in default.aspx with the content within <asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">:
    <h3>Welcome to SPDS University Application:</h3>
     <ol class="round">
       <li class="one">
         <h2><asp:Label ID="lbllogin" runat="server" Text="You are not Loged in, You can login using Yammer Credential, click on Log In button on top right"></asp:Label>   </h2>
       </li>
     </ol>
     <asp:TextBox ID="txtCode" runat="server" Visible="False"></asp:TextBox>
     <asp:TextBox ID="txtaccesstoken" runat="server" Visible="false"></asp:TextBox>
  15. Remove the following content placeholder from Default.aspx:
    <asp:Content runat="server" ID="FeaturedContent" ContentPlaceHolderID="FeaturedContent">
  16. Login.aspx: You now need to modify the login.aspx file to add the “Log In with Yammer” button. Open login.aspx from account/login.aspx, find <section id="socialLoginForm">, and replace it with the following code:
    <asp:ImageButton ID="imgbtnLogin" runat="server" ImageUrl="~/Images/yammer_signin.png" OnClick="imgbtnLogin_Click" />
  17. Login.aspx: Remove all the validation controls from login.aspx:
    <asp:RequiredFieldValidator runat="server" ControlToValidate="UserName" CssClass="field-validation-error" ErrorMessage="The user name field is required." />

    <asp:RequiredFieldValidator runat="server" ControlToValidate="Password" CssClass="field-validation-error" ErrorMessage="The password field is required." />
  18. Login.aspx.cs: Remove the code from Page_Load() event.
  19. Login.aspx.cs: Open the code-behind file Login.aspx.cs and add the following code in the using directive. This namespace is required to write code in order to read the app settings value from the Web.config file.
    using System.Web.Configuration;
  20. Login.aspx.cs: Add the following code to handle the “Login In with Yammer” button event. Open the Login.aspx file in Design view and double-click on the Login button. This will open the code-behind file Login.aspx.cs.
    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
        protected void imgbtnLogin_Click(object sender, ImageClickEventArgs e)
         {
               string YammerURL = WebConfigurationManager.AppSettings["OAuthURL"] + WebConfigurationManager.AppSettings["client_id"] + "&redirect_uri=" + WebConfigurationManager.AppSettings["redirect_uri"];
                Response.Redirect(YammerURL);
          }

    The button click event forms the OAuth URL. The final OAuth URL should be:

    https://www.yammer.com/dialog/oauth?client_id= 9aax1mFox7yMVBS2LpIJQ&redirect_uri=http://localhost:54173/Default.aspx"

    Table 4-12 describes the query string parameters.

    Table 4-12. OAuth URL’s Query String Parameters

    Parameter

    Description

    client_id

    Obtain the Client_ID for the SPDS University Yammer app using the Yammer UI. Use the https://www.yammer.com/client_applications link for a list of registered client IDs.

    redirect_uri

    The redirect_uri should match the redirect_uri configured for the SPDS University app.

    After forming the OAuth URL by reading values from the Web.Config file, the code calls Response.Redirect(YammerURL).

    If the redirect_URI does not match the configuration of the SPDS University Yammer app, Yammer will throws an error entitled “Invalid Redirect URI”. So be sure that the redirect_uri matches.

    Handle the Yammer’s Response

    Once the OAuth flow is complete, Yammer will redirect to the Redirect URI with the query string parameter, as illustrated in the following URL:

    http://localhost:54173/Default.aspx?code=4G5y1ipTNt5nCtCw8DS1sw
  21. Default.aspx.cs: Open the code-behind file called Default.aspx.cs and add the following code to the using directive. This namespace is required to write code in order to read app settings value from the Web.config file:
    using System.Web.Configuration;
  22. Default.aspx.cs: Add the following code to the Page_Load event to read the query string passed by Yammer in order to find the key "Code" and retrieve the value of the key. Once the code is retrieved, we will store it in a textbox and invoke the call to Yammer using the given code to get the access token.
    /// <summary>
    /// Page load event to check if query string contains a key called "Code"
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
            protected void Page_Load(object sender, EventArgs e)
            {

                string qsCode = Request.QueryString["Code"];
                if (qsCode != null)
                {
                    txtCode.Text = qsCode;
                    Obtain_Access_Token();
                }
                else
                {
                }
            }

    The previous code reads the query string key "Code", if it is present, and then stores the code in a textbox and hides the Login button. Finally, we call the Obtain_Access_Token() method to obtain the access token.

    Obtain the Access Token

    To obtain the access token, we need to submit a GET request using an OAuth 2.0 endpoint, with these three parameters—client_id, client_secret, and code.

    The complete endpoint is:

    https://www.yammer.com/oauth2/access_token.json?client_id=[:client_id]&client_secret=[:client_secret]&code=[:code]

    So let’s implement the code to obtain the access token.

    The response you’ll receive from Yammer will be in JSON or XML format based on the API endpoint you invoke. The JSON endpoint is https://www.yammer.com/oauth2/access_token.json and the XML endpoint is https://www.yammer.com/oauth2/access_token.xml. Your application should convert the given JSON string into an object. In this particular case, the response needs to be deserialized first. Then you retrieve the access token from the instance using DataContractJsonSerializer. So we will start adding few classes to help with serialize and deserialize, back and forth.

  23. In Solution Explorer, right-click on References and select Add Reference. In the assemblies group of references, select the assembly called System.Runtime.Serialization.
  24. In Solution Explorer, right-click on the project and select Add image ASP.NET Folder image App_Code. The App_Code folder is a special folder that stores classes, typed data sets, and other supporting classes for the project. The classes that are stored in App_Code are accessible throughout the application.
  25. In Solution Explorer, right-click on the App_Code folder and then choose Add image Class, as illustrated in Figure 4-15.

    9781484209448_Fig04-15.jpg

    Figure 4-15. Add a new class to your web site project

  26. You will be presented with a window, as illustrated in Figure 4-16, where you need to select the class template.

    9781484209448_Fig04-16.jpg

    Figure 4-16. Select the class template from the available list and then enter the class name

  27. Enter the name of the class as SerializedJson.
  28. Click Add.
  29. Once the class is added, open the class in code mode and add the following code snippet to the class:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using System.IO;

    namespace SPDS UniversityWebApplication.App_Code
    {
        [Serializable]
        public abstract class SerializedJson<T> where T : new()
        {

            public static T GetObjectInstanceFromJson(string data)
            {
                T returnInstance = default(T);

                try
                {
                    MemoryStream m_stream = new MemoryStream();
                    byte[] buf = System.Text.UTF8Encoding.UTF8.GetBytes(data);
                    m_stream.Write(buf, 0, Convert.ToInt32(buf.Length));
                    m_stream.Position = 0;
                    DataContractJsonSerializer sdc_JSON_Ser = new DataContractJsonSerializer(typeof(T));
                    returnInstance = (T)sdc_JSON_Ser.ReadObject(m_stream);
                }
                catch (Exception ex)
                {

                }

                return returnInstance;
            }

        }

    }

    The SerializedJson class implements an abstract method called GetObjectInstanceFromJson, which accepts a JSON string. The method will then convert JSON to stream by using the MemoryStream class and then use the DataContractJsonSerializer class’s ReadObject method to read the JSON into an object.

    The next step is to add classes for data contracts for different objects, including for access token, user, messages, and so on, using the DataContract and DataMember attributes.

  30. Add a new class called User to the App_Code folder by right-clicking on App_Code folder and choosing Add image Class. Specify the name of the class as illustrated in Figures 4-14 and 4-15.
  31. After the class is created, add the following code snippet for the User class.
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using System.IO;
    using System.Diagnostics;

    namespace SPDS UniversityWebApplication.App_Code
    {
        [DataContract]
        public class User : SerializedJson<User>
        {
            [DataMember(Name = "id")]
            public string UserID { get; set; }

            [DataMember(Name = "network_id")]
            public string NetworkID { get; set; }

            [DataMember(Name = "state")]
            public string AccountStatus { get; set; }

            [DataMember(Name = "job_title")]
            public string JobTitle { get; set; }

            [DataMember(Name = "expertise")]
            public string Expertise { get; set; }

            [DataMember(Name = "full_name")]
            public string FullName { get; set; }

            [DataMember(Name = "first_name")]
            public string FirstName { get; set; }

            [DataMember(Name = "last_name")]
            public string LastName { get; set; }

            [DataMember(Name = "url")]
            public string ApiUrl { get; set; }

            [DataMember(Name = "web_url")]
            public string WebUrl { get; set; }

            [DataMember(Name = "mugshot_url")]
            public string PhotoUrl { get; set; }

            [DataMember(Name = "mugshot_url_template")]
            public string PhotoTemplateUrl { get; set; }

            [DataMember(Name = "department")]
            public string Department { get; set; }

            [DataMember(Name = "contact")]
            public ContactInfo ContactInfo { get; set; }

            [DataMember(Name = "web_preferences")]
            public SettingsAndFeedsAndGroups SettingsAndFeedsAndGroups { get; set; }

            [DataMember(Name = "previous_companies")]
            public List<EmployerData> PreviousEmployers { get; set; }

            [DataMember(Name = "schools")]
            public List<YammerSchool> Schools { get; set; }

            [DataMember(Name = "stats")]
            public UserStats UserStats { get; set; }

            public User()
            {
                this.ContactInfo = new ContactInfo();
                this.SettingsAndFeedsAndGroups = new SettingsAndFeedsAndGroups();
                this.PreviousEmployers = new List<EmployerData>();
                this.Schools = new List<YammerSchool>();
                this.UserStats = new UserStats();
            }
        }

        [DataContract]
        public class UserStats
        {
            [DataMember(Name = "followers")]
            public int Followers { get; set; }

            [DataMember(Name = "following")]
            public int Following { get; set; }

            [DataMember(Name = "updates")]
            public int Updates { get; set; }
        }

        [DataContract]
        public class YammerSchool
        {
            [DataMember(Name = "degree")]
            public string Degree { get; set; }

            [DataMember(Name = "description")]
            public string Description { get; set; }

            [DataMember(Name = "end_year")]
            public string EndYear { get; set; }

            [DataMember(Name = "start_year")]
            public string StartYear { get; set; }

            [DataMember(Name = "school")]
            public string School { get; set; }
        }

        [DataContract]
        public class EmployerData
        {
            [DataMember(Name = "description")]
            public string Description { get; set; }

            [DataMember(Name = "employer")]
            public string Employer { get; set; }

            [DataMember(Name = "end_year")]
            public string EndYear { get; set; }

            [DataMember(Name = "position")]
            public string Position { get; set; }

            [DataMember(Name = "start_year")]
            public string StartYear { get; set; }
        }

        [DataContract]
        public class SettingsAndFeedsAndGroups
        {
            [DataMember(Name = "network_settings")]
            public NetworkSettings NetworkSettings { get; set; }

            [DataMember(Name = "home_tabs")]
            public List<GroupsAndFeeds> GroupsAndFeeds { get; set; }

            public SettingsAndFeedsAndGroups()
            {
                this.NetworkSettings = new NetworkSettings();
                this.GroupsAndFeeds = new List<GroupsAndFeeds>();
            }
        }

        [DataContract]
        public class GroupsAndFeeds
        {
            [DataMember(Name = "name")]
            public string Name { get; set; }

            [DataMember(Name = "select_name")]
            public string SelectName { get; set; }

            [DataMember(Name = "type")]
            public string Type { get; set; }

            [DataMember(Name = "feed_description")]
            public string Description { get; set; }

            [DataMember(Name = "ordering_index")]
            public int OrderingIndex { get; set; }

            [DataMember(Name = "url")]
            public string Url { get; set; }

            [DataMember(Name = "group_id")]
            public string GroupID { get; set; }

            [DataMember(Name = "private")]
            public bool IsPrivate { get; set; }
        }

        [DataContract]
        public class NetworkSettings
        {
            [DataMember(Name = "message_prompt")]
            public string MessagePrompt { get; set; }

            [DataMember(Name = "allow_attachments")]
            public bool AllowAttachments { get; set; }

            [DataMember(Name = "show_communities_directory")]
            public bool ShowCommunitiesDirectory { get; set; }

            [DataMember(Name = "enable_groups")]
            public bool EnableGroups { get; set; }

            [DataMember(Name = "allow_yammer_apps")]
            public bool AllowYammerApps { get; set; }

            [DataMember(Name = "admin_can_delete_messages")]
            public bool AdminCanDeleteMessages { get; set; }

            [DataMember(Name = "allow_inline_document_view")]
            public bool AllowInlineDocumentView { get; set; }

            [DataMember(Name = "allow_inline_video")]
            public bool AllowInlineVideo { get; set; }

            [DataMember(Name = "enable_private_messages")]
            public bool EnablePrivateMessages { get; set; }

            [DataMember(Name = "allow_external_sharing")]
            public bool AllowExternalSharing { get; set; }

            [DataMember(Name = "enable_chat")]
            public bool EnableChat { get; set; }
        }
        [DataContract]
        public class ContactInfo
        {
            [DataMember(Name = "has_fake_email")]
            public bool HasFakeEmail { get; set; }

            [DataMember(Name = "email_addresses")]
            public List<EmailAddresses> EmailAddresses { get; set; }

            [DataMember(Name = "phone_numbers")]
            public List<PhoneNumbers> PhoneNumbers { get; set; }

            [DataMember(Name = "im")]
            public IM IM { get; set; }

            public ContactInfo()
            {
                this.EmailAddresses = new List<EmailAddresses>();
                this.PhoneNumbers = new List<PhoneNumbers>();
                this.IM = new IM();
            }
        }

        [DataContract]
        public class EmailAddresses
        {
            [DataMember(Name = "address")]
            public string Address { get; set; }

            [DataMember(Name = "type")]
            public string Type { get; set; }

            public EmailAddresses() { }

            public EmailAddresses(string address, string type)
            {
                this.Address = address;
                this.Type = type;
            }
        }

        [DataContract]
        public class PhoneNumbers
        {
            [DataMember(Name = "number")]
            public string PhoneNumber { get; set; }

            [DataMember(Name = "type")]
            public string Type { get; set; }
        }

        [DataContract]
        public class IM
        {
            [DataMember(Name = "provider")]
            public string Provider { get; set; }

            [DataMember(Name = "username")]
            public string UserName { get; set; }
        }
    }
  32. Add a new class called Data to the App_Code folder by right-clicking on the App_Code folder and choosing Add image Class. Specify the name of the class as illustrated in Figures 4-14 and 4-15.

    The Data.cs class defines two classes, AccessToken and TokenResponse by attaching DataContractAttribute to the classes and DataMemberAttribute to the members you want to serialize.

  33. Replace the following code snippet in the Data.cs. It defines the AccessToken and TokenResponse classes.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using System.IO;
    using System.Diagnostics;

    namespace SPDS UniversityWebApplication.App_Code
    {

        [DataContract]
        public class TokenResponse
        {
            [DataMember(Name = "user_id")]
            public string UserID { get; set; }

            [DataMember(Name = "network_id")]
            public string NetworkID { get; set; }

            [DataMember(Name = "network_permalink")]
            public string NetworkPermaLink { get; set; }

            [DataMember(Name = "network_name")]
            public string NetworkName { get; set; }

            [DataMember(Name = "token")]
            public string Token { get; set; }
        }

        [DataContract]
        public class AccessToken : SerializedJson<AccessToken>
        {
            [DataMember(Name = "access_token")]
            public TokenResponse TokenResponse { get; set; }

            [DataMember(Name = "user")]
            public User CurrentUser { get; set; }

            public AccessToken()
            {
                this.TokenResponse = new TokenResponse();
                this.CurrentUser = new User();
            }
        }
    }
  34. Add a new class called YammerUtility to the App_Code folder by right-clicking on that folder and choosing Add image Class. Specify the name of the class as illustrated in Figures 4-14 and 4-15.
  35. Add the following code to the YammerUtility.cs file.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Net;
    using System.IO;

    namespace SPDS UniversityWebApplication.App_Code
    {
        public class YammerUtility
        {
            private static HttpWebResponse HTTPWebRes;
            private static HttpWebRequest HTTPWebReq;

            /// <summary>
            ///
            /// </summary>
            /// <param name="Url"></param>
            /// <param name="authHeader"></param>
            /// <param name="AddCookies"></param>
            /// <returns></returns>
            public static string InvokeHttpGetRequest(string Url, string authHeader = null, bool AddCookies = false)
            {
                string results = string.Empty;

                try
                {
                    HTTPWebReq = WebRequest.CreateHttp(Url);
                    HTTPWebReq.Method = "GET";

                    if (!string.IsNullOrEmpty(authHeader))
                        HTTPWebReq.Headers.Add("Authorization", "Bearer " + authHeader);

                    HTTPWebRes = (HttpWebResponse)HTTPWebReq.GetResponse();

                    Stream dataStream = HTTPWebRes.GetResponseStream();
                    StreamReader reader = new StreamReader(dataStream);

                    results = reader.ReadToEnd();

                    reader.Close();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error in MakeGetRequest: " + ex.Message);
                }

                return results;
            }

        }
    }

    In the previous class definition, the AccessToken class contains two other objects—TokenResponse (defined in Data.cs) and User (defined in user.cs).

  36. Add the method Obtain_Access_Token() to the Default.aspx.cs file.
    /// <summary>
            /// Obtain the access Token
            /// </summary>
            private void Obtain_Access_Token()
            {
                string accessToken = default(string);
                string AccesTokenURL = WebConfigurationManager.AppSettings["AccessTokenURL"] + "client_id=" + WebConfigurationManager.AppSettings["client_id"] + "&client_secret=" + WebConfigurationManager.AppSettings["client_secret"] + "&code=" + txtCode.Text;
                string response = SPDS UniversityWebApplication.App_Code.YammerUtility.InvokeHttpGetRequest(AccesTokenURL);
                if (!string.IsNullOrEmpty(response))
                {
                    SPDS UniversityWebApplication.App_Code.AccessToken jat = SPDS UniversityWebApplication.App_Code.AccessToken.GetObjectInstanceFromJson(response);

                    if (!string.IsNullOrEmpty(jat.TokenResponse.Token))
                    {
                        accessToken = jat.TokenResponse.Token;
                        lbllogin.Text = "Welcome " + jat.CurrentUser.FullName;
                        txtaccesstoken.Text = accessToken;
                        Session["accesstoken"] = accessToken;
                    }
                }
            }

    We added three classes to the project. Figure 4-17 shows the class diagrams

    9781484209448_Fig04-17.jpg

    Figure 4-17. The Yammer authentication classes

    The access token received from Yammer will be valid for a very long time, so you should save the token for a user and keep using it. For the ASP.NET application, the best approach is to store it in the cookies.

    Image Note  Once the access token expires, developers have to re-run the previous steps to generate a new code and access token. If a new access token is requested for the user who has already authorized your app, that user will not be promoted to authorize the app again.

    Run the Application

  37. Press F5 to execute the application. It will open in Internet Explorer with the Default.aspx file as the home page. The page will look similar to Figure 4-18.

    9781484209448_Fig04-18.jpg

    Figure 4-18. The Default.aspx file in run mode

  38. Click on the “Log In” button, which will redirect you to the Login page. That page allows users to log in using their registered accounts or using Yammer, as illustrated in Figure 4-19.

    9781484209448_Fig04-19.jpg

    Figure 4-19. The Login.aspx page in run mode

  39. Click on the “Sign In with Yammer” button.
  40. You will be prompted with the Yammer Login page. Enter your login credentials and click “Log In,” as shown in Figure 4-20.

    9781484209448_Fig04-20.jpg

    Figure 4-20. Yammer Login page

  41. You will be presented with the Default.aspx page showing a message, as illustrated in Figure 4-21.

9781484209448_Fig04-21.jpg

Figure 4-21. The message after successful completion of OAuth 2.0 flow

At this point, you have successfully implemented OAuth 2.0 server-side flow in an ASP.NET web application. In the next section, you will look at the client-side flow using a similar exercise. It will showcase the client-side flow in a Microsoft SharePoint-hosted app.

Client-Side Flow

Yammer’s OAuth authentication also supports client-side flows for authentication and authorization of JavaScript-centric applications. Client-side flows are optimized for public clients, such as those implemented in JavaScript or on mobile devices, where client credentials cannot be stored.

The client-side flow is also referred as an “implicit grant,” which is different from the server-side flow. In the client-side flow, the client makes a single request only to obtain the access token, as the authorization code is not required in this case.

The steps involved in an implicit grant or a client-side flow are as follows:

Step

Name

Description

#1

Application Request Authentication

The OAuth 2.0 authentication is initiated as soon as the user (resource owner) clicks on the “Sign In with Yammer” button; here, the user is redirected to the OAuth 2.0 authorization endpoint.

#2

Yammer Request Credentials

Yammer authorization server then prompts the user with a login page.

#3

Yammer Request App Authorization

The OAuth process prompts the user to authorize the Yammer app.

#4

Application Receives Access Token

Once authorized, Yammer sends the access token to the client app.

Step #1: Application Request Authentication

The authorization sequence begins when your application redirects a browser to the Yammer OAuth URL; the URL includes query parameters that indicate the type of access being requested. First, as for server-side flow, you must create the Yammer OAuth URL to initiate the flow.

Your application should redirect the user to the OAuth URL along with the Yammer app’s ClientID and redirect_URI as per configuration. The OAuth URL is

https://www.yammer.com/dialog/oauth?client_id=[:client_id]&redirect_uri=[:redirect_uri] &response_type=token

Table 4-13 lists all the parameters required in order to request the access token.

Table 4-13. OAuth URL’s Query String Parameters

Parameter

Description

client_id

Obtain the Client_ID for your Yammer app using the Yammer UI. Use the https://www.yammer.com/client_applications link for list of the registered client ID.

redirect_uri

This redirect_uri should match the redirect_uri configured for your app in the Yammer platform.

response_type

The response_type=token parameter.

For the SPDS University SharePoint-hosted app, the complete OAuth URL will look like this:

https://www.yammer.com/dialog/oauth?client_id=9aax1mFox7yMVBS2LpIJQ&redirect_uri=http://localhost:54173/Default.aspx&response_type=token

To obtain the client_id and redirect_uri, navigate to your registered app in Yammer, as illustrated in Figure 4-22.

9781484209448_Fig04-22.jpg

Figure 4-22. The SPDS University app’s Key and Tokens Configuration

Step #2: Server Request Credentials

The OAuth process will prompt the user with the Yammer Login window. Users then enter their credentials and submit the request, as shown in Figure 4-23.

9781484209448_Fig04-23.jpg

Figure 4-23. Yammer Login page

Step #3: Server Request App Authorization

In this step, the OAuth 2.0 authentication process shows an App Authorization screen, as shown in Figure 4-24. If the user has allowed your Yammer app, the app will be authorized and an access token will be generated for that user.

9781484209448_Fig04-24.jpg

Figure 4-24. App authorization

Step #4: Application Receives Access Token

The response will be sent to the redirect_uri as specified in the request URL. If the user approves the access request, then the response contains an authorization code. If the user does not approve the request, the response contains an error message. The redirect URL’s parameters will be different when the user allows the Yammer app compared to when they deny it access. Let’s look at the redirect URL’s parameters in each case.

Redirect URL’s Parameters When Users Allow the Yammer App

Yammer will redirect the users to your Yammer app’s redirect URL as per its configuration with the authorization code (parameter) as part of the URL. It’s a query string and is listed in Table 4-14.

http://[:redirect_uri]#access_token=[:access_token]

Table 4-14. OAuth URL’s Query String Parameters

Parameter

Description

redirect_uri

The redirect_uri used in the OAuth URL.

access_token

Yammer-generated access_token for the user who has authorized the app.

Redirect URL’s Parameters When Users Deny the Yammer App

When the user denies access to the Yammer custom app, Yammer will redirect the users to your Yammer app’s redirect URL as per its configuration. The error information is within the URL as query string. Table 4-15 lists all the query string parameters from the redirect URL.

Table 4-15. OAuth URL’s Query String Parameter

Parameter

Description

Error

This contains the actual error; for example, “Access Denied”.

error_description

The description of the error; for example, “The user denied your request”.

invalid redirect_uri

If redirect_uri does not match your Yammer app configuration, you get an error entitled “Invalid Redirect_uri”.

For example, the following URL contains “access denied” in the error parameter and “the user denied your request” in the error description parameter.

http://localhost:54173/Default.aspx?error=access_denied&error_description=the%20user%20denied%20your%20request

In this section you learned about the steps involved in client-side flow, which is mainly used in business applications that use client scripting like JavaScript.

Implementing Client-Side Flow in a Microsoft SharePoint-Hosted App

In the next exercise, we will implement Yammer authentication using client-side flow in a Microsoft SharePoint-hosted app. You need to have Visual Studio 2012 Professional, Premium, or Ultimate installed on your local computer. You also need to have the Office Developer Tools for Visual Studio 2012 installed. These can be downloaded from http://msdn.microsoft.com/en-us/office/apps/fp123627.

EXERCISE 4-2: CLIENT-SIDE FLOW USING THE “SIGN IN WITH YAMMER” BUTTON WITH THE JAVASCRIPT SDK

In this exercise, we will create a SPDS University, Microsoft SharePoint-hosted app for Microsoft SharePoint Online. There will be a “Log In with Yammer” button on the Microsoft SharePoint App’s target page.

Prerequisites for Creating a Basic Microsoft SharePoint-Hosted App

  • A computer that is configured for app isolation with Microsoft SharePoint 2013 installed on it. If you’re using an Office 365 Developer Site, you already have a Microsoft SharePoint 2013 environment that supports OAuth.
  • Visual Studio 2012 or higher.
  • Office Developer Tools for Visual Studio 2012.

Create a New Microsoft SharePoint App Project

  1. Start Visual Studio by using the Run as Administrator option.
  2. The first screen presented to you is the Visual Studio Start page, as illustrated in Figure 4-25.

    9781484209448_Fig04-25.jpg

    Figure 4-25. Visual Studio Start page offers a quick way to get started

  3. On the left side of the start page, on the navigation pane, choose New Project. Alternatively you can use the File image New Project menu command.
  4. This brings up the New Project window, as illustrated in Figure 4-26. Expand the Visual C# node, expand the Office/SharePoint node, and then choose Apps image App for SharePoint 2013.

    9781484209448_Fig04-26.jpg

    Figure 4-26. Select the app for the SharePoint template under Office/SharePoint

  5. You will be presented with the Specify the App for SharePoint Settings window. Name your app and provide the URL of the Microsoft SharePoint 2013 site that you want to use to debug your app. Under the “How do you want to host your app for SharePoint” option, choose SharePoint-hosted. Then click the Finish button, as shown in Figure 4-27.

    9781484209448_Fig04-27.jpg

    Figure 4-27. Specify the app for the SharePoint settings and provide the URL of the SharePoint web site that you want to use for debugging

    After the wizard finishes, you should have a structure in Solution Explorer that resembles Figure 4-28. The solution comprises one App Project that contains the SharePoint-hosted app structure with an AppManifest.xml file.

    9781484209448_Fig04-28.jpg

    Figure 4-28. The SharePoint-hosted app project structure

    Create Customer Ribbon Action

    We will now add a new “Menu Item Custom Action” item to the SharePoint app. But first we will add a page for the custom action.

  6. Right-click on the Page node in the web project and add a new page. Name the page CustomActionTarget.aspx, as shown in Figure 4-29.

    9781484209448_Fig04-29.jpg

    Figure 4-29. Adding a new page to the SharePoint app project

    Add a Control “Menu Item Custom Action

  7. Right-click on the page node for the SharePoint project and add a new “Menu Item Custom Action” item. Name it MenuItem_PosttoYammer, as illustrated in Figure 4-30.

    9781484209448_Fig04-30.jpg

    Figure 4-30. Add a new menu item custom action to the SharePoint app project

  8. You’ll be presented with the Specify the Properties to Create Custom Action Menu Item window, as illustrated in Figure 4-31. From there, you need to set the following properties for the custom action (refer to Table 4-16 for each property value).

    9781484209448_Fig04-31.jpg

    Figure 4-31. Set the properties for the custom action

    Table 4-16. OAuth URL’s Query String Parameter

    Property Question

    Answer

    Where do you want to expose the custom action?

    Choose Host Web

    Where is the custom action scoped to?

    Choose List Template

    Which particular item is the custom action scoped to?

    Choose Custom List

    What is the text on the menu item?

    Type “Invoke post to Yammer custom action”

  9. You’ll be presented with another window, entitled Specify the Properties to Create Custom Action Menu Item, as illustrated in Figure 4-32. From there, you need to set the following properties for the custom action (refer to Table 4-17 for property value).

    9781484209448_Fig04-32.jpg

    Figure 4-32. Set the properties for the custom action

    Table 4-17. Specify the Properties for the Custom Action

    Property Question

    Answer

    What is the text on the menu item?

    Enter “Invoke ’Post To Yammer Action”

    Where the custom action does navigates to?

    Choose the CustomActionTarget.aspx which we created in previous step

  10. After setting the properties for the custom action menu item, click Finish.

    Visual Studio generates the following markup in the elements.xml file of the menu item custom action feature:

    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <CustomAction Id="75be0d47-8c42-4f9b-afd4-7bb601ffc5e0.MenuItem_PostToYammer"
                    RegistrationType="List"
                    RegistrationId="100"
                    Location="EditControlBlock"
                    Sequence="10001"
                    Title="Invoke &apos;Post To Yammer&apos; action">
        <!--
        Update the Url below to the page you want the custom action to use.
        Start the URL with the token ~remoteAppUrl if the page is in the
        associated web project, use ~appWebUrl if page is in the app project.
        -->
        <UrlAction Url="~appWebUrl/Pages/CustomActionTarget.aspx?{StandardTokens}&amp;SPListItemId={ItemId}&amp;SPListId={ListId}" />
      </CustomAction>
    </Elements>

    Implement the Authentication

    We have all controls in the project so now we can start implementing the authentication using the JavaScript SDK. First we’ll modify the CustomActionTarget.aspx page by adding some code in the HTML markup.

  11. Add the following HTML markup to CustomActionTarget.aspx. Add this within the <asp:Content ContentPlaceHolderId="PlaceHolderAdditionalPageHead" runat="server"> placeholder:
    <script type="text/javascript" src="../Scripts/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.js"></script>
    <script type="text/javascript" data-app-id="Fmi5JYfF5jqMLCcydqkJWQ" src="https://c64.assets-yammer.com/assets/platform_js_sdk.js"></script>

    Here you need to replace data-app-id with your Yammer app’s ID. You need to get the client ID that was generated when you registered the app on Yammer.com.

    The second parameter sec refers to the JavaScript SDK.

  12. Replace the following code snippet with ContentPlaceHolderID="PlaceHolderMain" in the CustomActionTarget.aspx file:
    <asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">
          <div>
            <h3>Yammer Authenication Example</h3>
            <br />
            <span id="yammer-login"></span>
          </div>

          <div class="logged-in" style="display:none">
                <p>User is now signed in to the app using Yammer</p>
                <button id="disconnect" class="yj-btn yj-btn-alt">Log out from your Yammer account</button>
          </div>
          <div class="logged-in" style="display:none">
                <h2>Authentication Logs</h2>
                <pre id="authResult"></pre>
          </div>

    </asp:Content>

    This code will display the “Log In with Yammer” button, as illustrated in Figure 4-33. It uses an HTML span control with ID="yammer-login" to create that button.

    9781484209448_Fig04-33.jpg

    Figure 4-33. The “Log In with Yammer” button created using the span control with Id=“yammer-Login”

  13. Add the following JavaScript code to ContentPlaceHolderID="PlaceHolderAdditionalPageHead" of CustomActionTarget.aspx:
    01:  <script>
    02:        yam.connect.loginButton('#yammer-login',
    03:              function (resp) {
    04:                  if (resp.authResponse) {
    05:                      console.log(resp);
    06:                      displayAuthResult(resp);
    07:                  }
    08:              });

    09:        function displayAuthResult(resp) {
    10:            document.getElementById("yammer-login").innerHTML = 'Welcome to Yammer!, The user ID is:  ' + resp.access_token.user_id;
    11:           toggleLoginStatus(true);
    12:            $('#authResult').append(' ========= <br/>');
    13:            $('#authResult').append(' Access Token: <br/>');
    14:            $('#authResult').append(' ========= <br/>');
    15:            for (var field in resp.access_token) {
    16:                $('#authResult').append(' ' + field + ': ' +
    17:                   resp.access_token[field] + '<br/>');
    18:           }
    19:        }

    20:        function toggleLoginStatus(loggedIn) {
    21:            if (loggedIn) {
    22:                $('.not-logged-in').hide();
    23:                $('.logged-in').show('slow');
    24:            } else {
    25:                $('.not-logged-in').show('slow');
    26:                $('.logged-in').hide();
    27:            }
    28:        }
    29:  </script>

    This JavaScript code on line 2 calls the yam.connect.loginButton function by passing two parameters—the selector (ID of span control "yammer-login" as a selector) and the callback function (function that will be fired after the login flow is completed). The span control <span id="yammer-login"></span> in the ContentPlaceHolderId="PlaceHolderMain" will become a standard “Log In with Yammer” button. When this button is clicked, it will initiate the Yammer client-side OAuth workflow. Once the user approves or denies the SPDS University app, the OAuth callback will fire. The callback function on lines 3-8 first checks if AuthResponse is true and then calls the displayAuthResult function by passing the resp parameter. The displayAuthResult function code on line 9 changes the inner HTML of the span control to a welcome message and the user ID of the logged in user. The for loop on lines 15-18 displays all the properties of the resp.

  14. The complete code of CustomActionTarget.aspx is shown in the following code snippet:
    <%@ Page Language="C#" MasterPageFile="~masterurl/default.master" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

    <%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

    <asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
       <SharePoint:ScriptLink Name="sp.js" runat="server" OnDemand="true" LoadAfterUI="true" Localizable="false" />
       <script type="text/javascript" src="../Scripts/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.js"></script>
    <script type="text/javascript" data-app-id="Fmi5JYfF5jqMLCcydqkJWQ" src="https://c64.assets-yammer.com/assets/platform_js_sdk.js"></script>
        <script>
          yam.connect.loginButton('#yammer-login',
             function (resp) {
                  if (resp.authResponse) {
                      console.log(resp);
                      displayAuthResult(resp);
                  }
              });
        function displayAuthResult(resp) {
            document.getElementById('yammer-login').innerHTML = 'Welcome to Yammer!, The user ID is:  ' + resp.access_token.user_id;
            toggleLoginStatus(true);
            $('#authResult').append(' ========= <br/>');
            $('#authResult').append(' Access Token: <br/>');
            $('#authResult').append(' ========= <br/>');
            for (var field in resp.access_token) {
                $('#authResult').append(' ' + field + ': ' +
                   resp.access_token[field] + '<br/>');

            }
        }
        function toggleLoginStatus(loggedIn) {
            if (loggedIn) {
                $('.not-logged-in').hide();
                $('.logged-in').show('slow');
            } else {
                $('.not-logged-in').show('slow');
                $('.logged-in').hide();
            }
        }
    </script>
    </asp:Content>
    <asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">
       <div>
          <h3>Yammer Authenication Example</h3>
          <br />
          <span id="yammer-login"></span>
      </div>
       <div class="logged-in" style="display: none">
              <h2>Authentication Logs</h2>
              <pre id="authResult"></pre>
          </div>
    </asp:Content>

    Run the Solution

  15. You can run this app now and see that Visual Studio deploys the app to your site. To deploy it from Visual Studio, select Deploy from the project’s context menu, as illustrated in Figure 4-34.

    9781484209448_Fig04-34.jpg

    Figure 4-34. Visual Studio’s deploy solution

  16. Visual Studio will deploy the solution to the SharePoint Online site. In the first step, it will prompt you to log in to your SharePoint Online site, enter your Office 365 credentials, and click on Sign In, as shown in Figure 4-35.

    9781484209448_Fig04-35.jpg

    Figure 4-35. Log in to the Office 365 site

  17. You will be prompted to authorize the app. Click on the Trust It button and Visual Studio will deploy the app in the target site, as shown in Figure 4-36.

    9781484209448_Fig04-36.jpg

    Figure 4-36. SharePoint prompts you to authorize the app

  18. You will be presented with the SharePoint app’s default page, as shown in Figure 4-37.

    9781484209448_Fig04-37.jpg

    Figure 4-37. The app’s default page

  19. Now click on the “Log In with Yammer” button. You will be prompted with the Yammer Login screen, as illustrated in Figure 4-38.

9781484209448_Fig04-38.jpg

Figure 4-38. Clicking on the “Log In with Yammer” button opens the Yammer Login page

After you log into Yammer using your Yammer credentials, Yammer will return to the callback function you have written in the Default.aspx function. In this case it is the inline callback function that checks if resp.authResponse is not null. If it is not null, that means the user is already logged into Yammer. The code then displays the fields available in access_tokenuser_id, network_id, network_permalink, network_name, token, view_members, view_groups, view_message, view_subscriptions, modify_subscriptions, modify_message, view_tags, created_at, authorized_at, and expires_at, as shown in Figure 4-39.

9781484209448_Fig04-39.jpg

Figure 4-39. CustomActionTarget.aspx displays the fields from access_token after the user logs in successfully

At this point, you have successfully implemented OAuth 2.0 client-side flow in a SharePoint-hosted app.

Summary

By now you are aware of Yammer apps and understand the authorization process on Yammer for integration with your business applications. Examples provided in this chapter have given you a kick-start to enable Yammer integration in your business applications. In Chapters 5, 6, and 7, you’ll learn advanced Yammer integration concepts using different technologies like Open Graph and REST APIs.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset