Je vyžadována podpora jazyka JavaScript
Některé stránky na tomto webu vyžadují podporu jazyka JavaScript. Váš webový prohlížeč jazyk JavaScript nepodporuje nebo jazyk JavaScript není povolen.
Chcete-li zjistit, zda webový prohlížeč podporuje jazyk JavaScript nebo jazyk JavaScript chcete povolit, přečtěte si nápovědu k vašemu webovému prohlížeči.
LiveAuthClient.cs
Download fileToto je zdrojový kód souboru LiveAuthClient.cs
Windows Live ID (former Microsoft Account) authentication (using Live Connect REST API).
using System;
using System.IO;
using System.Net;
using System.Web;
using System.Web.UI;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
namespace WindowsLive
{
[System.Diagnostics.DebuggerDisplay("UserID = {UserID}, FullName = {FullName}, FirstName = {FirstName}, LastName = {LastName}, Gender = {Gender}, Locale = {Locale}")]
public sealed class LiveAuthUser
{
#region member varible and default property initialization
public string UserID { get; private set; }
public string FullName { get; private set; }
public string FirstName { get; private set; }
public string LastName { get; private set; }
public string Gender { get; private set; }
public string Locale { get; private set; }
#endregion
#region constructors and destructors
internal LiveAuthUser(string userID, string fullName, string firstName, string lastName, string gender, string locale)
{
this.UserID = userID;
this.FullName = fullName;
this.FirstName = firstName;
this.LastName = lastName;
this.Gender = gender;
this.Locale = locale;
}
#endregion
}
public class LiveAuthException : Exception
{
#region member varible and default property initialization
public string ErrorCode { get; private set; }
#endregion
#region constructors and destructors
public LiveAuthException() { }
public LiveAuthException(string errorCode, string message)
: base(message)
{
this.ErrorCode = errorCode;
}
public LiveAuthException(string errorCode, string message, Exception innerException)
: base(message, innerException)
{
this.ErrorCode = errorCode;
}
#endregion
#region action methods
public override string ToString()
{
return this.ErrorCode + ": " + base.ToString();
}
#endregion
}
public class LiveAuthClient
{
#region member types declaration
private enum DisplayType
{
Popup,
Touch,
}
private class RequestAccessTokenResults
{
#region member varible and default property initialization
public string AccessToken { get; private set; }
public DateTimeOffset Expires { get; internal set; }
public IEnumerable<string> Scopes { get; internal set; }
public Exception Error { get; private set; }
#endregion
#region constructors and destructors
public RequestAccessTokenResults(string accessToken, DateTimeOffset expires, IEnumerable<string> scopes)
{
this.AccessToken = accessToken;
this.Expires = expires;
this.Scopes = scopes;
}
public RequestAccessTokenResults(Exception error)
{
this.Error = error;
}
#endregion
}
private class RequestUserInfoResults
{
#region member varible and default property initialization
public LiveAuthUser User { get; private set; }
public Exception Error { get; private set; }
#endregion
#region constructors and destructors
public RequestUserInfoResults(LiveAuthUser user)
{
this.User = user;
}
public RequestUserInfoResults(Exception error)
{
this.Error = error;
}
#endregion
}
[DataContract]
private class AuthToken
{
[DataMember(Name = AuthConstants.AccessToken)]
public string AccessToken { get; private set; }
[DataMember(Name = AuthConstants.ExpiresIn)]
public string ExpiresIn { get; private set; }
[DataMember(Name = AuthConstants.Scope)]
public string Scope { get; private set; }
}
[DataContract]
private class AuthUser
{
[DataMember(Name = AuthConstants.ID)]
public string ID { get; set; }
[DataMember(Name = AuthConstants.Name)]
public string Name { get; set; }
[DataMember(Name = AuthConstants.FirstName)]
public string FirstName { get; set; }
[DataMember(Name = AuthConstants.LastName)]
public string LastName { get; set; }
[DataMember(Name = AuthConstants.Gender)]
public string Gender { get; set; }
[DataMember(Name = AuthConstants.Locale)]
public string Locale { get; set; }
}
[DataContract]
private class AuthError
{
[DataMember(Name = AuthConstants.Error)]
public string ErrorCode { get; private set; }
[DataMember(Name = AuthConstants.ErrorDescription)]
public string ErrorDescription { get; private set; }
}
private static class AuthConstants
{
#region constants
public const string AccessToken = "access_token";
public const string ExpiresIn = "expires_in";
public const string Scope = "scope";
public const string Logout = "logout";
public const string ID = "id";
public const string Name = "name";
public const string FirstName = "first_name";
public const string LastName = "last_name";
public const string Gender = "gender";
public const string Locale = "locale";
public const string Error = "error";
public const string ErrorDescription = "error_description";
#endregion
}
#endregion
#region constants
private const string wlCookie = "wl_auth";
private const string ConsentEndpoint = "https://oauth.live.com";
private const string AuthorizeUrlTemplate = "{0}/authorize?client_id={1}&redirect_uri={2}&scope={3}&response_type=code&locale={4}&display={5}&state={6}";
private const string UserInfoUrlTemplate = "https://apis.live.net/v5.0/me?access_token={0}";
private const string AuthCodePostBodyTemplate = "client_id={0}&code={1}&redirect_uri={2}&client_secret={3}&grant_type=authorization_code";
private const string CreateSessionState = "create_session";
private const DisplayType Display = DisplayType.Popup;
private static readonly string[] DefaultScopes = new[] { "wl.signin" };
private static readonly char[] ScopeSeparators = new[] { ' ', ',' };
#endregion
#region member varible and default property initialization
private readonly string ClientId;
private readonly string ClientSecret;
private readonly string RedirectUri;
private IEnumerable<string> RequiredScopes;
private bool IsInitialized;
private string AccessToken;
private DateTimeOffset Expires;
private IEnumerable<string> Scopes;
#endregion
#region constructors and destructors
public LiveAuthClient(string clientId, string clientSecret, string redirectUri, IEnumerable<string> requiredScopes)
{
if (clientId == null)
{
throw new ArgumentNullException("clientId");
}
if (clientId.Length == 0)
{
throw new ArgumentException("clientId is empty.", "clientId");
}
if (clientSecret == null)
{
throw new ArgumentNullException("clientSecret");
}
if (clientSecret.Length == 0)
{
throw new ArgumentException("clientSecret is empty.", "clientSecret");
}
if (redirectUri == null)
{
throw new ArgumentNullException("redirectUri");
}
if (redirectUri.Length == 0)
{
throw new ArgumentException("redirectUri is empty.", "redirectUri");
}
this.ClientId = clientId;
this.ClientSecret = clientSecret;
this.RedirectUri = redirectUri;
this.RequiredScopes = requiredScopes ?? DefaultScopes;
}
public LiveAuthClient(string clientId, string clientSecret, string redirectUri) : this(clientId, clientSecret, redirectUri, null) { }
#endregion
#region action methods
public LiveAuthUser GetUserInfo(Page page)
{
if (page == null)
{
throw new ArgumentNullException("page");
}
InitializeInternal(page);
if (this.AccessToken != null)
{
var results = RequestUserInfo(this.AccessToken);
if (results.User != null)
{
return results.User;
}
}
return null;
}
public static void SignOut()
{
var cookie = new HttpCookie(wlCookie);
cookie[AuthConstants.Logout] = "1";
HttpContext.Current.Response.Cookies.Remove(wlCookie);
HttpContext.Current.Response.Cookies.Add(cookie);
}
public static void ProcessCallback(string clientId, string clientSecret, string redirectUri)
{
var client = new LiveAuthClient(clientId, clientSecret, redirectUri);
client.OnAuthenticateCompleted(HttpContext.Current.Request.Url);
}
#endregion
#region property getters/setters
public string LoginUrl
{
get
{
return BuildLoginUrl(this.ClientId, this.RedirectUri, this.RequiredScopes, false, null);
}
}
#endregion
#region private member functions
private void InitializeInternal(Page page)
{
if (this.IsInitialized)
{
return;
}
this.IsInitialized = true;
HttpContext context = HttpContext.Current;
HttpCookie cookie = context.Request.Cookies[wlCookie];
bool isLiveSessionCreated = cookie != null;
if (isLiveSessionCreated)
{
string accessToken = cookie[AuthConstants.AccessToken];
if (!string.IsNullOrEmpty(accessToken))
{
DateTimeOffset expires = DateTimeOffset.FromFileTime(Int64.Parse(cookie[AuthConstants.ExpiresIn]));
//Check Expiration
if (expires > DateTimeOffset.UtcNow.Add(new TimeSpan(0, 0, 60)))
{
this.AccessToken = accessToken;
this.Scopes = ParseScopeString(cookie[AuthConstants.Scope]);
this.Expires = expires;
return;
}
isLiveSessionCreated = false;
}
if (cookie[AuthConstants.Logout] == "1") //Run logout script
{
page.ClientScript.RegisterClientScriptBlock(page.GetType(), "logout", "logoutWindowsLive();", true);
SetLiveAuthCookie(); //Create empty cookie
return;
}
}
if (!OnAuthenticateCompleted(HttpContext.Current.Request.Url) && !isLiveSessionCreated)
{
//Silent authentication
context.Response.Redirect(BuildLoginUrl(this.ClientId, this.RedirectUri, this.RequiredScopes, true, CreateSessionState));
}
}
private bool OnAuthenticateCompleted(Uri responseUri)
{
var dictionary = ParseQueryString(responseUri.Query);
string code;
if (dictionary.TryGetValue("code", out code) && !string.IsNullOrEmpty(code))
{
var results = RequestAccessToken(code, this.ClientId, this.ClientSecret, this.RedirectUri);
if (results.Error == null)
{
this.AccessToken = results.AccessToken;
this.Expires = results.Expires;
this.Scopes = results.Scopes;
SetLiveAuthCookie();
return true;
}
}
string state;
if (dictionary.TryGetValue("state", out state) && state == CreateSessionState)
{
SetLiveAuthCookie(); //Create empty cookie
return true;
}
return false;
}
private void SetLiveAuthCookie()
{
var cookie = new HttpCookie(wlCookie);
if (this.AccessToken != null)
{
cookie[AuthConstants.AccessToken] = HttpUtility.UrlEncode(this.AccessToken);
cookie[AuthConstants.Scope] = HttpUtility.UrlPathEncode(BuildScopeString(this.Scopes));
cookie[AuthConstants.ExpiresIn] = this.Expires.ToFileTime().ToString();
}
HttpContext.Current.Response.Cookies.Remove(wlCookie);
HttpContext.Current.Response.Cookies.Add(cookie);
}
private static RequestAccessTokenResults RequestAccessToken(string code, string clientId, string clientSecret, string redirectUri)
{
Uri url = new Uri(ConsentEndpoint + "/token");
string body = string.Format(AuthCodePostBodyTemplate, HttpUtility.UrlEncode(clientId), code, redirectUri, HttpUtility.UrlEncode(clientSecret));
var request = WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
try
{
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(body);
}
var response = request.GetResponse();
if (response != null)
{
Stream responseStream = response.GetResponseStream();
if (responseStream != null)
{
try
{
var serializer = new DataContractJsonSerializer(typeof(AuthToken));
var token = (AuthToken)serializer.ReadObject(responseStream);
if (token != null)
{
return new RequestAccessTokenResults(token.AccessToken, DateTimeOffset.UtcNow.AddSeconds((double)Int64.Parse(token.ExpiresIn)), ParseScopeString(token.Scope));
}
}
catch (FormatException ex)
{
return new RequestAccessTokenResults(ex);
}
}
}
}
catch (WebException e)
{
var response = e.Response;
if (response != null)
{
Stream responseStream = response.GetResponseStream();
if (responseStream != null)
{
try
{
var serializer = new DataContractJsonSerializer(typeof(AuthError));
var error = (AuthError)serializer.ReadObject(response.GetResponseStream());
if (error != null)
{
return new RequestAccessTokenResults(new LiveAuthException(error.ErrorCode, error.ErrorDescription));
}
}
catch (FormatException ex)
{
return new RequestAccessTokenResults(ex);
}
}
}
}
catch (IOException)
{
//Ignore exception
}
return new RequestAccessTokenResults(new LiveAuthException("client_error", "A connection to the server could not be established."));
}
private static RequestUserInfoResults RequestUserInfo(string accessToken)
{
Uri url = new Uri(string.Format(UserInfoUrlTemplate, accessToken));
var request = WebRequest.Create(url);
try
{
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
if (response != null)
{
Stream responseStream = response.GetResponseStream();
if (responseStream != null)
{
try
{
var serializer = new DataContractJsonSerializer(typeof(AuthUser));
var user = (AuthUser)serializer.ReadObject(responseStream);
if (user != null)
{
return new RequestUserInfoResults(new LiveAuthUser(user.ID, user.Name, user.FirstName, user.LastName, user.Gender, user.Locale));
}
}
catch (FormatException ex)
{
return new RequestUserInfoResults(ex);
}
}
}
}
catch (WebException e)
{
var response = e.Response;
if (response != null)
{
Stream responseStream = response.GetResponseStream();
if (responseStream != null)
{
try
{
var serializer = new DataContractJsonSerializer(typeof(AuthError));
var error = (AuthError)serializer.ReadObject(response.GetResponseStream());
if (error != null)
{
return new RequestUserInfoResults(new LiveAuthException(error.ErrorCode, error.ErrorDescription));
}
}
catch (FormatException ex)
{
return new RequestUserInfoResults(ex);
}
}
}
}
catch (IOException)
{
//Ignore exception
}
return new RequestUserInfoResults(new LiveAuthException("client_error", "A connection to the server could not be established."));
}
private static string BuildLoginUrl(string clientId, string redirectUri, IEnumerable<string> scopes, bool silent, string state)
{
return string.Format(AuthorizeUrlTemplate,
ConsentEndpoint,
HttpUtility.UrlEncode(clientId),
HttpUtility.UrlEncode(redirectUri),
HttpUtility.UrlEncode(BuildScopeString(scopes)),
HttpUtility.UrlEncode(System.Globalization.CultureInfo.CurrentUICulture.ToString()),
silent ? "none" : HttpUtility.UrlEncode(Display.ToString().ToLowerInvariant()),
state);
}
private static string BuildScopeString(IEnumerable<string> scopes)
{
var sb = new System.Text.StringBuilder();
if (scopes != null)
{
foreach (string str in scopes)
{
sb.Append(str).Append(ScopeSeparators[0]);
}
}
return sb.ToString().TrimEnd(ScopeSeparators);
}
private static IEnumerable<string> ParseScopeString(string scopesString)
{
return new List<string>(scopesString.Split(ScopeSeparators, StringSplitOptions.RemoveEmptyEntries));
}
private static IDictionary<string, string> ParseQueryString(string query)
{
var dictionary = new Dictionary<string, string>();
if (!string.IsNullOrEmpty(query))
{
query = query.TrimStart(new char[] { '?', '#' });
if (string.IsNullOrEmpty(query))
{
return dictionary;
}
foreach (string str in query.Split(new char[] { '&' }))
{
string[] strArray2 = str.Split(new char[] { '=' });
if (strArray2.Length == 2)
{
dictionary.Add(strArray2[0], strArray2[1]);
}
}
}
return dictionary;
}
#endregion
}
}