Ниже приведен фрагмент кода для проверки подлинности yammer. Статья Стива Пеши — http://blogs.technet.com/b/speschka/archive/2013/10/05/using-the-yammer-api-in-a-net-client-application.aspx объясняет, как выполнить программную проверку подлинности yammer. Я настроил его в соответствии со своими потребностями.
public class YammerSession
{
#region Variables
/// <summary>
/// The client identifier
/// </summary>
private readonly string clientId = "XXXXXXXX";
/// <summary>
/// client secret
/// </summary>
private readonly string clientSecret = "XXXXXXXX";
/// <summary>
/// Cookie container that stores yammer authentication information
/// </summary>
private CookieContainer cookieContainer = new CookieContainer(2);
/// <summary>
/// The user code sent in response to login request
/// </summary>
private string userCode;
/// <summary>
/// The user email
/// </summary>
private string email;
/// <summary>
/// The user password
/// </summary>
private SecureString password;
#endregion
#region Methods
/// <summary>
/// Gets the supported yammer version
/// </summary>
public static int SupportedVersion
{
get
{
return 1;
}
}
/// <summary>
/// Gets the client id.
/// </summary>
public string ClientId
{
get
{
return this.clientId;
}
}
/// <summary>
/// Gets the authenticity token.
/// </summary>
/// <value>
/// The authenticity token.
/// </value>
public string AuthenticityToken { get; private set; }
/// <summary>
/// Gets the token.
/// </summary>
/// <value>
/// The token.
/// </value>
public string Token { get; private set; }
/// <summary>
/// Connects the specified connection.
/// </summary>
public override void Connect()
{
this.InternalLogin(this.Connection.User, this.Connection.Password);
}
/// <summary>
/// Disconnects this instance.
/// </summary>
public override void Disconnect()
{
// Log out
this.InternalLogout(this.Connection.Address);
}
/// <summary>
/// Creates the web request to a service endpoint.
/// </summary>
/// <param name="serviceEndpoint">The service endpoint.</param>
/// <returns>
/// A new HTTP web request.
/// </returns>
public string GetEndpoint(string serviceEndpoint)
{
// Get the uri
var requestUri = string.Format("{0}/api/v{1}/{2}", this.Connection.Address, SupportedVersion, serviceEndpoint);
// return the result
return requestUri;
}
/// <summary>
/// Connects the specified email.
/// </summary>
/// <param name="email">The email.</param>
/// <param name="password">The password.</param>
private void InternalLogin(string email, SecureString password)
{
this.email = email;
this.password = password;
// Get the user code.
this.GetUserCode();
// Now get the bearer token
this.GetBearerToken(this.userCode);
}
/// <summary>
/// Gets the user code.
/// </summary>
private void GetUserCode()
{
string yammerAuthUrl = string.Format("https://www.yammer.com/dialog/oauth?client_id={0}", this.clientId);
string yammerSessionUrl = string.Format("https://www.yammer.com/session?client_id={0}", this.clientId);
// The authenticity token
string authenticityToken = string.Empty;
// Make a get request to Yammer authentication endpoint and get the response
using (HttpWebResponse webResponse = this.MakeGetRequestToEndPoint(yammerAuthUrl))
{
// Set the cookies
this.SetCookies(webResponse);
// Look for authenticity token
authenticityToken = this.GetAuthenticityToken(SessionHelper.ConvertResponseStreamToString(webResponse, Encoding.UTF8));
}
if (!string.IsNullOrEmpty(authenticityToken))
{
// Construct the post body with user login information
string postBody = string.Format(
"{0}{1}{2}{3}{4}{5}{6}",
"utf8=%E2%9C%93&authenticity_token=",
HttpUtility.UrlEncode(authenticityToken),
"&network_permalink=&login=",
HttpUtility.UrlEncode(this.email),
"&password=",
HttpUtility.UrlEncode(this.password.ConvertToUnsecureString()),
"&remember_me=off");
// Make the first post for User Code
HttpWebResponse sessionPostWebResponse = this.MakePostRequestToEndPoint(postBody, yammerSessionUrl);
string postResults = this.GetResponseAsString(sessionPostWebResponse);
// Get the next auth token that was returned. This will be used for logout purposes
this.AuthenticityToken = this.GetAuthenticityToken(postResults);
using (HttpWebResponse webResponse = this.MakeGetRequestToEndPoint(yammerAuthUrl, true))
{
// Now look for the query string and set the user code
this.userCode = webResponse.ResponseUri.Query;
// Check whether we are in Authorization Page
if (this.userCode.IndexOf("?client_id") >= 0)
{
// Construct the yammer network name
string yammerNetworkName = webResponse.ResponseUri.AbsolutePath.Substring(0, webResponse.ResponseUri.AbsolutePath.ToLower().IndexOf("dialog/"));
// Construct the yammer decision url
string yammerUserAuthDecisionUrl = string.Format(
"{0}{1}{2}{3}{4}",
"https://www.yammer.com",
yammerNetworkName,
"oauth2/decision?client_id=",
this.clientId,
"&redirect_uri=https%3A%2F%2Fwww.yammer.com&response_type=code");
// Construct the Payload for authorization page
string payLoad = "utf8=%E2%9C%93&authenticity_token=" + HttpUtility.UrlEncode(this.AuthenticityToken) + "&allow=Allow";
// Authorize the app by posting the request
using (HttpWebResponse decisionPostWebResponse = this.MakePostRequestToEndPoint(payLoad, yammerUserAuthDecisionUrl))
{
// Reset the user Code
this.userCode = decisionPostWebResponse.ResponseUri.Query;
}
}
// App should have been granted access at this point if it did not already have access.
// Now check whether the code is present in the query string
if (this.userCode.IndexOf("?code=") < 0)
{
throw new ArgumentException(Properties.ErrorMessges.UnableToLogin);
}
this.userCode = this.userCode.Replace("?code=", string.Empty);
}
}
}
/// <summary>
/// Get Yammer Authenticity Token
/// </summary>
/// <param name="rawHtml">The Yammer response that was got after posting to yammer endpoint</param>
/// <returns>The Yammer authenticity token</returns>
private string GetAuthenticityToken(string rawHtml)
{
string result = string.Empty;
int at = rawHtml.IndexOf("<meta name=\"authenticity_token\" id=\"authenticity_token\"");
if (at > -1)
{
// Get the authenticity token string
int et = rawHtml.IndexOf("/>", at + 1);
string tokenText = rawHtml.Substring(at, et - at);
// Get the token value
int ts = tokenText.IndexOf("content=");
int es = tokenText.LastIndexOf("\"");
result = tokenText.Substring(ts + 9, es - ts - 9);
}
return result;
}
/// <summary>
/// Perform a get request to an endpoint and return the Http response
/// </summary>
/// <param name="endPoint">The endpoint to make the request</param>
/// <param name="addCookies">Should cookies be added to the request</param>
/// <returns>The Http Web Response</returns>
private HttpWebResponse MakeGetRequestToEndPoint(string endPoint, bool addCookies = false)
{
HttpWebRequest webRequest = WebRequest.CreateHttp(endPoint);
webRequest.Method = "GET";
if (addCookies)
{
webRequest.CookieContainer = this.cookieContainer;
}
return (HttpWebResponse)webRequest.GetResponse();
}
/// <summary>
/// Read the cookies from the web response object and store it in the cookie container instance variable
/// </summary>
/// <param name="webResponse">The Web Response object</param>
private void SetCookies(HttpWebResponse webResponse)
{
const string YAMTRAK_COOKIE = "yamtrak_id";
const string SESSION_COOKIE = "_workfeed_session_id";
const string LOGIN_CSRF_TOKEN_COOKIE = "login_csrf_token";
string cookies = webResponse.Headers["Set-Cookie"];
if (string.IsNullOrEmpty(cookies))
{
this.cookieContainer = new CookieContainer();
}
else
{
// Split the cookie based on , and ;
string[] sepChar = new string[2];
sepChar[0] = ",";
sepChar[1] = ";";
string[] cookieArray = cookies.Split(sepChar, StringSplitOptions.None);
// Declare variables to hold the different types of cookies
string login_csrf_token = string.Empty;
string yammerTrakToken = string.Empty;
string sessionToken = string.Empty;
// Parse the cookie array and store the cookies in the array
for (int i = 0; i < cookieArray.Length; i++)
{
if (cookieArray[i].IndexOf(YAMTRAK_COOKIE) >= 0)
{
yammerTrakToken = cookieArray[i];
}
if (cookieArray[i].IndexOf(SESSION_COOKIE) >= 0)
{
sessionToken = cookieArray[i];
}
if (cookieArray[i].IndexOf(LOGIN_CSRF_TOKEN_COOKIE) >= 0)
{
login_csrf_token = cookieArray[i];
}
}
// Create the cookie container
this.cookieContainer = new CookieContainer();
// Get the value for each of the cookie and add it to the cookie container
if (!string.IsNullOrWhiteSpace(yammerTrakToken))
{
yammerTrakToken = yammerTrakToken.Substring(YAMTRAK_COOKIE.Length + 1);
this.cookieContainer.Add(new Cookie(YAMTRAK_COOKIE, yammerTrakToken, "/", "www.yammer.com"));
}
if (!string.IsNullOrWhiteSpace(sessionToken))
{
sessionToken = sessionToken.Substring(SESSION_COOKIE.Length + 1);
this.cookieContainer.Add(new Cookie(SESSION_COOKIE, sessionToken, "/", "www.yammer.com"));
}
if (!string.IsNullOrWhiteSpace(login_csrf_token))
{
login_csrf_token = login_csrf_token.Substring(LOGIN_CSRF_TOKEN_COOKIE.Length + 1);
this.cookieContainer.Add(new Cookie(LOGIN_CSRF_TOKEN_COOKIE, login_csrf_token, "/", "www.yammer.com"));
}
}
}
/// <summary>
/// Make a post request to an endpoint and return the result
/// </summary>
/// <param name="postBody">The post request payload</param>
/// <param name="endPoint">The endpoint</param>
/// <returns>The response got from the server</returns>
private HttpWebResponse MakePostRequestToEndPoint(string postBody, string endPoint)
{
string responseString = string.Empty;
HttpWebRequest webRequest = WebRequest.CreateHttp(endPoint);
webRequest.Method = "POST";
webRequest.CookieContainer = this.cookieContainer;
webRequest.ContentType = "application/x-www-form-urlencoded";
SessionHelper.WritePayLoadToWebRequest(webRequest, postBody);
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
return webResponse;
}
/// <summary>
/// Get Response as string
/// </summary>
/// <param name="webResponse">The http web response object</param>
/// <returns>The web response string</returns>
/// <remarks>The Http Response object would be disposed after use</remarks>
private string GetResponseAsString(HttpWebResponse webResponse)
{
string responseString = string.Empty;
using (webResponse)
{
responseString = SessionHelper.ConvertResponseStreamToString(webResponse, Encoding.UTF8);
}
return responseString;
}
/// <summary>
/// Gets the user code.
/// </summary>
/// <param name="userCode">The user code.</param>
/// <exception cref="System.TimeoutException">Waiting for login page load.
/// or
/// Waiting for post login page load.</exception>
private void GetBearerToken(string userCode)
{
string formatUri = string.Format("https://www.yammer.com/oauth2/access_token.json?client_id={0}&client_secret={1}&code={2}", this.clientId, this.clientSecret, userCode);
Uri yammerUri = new Uri(formatUri);
WebRequest webRequest = WebRequest.Create(yammerUri);
webRequest.Method = "GET";
using (WebResponse response = webRequest.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
DataContractJsonSerializer seralizer = new DataContractJsonSerializer(typeof(Model.JSON.Yammer.AccessTokenResponse));
Model.JSON.Yammer.AccessTokenResponse accessTokenResponse = (Model.JSON.Yammer.AccessTokenResponse)seralizer.ReadObject(responseStream);
if (string.IsNullOrWhiteSpace(accessTokenResponse.access_token.token))
{
throw new InvalidOperationException("Unable to extract Yammer.com authorization bearer token.");
}
// Set the bearer token
this.Token = accessTokenResponse.access_token.token;
}
}
}
/// <summary>
/// Internal logout.
/// </summary>
/// <param name="address">The address.</param>
private void InternalLogout(string address)
{
string formatUri = string.Format("{0}/logout?from=nav", address);
Uri yammerUri = new Uri(formatUri);
// Create request
var request = HttpWebRequest.CreateHttp(yammerUri);
// POST
request.Method = "POST";
// Set the cookie container
request.CookieContainer = this.cookieContainer;
// Sent the request body
request.ContentType = "application/x-www-form-urlencoded";
string requestBody = string.Format(
"authenticity_token={0}&_method=delete",
HttpUtility.UrlEncode(this.AuthenticityToken));
byte[] requestBodyUTF8 = Encoding.UTF8.GetBytes(requestBody);
// Set the length before writing the request steam.
request.ContentLength = requestBody.Length;
// Write the request stream
using (var requestStream = request.GetRequestStream())
{
using (StreamWriter streamWrite = new StreamWriter(requestStream))
{
streamWrite.Write(requestBody);
}
}
// Make the request
using (var response = request.GetResponse())
{
// Always read the response
using (Stream responseStream = response.GetResponseStream())
{
}
}
}
#endregion
}
В приведенном выше коде замените идентификатор клиента, секрет клиента, адрес электронной почты и пароль. Затем вы можете использовать метод подключения, чтобы получить токен носителя и отключиться, чтобы выйти из yammer. Недавно yammer изменил количество файлов cookie, которые передавались туда и обратно, и я исправил проблему.
person
user3634665
schedule
20.08.2014