summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2013-02-26 22:55:18 -0800
committerAndrew Arnott <andrewarnott@gmail.com>2013-02-26 22:55:18 -0800
commit6204dcf07f31b78478bc1ddb55a6ca9027617b67 (patch)
tree2b92fff13f9e253c9504e73b677ec61b352d9f38
parent38a1162c5cbaea035e655dc9accd92f9de5019ed (diff)
downloadDotNetOpenAuth-6204dcf07f31b78478bc1ddb55a6ca9027617b67.zip
DotNetOpenAuth-6204dcf07f31b78478bc1ddb55a6ca9027617b67.tar.gz
DotNetOpenAuth-6204dcf07f31b78478bc1ddb55a6ca9027617b67.tar.bz2
Fixes some OAuth 1 build breaks.
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs35
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs170
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/YammerConsumer.cs23
-rw-r--r--samples/OAuthConsumer/GoogleAddressBook.aspx.cs36
-rw-r--r--samples/OAuthConsumer/GoogleApps2Legged.aspx.cs22
-rw-r--r--samples/OAuthConsumer/OAuthConsumer.csproj3
-rw-r--r--samples/OAuthConsumer/SampleWcf.aspx.cs50
-rw-r--r--samples/OAuthConsumer/SignInWithTwitter.aspx.cs6
-rw-r--r--samples/OAuthConsumer/Twitter.aspx.cs46
-rw-r--r--samples/OAuthConsumer/Yammer.aspx.cs43
-rw-r--r--src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs9
-rw-r--r--src/DotNetOpenAuth.OAuth.Consumer/DotNetOpenAuth.OAuth.Consumer.csproj1
-rw-r--r--src/DotNetOpenAuth.OAuth.Consumer/OAuth/ServiceProviderDescription.cs (renamed from src/DotNetOpenAuth.OAuth/OAuth/ServiceProviderDescription.cs)0
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/DotNetOpenAuth.OAuth.ServiceProvider.csproj1
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs10
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProviderHostDescription.cs101
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuthReporting.cs4
-rw-r--r--src/DotNetOpenAuth.OAuth/DotNetOpenAuth.OAuth.csproj1
-rw-r--r--src/DotNetOpenAuth.OpenIdOAuth/OAuth/ServiceProviderOpenIdProvider.cs8
19 files changed, 311 insertions, 258 deletions
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs b/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs
index 2302837..def378f 100644
--- a/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs
+++ b/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.ApplicationBlock {
using System;
using System.Collections.Generic;
+ using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.IO;
@@ -19,6 +20,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
+ using System.Web;
using System.Xml;
using System.Xml.Linq;
using DotNetOpenAuth.Messaging;
@@ -66,6 +68,18 @@ namespace DotNetOpenAuth.ApplicationBlock {
private static readonly Uri GetContactsEndpoint = new Uri("http://www.google.com/m8/feeds/contacts/default/full/");
/// <summary>
+ /// Initializes a new instance of the <see cref="GoogleConsumer"/> class.
+ /// </summary>
+ public GoogleConsumer() {
+ this.ServiceProvider = ServiceDescription;
+ this.ConsumerKey = ConfigurationManager.AppSettings["googleConsumerKey"];
+ this.ConsumerSecret = ConfigurationManager.AppSettings["googleConsumerSecret"];
+ this.TemporaryCredentialStorage = HttpContext.Current != null
+ ? (ITemporaryCredentialStorage)new CookieTemporaryCredentialStorage()
+ : new MemoryTemporaryCredentialStorage();
+ }
+
+ /// <summary>
/// The many specific authorization scopes Google offers.
/// </summary>
[Flags]
@@ -151,19 +165,23 @@ namespace DotNetOpenAuth.ApplicationBlock {
Maps = 0x8000,
}
- public GoogleConsumer() {
+ /// <summary>
+ /// Gets the scope URI in Google's format.
+ /// </summary>
+ /// <param name="scope">The scope, which may include one or several Google applications.</param>
+ /// <returns>A space-delimited list of URIs for the requested Google applications.</returns>
+ public static string GetScopeUri(Applications scope) {
+ return string.Join(" ", Util.GetIndividualFlags(scope).Select(app => DataScopeUris[(Applications)app]).ToArray());
}
/// <summary>
/// Requests authorization from Google to access data from a set of Google applications.
/// </summary>
- /// <param name="consumer">The Google consumer previously constructed using <see cref="CreateWebConsumer" /> or <see cref="CreateDesktopConsumer" />.</param>
/// <param name="requestedAccessScope">The requested access scope.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// A task that completes with the asynchronous operation.
/// </returns>
- /// <exception cref="System.ArgumentNullException">consumer</exception>
public Task<Uri> RequestUserAuthorizationAsync(Applications requestedAccessScope, CancellationToken cancellationToken = default(CancellationToken)) {
var extraParameters = new Dictionary<string, string> {
{ "scope", GetScopeUri(requestedAccessScope) },
@@ -175,7 +193,6 @@ namespace DotNetOpenAuth.ApplicationBlock {
/// <summary>
/// Gets the Gmail address book's contents.
/// </summary>
- /// <param name="consumer">The Google consumer.</param>
/// <param name="accessToken">The access token previously retrieved.</param>
/// <param name="maxResults">The maximum number of entries to return. If you want to receive all of the contacts, rather than only the default maximum, you can specify a very large number here.</param>
/// <param name="startIndex">The 1-based index of the first result to be retrieved (for paging).</param>
@@ -183,7 +200,6 @@ namespace DotNetOpenAuth.ApplicationBlock {
/// <returns>
/// An XML document returned by Google.
/// </returns>
- /// <exception cref="System.ArgumentNullException">consumer</exception>
public async Task<XDocument> GetContactsAsync(AccessToken accessToken, int maxResults = 25, int startIndex = 1, CancellationToken cancellationToken = default(CancellationToken)) {
// Enable gzip compression. Google only compresses the response for recognized user agent headers. - Mike Lim
var handler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip };
@@ -244,14 +260,5 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
}
-
- /// <summary>
- /// Gets the scope URI in Google's format.
- /// </summary>
- /// <param name="scope">The scope, which may include one or several Google applications.</param>
- /// <returns>A space-delimited list of URIs for the requested Google applications.</returns>
- public static string GetScopeUri(Applications scope) {
- return string.Join(" ", Util.GetIndividualFlags(scope).Select(app => DataScopeUris[(Applications)app]).ToArray());
- }
}
}
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs b/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs
index 7bbfaa1..bb6f9d3 100644
--- a/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs
+++ b/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs
@@ -30,7 +30,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
/// <summary>
/// A consumer capable of communicating with Twitter.
/// </summary>
- public static class TwitterConsumer {
+ public class TwitterConsumer : Consumer {
/// <summary>
/// The description of Twitter's OAuth protocol URIs for use with actually reading/writing
/// a user's private Twitter data.
@@ -64,19 +64,36 @@ namespace DotNetOpenAuth.ApplicationBlock {
private static readonly Uri VerifyCredentialsEndpoint = new Uri("http://api.twitter.com/1/account/verify_credentials.xml");
- private class HostFactories : IHostFactories {
- private static readonly IHostFactories underlyingFactories = new DefaultOAuthHostFactories();
-
- public HttpMessageHandler CreateHttpMessageHandler() {
- return new WebRequestHandler();
- }
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TwitterConsumer"/> class.
+ /// </summary>
+ public TwitterConsumer() {
+ this.ServiceProvider = ServiceDescription;
+ this.ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
+ this.ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
+ this.TemporaryCredentialStorage = HttpContext.Current != null
+ ? (ITemporaryCredentialStorage)new CookieTemporaryCredentialStorage()
+ : new MemoryTemporaryCredentialStorage();
+ }
- public HttpClient CreateHttpClient(HttpMessageHandler handler = null) {
- var client = underlyingFactories.CreateHttpClient(handler);
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TwitterConsumer"/> class.
+ /// </summary>
+ /// <param name="consumerKey">The consumer key.</param>
+ /// <param name="consumerSecret">The consumer secret.</param>
+ public TwitterConsumer(string consumerKey, string consumerSecret)
+ : this() {
+ this.ConsumerKey = consumerKey;
+ this.ConsumerSecret = consumerSecret;
+ }
- // Twitter can't handle the Expect 100 Continue HTTP header.
- client.DefaultRequestHeaders.ExpectContinue = false;
- return client;
+ /// <summary>
+ /// Gets a value indicating whether the Twitter consumer key and secret are set in the web.config file.
+ /// </summary>
+ public static bool IsTwitterConsumerConfigured {
+ get {
+ return !string.IsNullOrEmpty(ConfigurationManager.AppSettings["twitterConsumerKey"]) &&
+ !string.IsNullOrEmpty(ConfigurationManager.AppSettings["twitterConsumerSecret"]);
}
}
@@ -86,7 +103,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
if (IsTwitterConsumerConfigured) {
ITemporaryCredentialStorage storage = forWeb ? (ITemporaryCredentialStorage)new CookieTemporaryCredentialStorage() : new MemoryTemporaryCredentialStorage();
return new Consumer(consumerKey, consumerSecret, ServiceDescription, storage) {
- HostFactories = new HostFactories(),
+ HostFactories = new TwitterHostFactories(),
};
} else {
throw new InvalidOperationException("No Twitter OAuth consumer key and secret could be found in web.config AppSettings.");
@@ -94,17 +111,55 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
/// <summary>
- /// Gets a value indicating whether the Twitter consumer key and secret are set in the web.config file.
+ /// Prepares a redirect that will send the user to Twitter to sign in.
/// </summary>
- public static bool IsTwitterConsumerConfigured {
- get {
- return !string.IsNullOrEmpty(ConfigurationManager.AppSettings["twitterConsumerKey"]) &&
- !string.IsNullOrEmpty(ConfigurationManager.AppSettings["twitterConsumerSecret"]);
+ /// <param name="forceNewLogin">if set to <c>true</c> the user will be required to re-enter their Twitter credentials even if already logged in to Twitter.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The redirect message.
+ /// </returns>
+ /// <remarks>
+ /// Call <see cref="OutgoingWebResponse.Send" /> or
+ /// <c>return StartSignInWithTwitter().<see cref="MessagingUtilities.AsActionResult">AsActionResult()</see></c>
+ /// to actually perform the redirect.
+ /// </remarks>
+ public static async Task<Uri> StartSignInWithTwitterAsync(bool forceNewLogin = false, CancellationToken cancellationToken = default(CancellationToken)) {
+ var redirectParameters = new Dictionary<string, string>();
+ if (forceNewLogin) {
+ redirectParameters["force_login"] = "true";
+ }
+ Uri callback = MessagingUtilities.GetRequestUrlFromContext().StripQueryArgumentsWithPrefix("oauth_");
+
+ var consumer = CreateConsumer();
+ consumer.ServiceProvider = SignInWithTwitterServiceDescription;
+ Uri redirectUrl = await consumer.RequestUserAuthorizationAsync(callback, cancellationToken: cancellationToken);
+ return redirectUrl;
+ }
+
+ /// <summary>
+ /// Checks the incoming web request to see if it carries a Twitter authentication response,
+ /// and provides the user's Twitter screen name and unique id if available.
+ /// </summary>
+ /// <param name="completeUrl">The URL that came back from the service provider to complete the authorization.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// A tuple with the screen name and Twitter unique user ID if successful; otherwise <c>null</c>.
+ /// </returns>
+ public static async Task<Tuple<string, int>> TryFinishSignInWithTwitterAsync(Uri completeUrl = null, CancellationToken cancellationToken = default(CancellationToken)) {
+ var consumer = CreateConsumer();
+ consumer.ServiceProvider = SignInWithTwitterServiceDescription;
+ var response = await consumer.ProcessUserAuthorizationAsync(completeUrl ?? HttpContext.Current.Request.Url, cancellationToken: cancellationToken);
+ if (response == null) {
+ return null;
}
+
+ string screenName = response.ExtraData["screen_name"];
+ int userId = int.Parse(response.ExtraData["user_id"]);
+ return Tuple.Create(screenName, userId);
}
- public static async Task<JArray> GetUpdatesAsync(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
- using (var httpClient = twitter.CreateHttpClient(accessToken)) {
+ public async Task<JArray> GetUpdatesAsync(AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
+ using (var httpClient = this.CreateHttpClient(accessToken)) {
using (var response = await httpClient.GetAsync(GetFriendTimelineStatusEndpoint, cancellationToken)) {
response.EnsureSuccessStatusCode();
string jsonString = await response.Content.ReadAsStringAsync();
@@ -114,8 +169,8 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
- public static async Task<XDocument> GetFavorites(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
- using (var httpClient = twitter.CreateHttpClient(accessToken)) {
+ public async Task<XDocument> GetFavorites(AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
+ using (var httpClient = this.CreateHttpClient(accessToken)) {
using (HttpResponseMessage response = await httpClient.GetAsync(GetFavoritesEndpoint, cancellationToken)) {
response.EnsureSuccessStatusCode();
return XDocument.Parse(await response.Content.ReadAsStringAsync());
@@ -123,7 +178,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
- public static async Task<XDocument> UpdateProfileBackgroundImageAsync(Consumer twitter, AccessToken accessToken, string image, bool tile, CancellationToken cancellationToken) {
+ public async Task<XDocument> UpdateProfileBackgroundImageAsync(AccessToken accessToken, string image, bool tile, CancellationToken cancellationToken) {
var imageAttachment = new StreamContent(File.OpenRead(image));
imageAttachment.Headers.ContentType = new MediaTypeHeaderValue("image/" + Path.GetExtension(image).Substring(1).ToLowerInvariant());
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, UpdateProfileBackgroundImageEndpoint);
@@ -132,7 +187,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
content.Add(new StringContent(tile.ToString().ToLowerInvariant()), "tile");
request.Content = content;
request.Headers.ExpectContinue = false;
- using (var httpClient = twitter.CreateHttpClient(accessToken)) {
+ using (var httpClient = this.CreateHttpClient(accessToken)) {
using (HttpResponseMessage response = await httpClient.SendAsync(request, cancellationToken)) {
response.EnsureSuccessStatusCode();
string responseString = await response.Content.ReadAsStringAsync();
@@ -141,19 +196,19 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
- public static Task<XDocument> UpdateProfileImageAsync(Consumer twitter, AccessToken accessToken, string pathToImage, CancellationToken cancellationToken = default(CancellationToken)) {
+ public Task<XDocument> UpdateProfileImageAsync(AccessToken accessToken, string pathToImage, CancellationToken cancellationToken = default(CancellationToken)) {
string contentType = "image/" + Path.GetExtension(pathToImage).Substring(1).ToLowerInvariant();
- return UpdateProfileImageAsync(twitter, accessToken, File.OpenRead(pathToImage), contentType, cancellationToken);
+ return this.UpdateProfileImageAsync(accessToken, File.OpenRead(pathToImage), contentType, cancellationToken);
}
- public static async Task<XDocument> UpdateProfileImageAsync(Consumer twitter, AccessToken accessToken, Stream image, string contentType, CancellationToken cancellationToken = default(CancellationToken)) {
+ public async Task<XDocument> UpdateProfileImageAsync(AccessToken accessToken, Stream image, string contentType, CancellationToken cancellationToken = default(CancellationToken)) {
var imageAttachment = new StreamContent(image);
imageAttachment.Headers.ContentType = new MediaTypeHeaderValue(contentType);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, UpdateProfileImageEndpoint);
var content = new MultipartFormDataContent();
content.Add(imageAttachment, "image", "twitterPhoto");
request.Content = content;
- using (var httpClient = twitter.CreateHttpClient(accessToken)) {
+ using (var httpClient = this.CreateHttpClient(accessToken)) {
using (HttpResponseMessage response = await httpClient.SendAsync(request, cancellationToken)) {
response.EnsureSuccessStatusCode();
string responseString = await response.Content.ReadAsStringAsync();
@@ -162,8 +217,8 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
- public static async Task<XDocument> VerifyCredentialsAsync(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
- using (var httpClient = twitter.CreateHttpClient(accessToken)) {
+ public async Task<XDocument> VerifyCredentialsAsync(AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
+ using (var httpClient = this.CreateHttpClient(accessToken)) {
using (var response = await httpClient.GetAsync(VerifyCredentialsEndpoint, cancellationToken)) {
response.EnsureSuccessStatusCode();
using (var stream = await response.Content.ReadAsStreamAsync()) {
@@ -173,57 +228,26 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
- public static async Task<string> GetUsername(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
- XDocument xml = await VerifyCredentialsAsync(twitter, accessToken, cancellationToken);
+ public async Task<string> GetUsername(AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
+ XDocument xml = await this.VerifyCredentialsAsync(accessToken, cancellationToken);
XPathNavigator nav = xml.CreateNavigator();
return nav.SelectSingleNode("/user/screen_name").Value;
}
- /// <summary>
- /// Prepares a redirect that will send the user to Twitter to sign in.
- /// </summary>
- /// <param name="forceNewLogin">if set to <c>true</c> the user will be required to re-enter their Twitter credentials even if already logged in to Twitter.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>
- /// The redirect message.
- /// </returns>
- /// <remarks>
- /// Call <see cref="OutgoingWebResponse.Send" /> or
- /// <c>return StartSignInWithTwitter().<see cref="MessagingUtilities.AsActionResult">AsActionResult()</see></c>
- /// to actually perform the redirect.
- /// </remarks>
- public static async Task<Uri> StartSignInWithTwitterAsync(bool forceNewLogin = false, CancellationToken cancellationToken = default(CancellationToken)) {
- var redirectParameters = new Dictionary<string, string>();
- if (forceNewLogin) {
- redirectParameters["force_login"] = "true";
+ private class TwitterHostFactories : IHostFactories {
+ private static readonly IHostFactories underlyingFactories = new DefaultOAuthHostFactories();
+
+ public HttpMessageHandler CreateHttpMessageHandler() {
+ return new WebRequestHandler();
}
- Uri callback = MessagingUtilities.GetRequestUrlFromContext().StripQueryArgumentsWithPrefix("oauth_");
- var consumer = CreateConsumer();
- consumer.ServiceProvider = SignInWithTwitterServiceDescription;
- Uri redirectUrl = await consumer.RequestUserAuthorizationAsync(callback, cancellationToken: cancellationToken);
- return redirectUrl;
- }
+ public HttpClient CreateHttpClient(HttpMessageHandler handler = null) {
+ var client = underlyingFactories.CreateHttpClient(handler);
- /// <summary>
- /// Checks the incoming web request to see if it carries a Twitter authentication response,
- /// and provides the user's Twitter screen name and unique id if available.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>
- /// A tuple with the screen name and Twitter unique user ID if successful; otherwise <c>null</c>.
- /// </returns>
- public static async Task<Tuple<string, int>> TryFinishSignInWithTwitterAsync(Uri completeUrl, CancellationToken cancellationToken = default(CancellationToken)) {
- var consumer = CreateConsumer();
- consumer.ServiceProvider = SignInWithTwitterServiceDescription;
- var response = await consumer.ProcessUserAuthorizationAsync(completeUrl, cancellationToken: cancellationToken);
- if (response == null) {
- return null;
+ // Twitter can't handle the Expect 100 Continue HTTP header.
+ client.DefaultRequestHeaders.ExpectContinue = false;
+ return client;
}
-
- string screenName = response.ExtraData["screen_name"];
- int userId = int.Parse(response.ExtraData["user_id"]);
- return Tuple.Create(screenName, userId);
}
}
}
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/YammerConsumer.cs b/samples/DotNetOpenAuth.ApplicationBlock/YammerConsumer.cs
index 4bcb112..1dff5b6 100644
--- a/samples/DotNetOpenAuth.ApplicationBlock/YammerConsumer.cs
+++ b/samples/DotNetOpenAuth.ApplicationBlock/YammerConsumer.cs
@@ -13,12 +13,13 @@ namespace DotNetOpenAuth.ApplicationBlock {
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+ using System.Web;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth;
using DotNetOpenAuth.OAuth.ChannelElements;
using DotNetOpenAuth.OAuth.Messages;
- public static class YammerConsumer {
+ public class YammerConsumer : Consumer {
/// <summary>
/// The Consumer to use for accessing Google data APIs.
/// </summary>
@@ -28,6 +29,15 @@ namespace DotNetOpenAuth.ApplicationBlock {
"https://www.yammer.com/oauth/authorize",
"https://www.yammer.com/oauth/access_token");
+ public YammerConsumer() {
+ this.ServiceProvider = ServiceDescription;
+ this.ConsumerKey = ConfigurationManager.AppSettings["YammerConsumerKey"];
+ this.ConsumerSecret = ConfigurationManager.AppSettings["YammerConsumerSecret"];
+ this.TemporaryCredentialStorage = HttpContext.Current != null
+ ? (ITemporaryCredentialStorage)new CookieTemporaryCredentialStorage()
+ : new MemoryTemporaryCredentialStorage();
+ }
+
/// <summary>
/// Gets a value indicating whether the Twitter consumer key and secret are set in the web.config file.
/// </summary>
@@ -37,16 +47,5 @@ namespace DotNetOpenAuth.ApplicationBlock {
!string.IsNullOrEmpty(ConfigurationManager.AppSettings["yammerConsumerSecret"]);
}
}
-
- public static Consumer CreateConsumer(bool forWeb = true) {
- string consumerKey = ConfigurationManager.AppSettings["yammerConsumerKey"];
- string consumerSecret = ConfigurationManager.AppSettings["yammerConsumerSecret"];
- if (IsConsumerConfigured) {
- ITemporaryCredentialStorage storage = forWeb ? (ITemporaryCredentialStorage)new CookieTemporaryCredentialStorage() : new MemoryTemporaryCredentialStorage();
- return new Consumer(consumerKey, consumerSecret, ServiceDescription, storage);
- } else {
- throw new InvalidOperationException("No Yammer OAuth consumer key and secret could be found in web.config AppSettings.");
- }
- }
}
}
diff --git a/samples/OAuthConsumer/GoogleAddressBook.aspx.cs b/samples/OAuthConsumer/GoogleAddressBook.aspx.cs
index 8a2a816..4eb4101 100644
--- a/samples/OAuthConsumer/GoogleAddressBook.aspx.cs
+++ b/samples/OAuthConsumer/GoogleAddressBook.aspx.cs
@@ -14,50 +14,34 @@
/// A page to demonstrate downloading a Gmail address book using OAuth.
/// </summary>
public partial class GoogleAddressBook : System.Web.UI.Page {
- private string AccessToken {
- get { return (string)Session["GoogleAccessToken"]; }
+ private AccessToken AccessToken {
+ get { return (AccessToken)Session["GoogleAccessToken"]; }
set { Session["GoogleAccessToken"] = value; }
}
- private InMemoryTokenManager TokenManager {
- get {
- var tokenManager = (InMemoryTokenManager)Application["GoogleTokenManager"];
- if (tokenManager == null) {
- string consumerKey = ConfigurationManager.AppSettings["googleConsumerKey"];
- string consumerSecret = ConfigurationManager.AppSettings["googleConsumerSecret"];
- if (!string.IsNullOrEmpty(consumerKey)) {
- tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
- Application["GoogleTokenManager"] = tokenManager;
- }
- }
-
- return tokenManager;
- }
- }
-
protected async void Page_Load(object sender, EventArgs e) {
- if (this.TokenManager != null) {
+ var google = new GoogleConsumer();
+ if (google.ConsumerKey != null) {
this.MultiView1.ActiveViewIndex = 1;
if (!IsPostBack) {
- var google = new WebConsumer(GoogleConsumer.ServiceDescription, this.TokenManager);
-
// Is Google calling back with authorization?
- var accessTokenResponse = await google.ProcessUserAuthorizationAsync(new HttpRequestWrapper(Request), Response.ClientDisconnectedToken);
+ var accessTokenResponse = await google.ProcessUserAuthorizationAsync(this.Request.Url);
if (accessTokenResponse != null) {
this.AccessToken = accessTokenResponse.AccessToken;
- } else if (this.AccessToken == null) {
+ } else if (this.AccessToken.Token == null) {
// If we don't yet have access, immediately request it.
- await GoogleConsumer.RequestAuthorizationAsync(google, GoogleConsumer.Applications.Contacts);
+ Uri redirectUri = await google.RequestUserAuthorizationAsync(GoogleConsumer.Applications.Contacts);
+ this.Response.RedirectLocation = redirectUri.AbsoluteUri;
}
}
}
}
protected async void getAddressBookButton_Click(object sender, EventArgs e) {
- var google = new WebConsumer(GoogleConsumer.ServiceDescription, this.TokenManager);
+ var google = new GoogleConsumer();
- XDocument contactsDocument = await GoogleConsumer.GetContactsAsync(google, this.AccessToken, 5, 1, Response.ClientDisconnectedToken);
+ XDocument contactsDocument = await google.GetContactsAsync(this.AccessToken, 5, 1, Response.ClientDisconnectedToken);
var contacts = from entry in contactsDocument.Root.Elements(XName.Get("entry", "http://www.w3.org/2005/Atom"))
select new { Name = entry.Element(XName.Get("title", "http://www.w3.org/2005/Atom")).Value, Email = entry.Element(XName.Get("email", "http://schemas.google.com/g/2005")).Attribute("address").Value };
StringBuilder tableBuilder = new StringBuilder();
diff --git a/samples/OAuthConsumer/GoogleApps2Legged.aspx.cs b/samples/OAuthConsumer/GoogleApps2Legged.aspx.cs
index af490cf..cff24ea 100644
--- a/samples/OAuthConsumer/GoogleApps2Legged.aspx.cs
+++ b/samples/OAuthConsumer/GoogleApps2Legged.aspx.cs
@@ -12,26 +12,10 @@
using DotNetOpenAuth.OAuth.Messages;
public partial class GoogleApps2Legged : System.Web.UI.Page {
- private InMemoryTokenManager TokenManager {
- get {
- var tokenManager = (InMemoryTokenManager)Application["GoogleTokenManager"];
- if (tokenManager == null) {
- string consumerKey = ConfigurationManager.AppSettings["googleConsumerKey"];
- string consumerSecret = ConfigurationManager.AppSettings["googleConsumerSecret"];
- if (!string.IsNullOrEmpty(consumerKey)) {
- tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
- Application["GoogleTokenManager"] = tokenManager;
- }
- }
-
- return tokenManager;
- }
- }
-
protected async void Page_Load(object sender, EventArgs e) {
- var google = new WebConsumer(GoogleConsumer.ServiceDescription, this.TokenManager);
- string accessToken = await google.RequestNewClientAccountAsync(cancellationToken: Response.ClientDisconnectedToken);
- using (var httpClient = google.CreateHttpClient(accessToken)) {
+ var google = new GoogleConsumer();
+ var accessToken = await google.RequestNewClientAccountAsync();
+ using (var httpClient = google.CreateHttpClient(accessToken.AccessToken)) {
await httpClient.GetAsync("http://someUri", Response.ClientDisconnectedToken);
}
}
diff --git a/samples/OAuthConsumer/OAuthConsumer.csproj b/samples/OAuthConsumer/OAuthConsumer.csproj
index 12553c3..94bed9c 100644
--- a/samples/OAuthConsumer/OAuthConsumer.csproj
+++ b/samples/OAuthConsumer/OAuthConsumer.csproj
@@ -107,9 +107,6 @@
</None>
</ItemGroup>
<ItemGroup>
- <Compile Include="..\DotNetOpenAuth.ApplicationBlock\InMemoryTokenManager.cs">
- <Link>Code\InMemoryTokenManager.cs</Link>
- </Compile>
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
diff --git a/samples/OAuthConsumer/SampleWcf.aspx.cs b/samples/OAuthConsumer/SampleWcf.aspx.cs
index 9c32f59..7ea5f62 100644
--- a/samples/OAuthConsumer/SampleWcf.aspx.cs
+++ b/samples/OAuthConsumer/SampleWcf.aspx.cs
@@ -24,9 +24,9 @@
public partial class SampleWcf : System.Web.UI.Page {
protected async void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
- if (Session["WcfTokenManager"] != null) {
- WebConsumer consumer = this.CreateConsumer();
- var accessTokenMessage = await consumer.ProcessUserAuthorizationAsync(new HttpRequestWrapper(Request), Response.ClientDisconnectedToken);
+ var consumer = this.CreateConsumer();
+ if (consumer.ConsumerKey != null) {
+ var accessTokenMessage = await consumer.ProcessUserAuthorizationAsync(this.Request.Url);
if (accessTokenMessage != null) {
Session["WcfAccessToken"] = accessTokenMessage.AccessToken;
this.authorizationLabel.Text = "Authorized! Access token: " + accessTokenMessage.AccessToken;
@@ -36,7 +36,7 @@
}
protected async void getAuthorizationButton_Click(object sender, EventArgs e) {
- WebConsumer consumer = this.CreateConsumer();
+ var consumer = this.CreateConsumer();
UriBuilder callback = new UriBuilder(Request.Url);
callback.Query = null;
string[] scopes = (from item in this.scopeList.Items.OfType<ListItem>()
@@ -44,11 +44,10 @@
select item.Value).ToArray();
string scope = string.Join("|", scopes);
var requestParams = new Dictionary<string, string> {
- { "scope", scope },
- };
- var response = await consumer.PrepareRequestUserAuthorizationAsync(callback.Uri, requestParams, null, Response.ClientDisconnectedToken);
- var responseMessage = await consumer.Channel.PrepareResponseAsync(response, Response.ClientDisconnectedToken);
- await responseMessage.SendAsync(new HttpResponseWrapper(Response), Response.ClientDisconnectedToken);
+ { "scope", scope },
+ };
+ Uri redirectUri = await consumer.RequestUserAuthorizationAsync(callback.Uri, requestParams);
+ this.Response.RedirectLocation = redirectUri.AbsoluteUri;
}
protected async void getNameButton_Click(object sender, EventArgs e) {
@@ -80,16 +79,15 @@
private async Task<T> CallServiceAsync<T>(Func<DataApiClient, T> predicate) {
DataApiClient client = new DataApiClient();
var serviceEndpoint = new MessageReceivingEndpoint(client.Endpoint.Address.Uri, HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.PostRequest);
- var accessToken = Session["WcfAccessToken"] as string;
- if (accessToken == null) {
+ var accessToken = (AccessToken)(Session["WcfAccessToken"] ?? default(AccessToken));
+ if (accessToken.Token == null) {
throw new InvalidOperationException("No access token!");
}
var httpRequest = new HttpRequestMessage(HttpMethod.Post, client.Endpoint.Address.Uri);
- using (WebConsumer consumer = this.CreateConsumer()) {
- using (var handler = consumer.CreateMessageHandler(accessToken)) {
- handler.ApplyAuthorization(httpRequest);
- }
+ var consumer = this.CreateConsumer();
+ using (var handler = consumer.CreateMessageHandler(accessToken)) {
+ handler.ApplyAuthorization(httpRequest);
}
HttpRequestMessageProperty httpDetails = new HttpRequestMessageProperty();
@@ -100,27 +98,17 @@
}
}
- private WebConsumer CreateConsumer() {
+ private Consumer CreateConsumer() {
string consumerKey = "sampleconsumer";
string consumerSecret = "samplesecret";
- var tokenManager = Session["WcfTokenManager"] as InMemoryTokenManager;
- if (tokenManager == null) {
- tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
- Session["WcfTokenManager"] = tokenManager;
- }
MessageReceivingEndpoint oauthEndpoint = new MessageReceivingEndpoint(
new Uri("http://localhost:65169/OAuth.ashx"),
HttpDeliveryMethods.PostRequest);
- WebConsumer consumer = new WebConsumer(
- new ServiceProviderDescription {
- RequestTokenEndpoint = oauthEndpoint,
- UserAuthorizationEndpoint = oauthEndpoint,
- AccessTokenEndpoint = oauthEndpoint,
- TamperProtectionElements = new DotNetOpenAuth.Messaging.ITamperProtectionChannelBindingElement[] {
- new HmacSha1SigningBindingElement(),
- },
- },
- tokenManager);
+ var consumer = new Consumer(
+ consumerKey,
+ consumerSecret,
+ new ServiceProviderDescription(oauthEndpoint.Location.AbsoluteUri, oauthEndpoint.Location.AbsoluteUri, oauthEndpoint.Location.AbsoluteUri),
+ new CookieTemporaryCredentialStorage());
return consumer;
}
diff --git a/samples/OAuthConsumer/SignInWithTwitter.aspx.cs b/samples/OAuthConsumer/SignInWithTwitter.aspx.cs
index f90d557..d34c0a5 100644
--- a/samples/OAuthConsumer/SignInWithTwitter.aspx.cs
+++ b/samples/OAuthConsumer/SignInWithTwitter.aspx.cs
@@ -19,7 +19,7 @@
this.MultiView1.ActiveViewIndex = 1;
if (!IsPostBack) {
- var tuple = await TwitterConsumer.TryFinishSignInWithTwitterAsync(Response.ClientDisconnectedToken);
+ var tuple = await TwitterConsumer.TryFinishSignInWithTwitterAsync();
if (tuple != null) {
string screenName = tuple.Item1;
int userId = tuple.Item2;
@@ -35,8 +35,8 @@
}
protected async void signInButton_Click(object sender, ImageClickEventArgs e) {
- var response = await TwitterConsumer.StartSignInWithTwitterAsync(this.forceLoginCheckbox.Checked, Response.ClientDisconnectedToken);
- await response.SendAsync();
+ Uri redirectUrl = await TwitterConsumer.StartSignInWithTwitterAsync(this.forceLoginCheckbox.Checked, Response.ClientDisconnectedToken);
+ this.Response.RedirectLocation = redirectUrl.AbsoluteUri;
}
}
} \ No newline at end of file
diff --git a/samples/OAuthConsumer/Twitter.aspx.cs b/samples/OAuthConsumer/Twitter.aspx.cs
index 6ff6993..e107928 100644
--- a/samples/OAuthConsumer/Twitter.aspx.cs
+++ b/samples/OAuthConsumer/Twitter.aspx.cs
@@ -14,51 +14,33 @@
using DotNetOpenAuth.OAuth;
public partial class Twitter : System.Web.UI.Page {
- private string AccessToken {
- get { return (string)Session["TwitterAccessToken"]; }
+ private AccessToken AccessToken {
+ get { return (AccessToken)Session["TwitterAccessToken"]; }
set { Session["TwitterAccessToken"] = value; }
}
- private InMemoryTokenManager TokenManager {
- get {
- var tokenManager = (InMemoryTokenManager)Application["TwitterTokenManager"];
- if (tokenManager == null) {
- string consumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
- string consumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
- if (!string.IsNullOrEmpty(consumerKey)) {
- tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
- Application["TwitterTokenManager"] = tokenManager;
- }
- }
-
- return tokenManager;
- }
- }
-
protected async void Page_Load(object sender, EventArgs e) {
- if (this.TokenManager != null) {
+ var twitter = new TwitterConsumer();
+ if (twitter.ConsumerKey != null) {
this.MultiView1.ActiveViewIndex = 1;
if (!IsPostBack) {
- var twitter = new WebConsumer(TwitterConsumer.ServiceDescription, this.TokenManager);
-
// Is Twitter calling back with authorization?
- var accessTokenResponse = await twitter.ProcessUserAuthorizationAsync(new HttpRequestWrapper(Request), Response.ClientDisconnectedToken);
+ var accessTokenResponse = await twitter.ProcessUserAuthorizationAsync(this.Request.Url);
if (accessTokenResponse != null) {
this.AccessToken = accessTokenResponse.AccessToken;
- } else if (this.AccessToken == null) {
+ } else {
// If we don't yet have access, immediately request it.
- var message = await twitter.PrepareRequestUserAuthorizationAsync(Response.ClientDisconnectedToken);
- var response = await twitter.Channel.PrepareResponseAsync(message, Response.ClientDisconnectedToken);
- await response.SendAsync();
+ Uri redirectUrl = await twitter.RequestUserAuthorizationAsync(MessagingUtilities.GetPublicFacingUrl());
+ this.Response.RedirectLocation = redirectUrl.AbsoluteUri;
}
}
}
}
protected async void downloadUpdates_Click(object sender, EventArgs e) {
- var twitter = new WebConsumer(TwitterConsumer.ServiceDescription, this.TokenManager);
- var statusesJson = await TwitterConsumer.GetUpdatesAsync(twitter, this.AccessToken, Response.ClientDisconnectedToken);
+ var twitter = new TwitterConsumer();
+ var statusesJson = await twitter.GetUpdatesAsync(this.AccessToken);
StringBuilder tableBuilder = new StringBuilder();
tableBuilder.Append("<table><tr><td>Name</td><td>Update</td></tr>");
@@ -83,13 +65,11 @@
return;
}
- var twitter = new WebConsumer(TwitterConsumer.ServiceDescription, this.TokenManager);
- XDocument imageResult = await TwitterConsumer.UpdateProfileImageAsync(
- twitter,
+ var twitter = new TwitterConsumer();
+ XDocument imageResult = await twitter.UpdateProfileImageAsync(
this.AccessToken,
this.profilePhoto.PostedFile.InputStream,
- this.profilePhoto.PostedFile.ContentType,
- Response.ClientDisconnectedToken);
+ this.profilePhoto.PostedFile.ContentType);
this.photoUploadedLabel.Visible = true;
}
}
diff --git a/samples/OAuthConsumer/Yammer.aspx.cs b/samples/OAuthConsumer/Yammer.aspx.cs
index 57169fc..b1031ae 100644
--- a/samples/OAuthConsumer/Yammer.aspx.cs
+++ b/samples/OAuthConsumer/Yammer.aspx.cs
@@ -11,48 +11,27 @@
using DotNetOpenAuth.OAuth;
public partial class Yammer : System.Web.UI.Page {
- private string RequestToken {
- get { return (string)ViewState["YammerRequestToken"]; }
- set { ViewState["YammerRequestToken"] = value; }
- }
-
- private string AccessToken {
- get { return (string)Session["YammerAccessToken"]; }
+ private AccessToken AccessToken {
+ get { return (AccessToken)Session["YammerAccessToken"]; }
set { Session["YammerAccessToken"] = value; }
}
- private InMemoryTokenManager TokenManager {
- get {
- var tokenManager = (InMemoryTokenManager)Application["YammerTokenManager"];
- if (tokenManager == null) {
- string consumerKey = ConfigurationManager.AppSettings["YammerConsumerKey"];
- string consumerSecret = ConfigurationManager.AppSettings["YammerConsumerSecret"];
- if (!string.IsNullOrEmpty(consumerKey)) {
- tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
- Application["YammerTokenManager"] = tokenManager;
- }
- }
-
- return tokenManager;
- }
- }
-
protected void Page_Load(object sender, EventArgs e) {
- if (this.TokenManager != null) {
+ var yammer = new YammerConsumer();
+ if (yammer.ConsumerKey != null) {
this.MultiView1.SetActiveView(this.BeginAuthorizationView);
}
}
protected void getYammerMessages_Click(object sender, EventArgs e) {
- var yammer = new WebConsumer(YammerConsumer.ServiceDescription, this.TokenManager);
+ var yammer = new YammerConsumer();
+
+ // TODO: code here
}
protected async void obtainAuthorizationButton_Click(object sender, EventArgs e) {
- var yammer = YammerConsumer.CreateConsumer(this.TokenManager);
- var tuple = await YammerConsumer.PrepareRequestAuthorizationAsync(yammer, Response.ClientDisconnectedToken);
- Uri popupWindowLocation = tuple.Item1;
- string requestToken = tuple.Item2;
- this.RequestToken = requestToken;
+ var yammer = new YammerConsumer();
+ Uri popupWindowLocation = await yammer.RequestUserAuthorizationAsync(MessagingUtilities.GetPublicFacingUrl());
string javascript = "window.open('" + popupWindowLocation.AbsoluteUri + "');";
this.Page.ClientScript.RegisterStartupScript(GetType(), "YammerPopup", javascript, true);
this.MultiView1.SetActiveView(this.CompleteAuthorizationView);
@@ -63,8 +42,8 @@
return;
}
- var yammer = YammerConsumer.CreateConsumer(this.TokenManager);
- var authorizationResponse = await YammerConsumer.CompleteAuthorizationAsync(yammer, this.RequestToken, this.yammerUserCode.Text, Response.ClientDisconnectedToken);
+ var yammer = new YammerConsumer();
+ var authorizationResponse = await yammer.ProcessUserAuthorizationAsync(this.yammerUserCode.Text);
if (authorizationResponse != null) {
this.accessTokenLabel.Text = HttpUtility.HtmlEncode(authorizationResponse.AccessToken);
this.MultiView1.SetActiveView(this.AuthorizationCompleteView);
diff --git a/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs
index 501b5b2..38abe4a 100644
--- a/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs
@@ -393,6 +393,15 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
+ /// Gets the public facing URL for the given incoming HTTP request.
+ /// </summary>
+ /// <returns>The URI that the outside world used to create this request.</returns>
+ public static Uri GetPublicFacingUrl() {
+ ErrorUtilities.VerifyHttpContext();
+ return GetPublicFacingUrl(new HttpRequestWrapper(HttpContext.Current.Request));
+ }
+
+ /// <summary>
/// Wraps a response message as an MVC <see cref="ActionResult"/> so it can be conveniently returned from an MVC controller's action method.
/// </summary>
/// <param name="response">The response message.</param>
diff --git a/src/DotNetOpenAuth.OAuth.Consumer/DotNetOpenAuth.OAuth.Consumer.csproj b/src/DotNetOpenAuth.OAuth.Consumer/DotNetOpenAuth.OAuth.Consumer.csproj
index fe14abc..173bb3e 100644
--- a/src/DotNetOpenAuth.OAuth.Consumer/DotNetOpenAuth.OAuth.Consumer.csproj
+++ b/src/DotNetOpenAuth.OAuth.Consumer/DotNetOpenAuth.OAuth.Consumer.csproj
@@ -29,6 +29,7 @@
<Compile Include="OAuth\OAuth1HttpMessageHandlerBase.cs" />
<Compile Include="OAuth\OAuth1PlainTextMessageHandler.cs" />
<Compile Include="OAuth\OAuth1RsaSha1HttpMessageHandler.cs" />
+ <Compile Include="OAuth\ServiceProviderDescription.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>
</SubType>
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ServiceProviderDescription.cs b/src/DotNetOpenAuth.OAuth.Consumer/OAuth/ServiceProviderDescription.cs
index e6a2b32..e6a2b32 100644
--- a/src/DotNetOpenAuth.OAuth/OAuth/ServiceProviderDescription.cs
+++ b/src/DotNetOpenAuth.OAuth.Consumer/OAuth/ServiceProviderDescription.cs
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/DotNetOpenAuth.OAuth.ServiceProvider.csproj b/src/DotNetOpenAuth.OAuth.ServiceProvider/DotNetOpenAuth.OAuth.ServiceProvider.csproj
index 059f025..fd2aa9e 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/DotNetOpenAuth.OAuth.ServiceProvider.csproj
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/DotNetOpenAuth.OAuth.ServiceProvider.csproj
@@ -32,6 +32,7 @@
<Compile Include="OAuth\ChannelElements\StandardTokenGenerator.cs" />
<Compile Include="OAuth\ChannelElements\TokenHandlingBindingElement.cs" />
<Compile Include="OAuth\ServiceProvider.cs" />
+ <Compile Include="OAuth\ServiceProviderHostDescription.cs" />
<Compile Include="OAuth\VerificationCodeFormat.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs
index de7ff7c..936bdaa 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs
@@ -55,7 +55,7 @@ namespace DotNetOpenAuth.OAuth {
/// </summary>
/// <param name="serviceDescription">The endpoints and behavior on the Service Provider.</param>
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
- public ServiceProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager)
+ public ServiceProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager)
: this(serviceDescription, tokenManager, new OAuthServiceProviderMessageFactory(tokenManager)) {
}
@@ -65,7 +65,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="serviceDescription">The endpoints and behavior on the Service Provider.</param>
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
/// <param name="messageTypeProvider">An object that can figure out what type of message is being received for deserialization.</param>
- public ServiceProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, OAuthServiceProviderMessageFactory messageTypeProvider)
+ public ServiceProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager, OAuthServiceProviderMessageFactory messageTypeProvider)
: this(serviceDescription, tokenManager, OAuthElement.Configuration.ServiceProvider.ApplicationStore.CreateInstance(GetHttpApplicationStore(), null), messageTypeProvider) {
Requires.NotNull(serviceDescription, "serviceDescription");
Requires.NotNull(tokenManager, "tokenManager");
@@ -78,7 +78,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="serviceDescription">The endpoints and behavior on the Service Provider.</param>
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
/// <param name="nonceStore">The nonce store.</param>
- public ServiceProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore)
+ public ServiceProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore)
: this(serviceDescription, tokenManager, nonceStore, new OAuthServiceProviderMessageFactory(tokenManager)) {
}
@@ -89,7 +89,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
/// <param name="nonceStore">The nonce store.</param>
/// <param name="messageTypeProvider">An object that can figure out what type of message is being received for deserialization.</param>
- public ServiceProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore, OAuthServiceProviderMessageFactory messageTypeProvider) {
+ public ServiceProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore, OAuthServiceProviderMessageFactory messageTypeProvider) {
Requires.NotNull(serviceDescription, "serviceDescription");
Requires.NotNull(tokenManager, "tokenManager");
Requires.NotNull(nonceStore, "nonceStore");
@@ -107,7 +107,7 @@ namespace DotNetOpenAuth.OAuth {
/// <summary>
/// Gets the description of this Service Provider.
/// </summary>
- public ServiceProviderDescription ServiceDescription { get; private set; }
+ public ServiceProviderHostDescription ServiceDescription { get; private set; }
/// <summary>
/// Gets or sets the generator responsible for generating new tokens and secrets.
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProviderHostDescription.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProviderHostDescription.cs
new file mode 100644
index 0000000..33834eb
--- /dev/null
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProviderHostDescription.cs
@@ -0,0 +1,101 @@
+//-----------------------------------------------------------------------
+// <copyright file="ServiceProviderHostDescription.cs" company="Outercurve Foundation">
+// Copyright (c) Outercurve Foundation. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OAuth {
+ using System;
+ using System.Diagnostics;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Linq;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ /// <summary>
+ /// A description of the endpoints on a Service Provider.
+ /// </summary>
+ public class ServiceProviderHostDescription {
+ /// <summary>
+ /// The field used to store the value of the <see cref="RequestTokenEndpoint"/> property.
+ /// </summary>
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private MessageReceivingEndpoint requestTokenEndpoint;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ServiceProviderHostDescription"/> class.
+ /// </summary>
+ public ServiceProviderHostDescription() {
+ this.ProtocolVersion = Protocol.Default.ProtocolVersion;
+ }
+
+ /// <summary>
+ /// Gets or sets the OAuth version supported by the Service Provider.
+ /// </summary>
+ public ProtocolVersion ProtocolVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets the URL used to obtain an unauthorized Request Token,
+ /// described in Section 6.1 (Obtaining an Unauthorized Request Token).
+ /// </summary>
+ /// <remarks>
+ /// The request URL query MUST NOT contain any OAuth Protocol Parameters.
+ /// This is the URL that <see cref="OAuth.Messages.UnauthorizedTokenRequest"/> messages are directed to.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown if this property is set to a URI with OAuth protocol parameters.</exception>
+ public MessageReceivingEndpoint RequestTokenEndpoint {
+ get {
+ return this.requestTokenEndpoint;
+ }
+
+ set {
+ if (value != null && UriUtil.QueryStringContainPrefixedParameters(value.Location, OAuth.Protocol.ParameterPrefix)) {
+ throw new ArgumentException(OAuthStrings.RequestUrlMustNotHaveOAuthParameters);
+ }
+
+ this.requestTokenEndpoint = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the URL used to obtain User authorization for Consumer access,
+ /// described in Section 6.2 (Obtaining User Authorization).
+ /// </summary>
+ /// <remarks>
+ /// This is the URL that <see cref="OAuth.Messages.UserAuthorizationRequest"/> messages are
+ /// indirectly (via the user agent) sent to.
+ /// </remarks>
+ public MessageReceivingEndpoint UserAuthorizationEndpoint { get; set; }
+
+ /// <summary>
+ /// Gets or sets the URL used to exchange the User-authorized Request Token
+ /// for an Access Token, described in Section 6.3 (Obtaining an Access Token).
+ /// </summary>
+ /// <remarks>
+ /// This is the URL that <see cref="OAuth.Messages.AuthorizedTokenRequest"/> messages are directed to.
+ /// </remarks>
+ public MessageReceivingEndpoint AccessTokenEndpoint { get; set; }
+
+ /// <summary>
+ /// Gets or sets the signing policies that apply to this Service Provider.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Type initializers require this format.")]
+ public ITamperProtectionChannelBindingElement[] TamperProtectionElements { get; set; }
+
+ /// <summary>
+ /// Gets the OAuth version supported by the Service Provider.
+ /// </summary>
+ internal Version Version {
+ get { return Protocol.Lookup(this.ProtocolVersion).Version; }
+ }
+
+ /// <summary>
+ /// Creates a signing element that includes all the signing elements this service provider supports.
+ /// </summary>
+ /// <returns>The created signing element.</returns>
+ internal ITamperProtectionChannelBindingElement CreateTamperProtectionElement() {
+ RequiresEx.ValidState(this.TamperProtectionElements != null);
+ return new SigningBindingElementChain(this.TamperProtectionElements.Select(el => (ITamperProtectionChannelBindingElement)el.Clone()).ToArray());
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuthReporting.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuthReporting.cs
index aa3f934..8171e1a 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuthReporting.cs
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuthReporting.cs
@@ -25,7 +25,7 @@ namespace DotNetOpenAuth {
/// <param name="service">The service.</param>
/// <param name="tokenManager">The token manager.</param>
/// <param name="nonceStore">The nonce store.</param>
- internal static void RecordFeatureAndDependencyUse(object value, ServiceProviderDescription service, ITokenManager tokenManager, INonceStore nonceStore) {
+ internal static void RecordFeatureAndDependencyUse(object value, ServiceProviderHostDescription service, ITokenManager tokenManager, INonceStore nonceStore) {
Requires.NotNull(value, "value");
Requires.NotNull(service, "service");
Requires.NotNull(tokenManager, "tokenManager");
@@ -45,7 +45,7 @@ namespace DotNetOpenAuth {
builder.Append(nonceStore.GetType().Name);
}
builder.Append(" ");
- builder.Append(service.ResourceOwnerAuthorizationEndpoint);
+ builder.Append(service.UserAuthorizationEndpoint.Location);
Reporting.ObservedFeatures.Add(builder.ToString());
Reporting.Touch();
}
diff --git a/src/DotNetOpenAuth.OAuth/DotNetOpenAuth.OAuth.csproj b/src/DotNetOpenAuth.OAuth/DotNetOpenAuth.OAuth.csproj
index 8524a78..af9aea9 100644
--- a/src/DotNetOpenAuth.OAuth/DotNetOpenAuth.OAuth.csproj
+++ b/src/DotNetOpenAuth.OAuth/DotNetOpenAuth.OAuth.csproj
@@ -44,7 +44,6 @@
<Compile Include="OAuth\Messages\ITokenContainingMessage.cs" />
<Compile Include="OAuth\Messages\SignedMessageBase.cs" />
<Compile Include="OAuth\ChannelElements\SigningBindingElementBase.cs" />
- <Compile Include="OAuth\ServiceProviderDescription.cs" />
<Compile Include="OAuth\ServiceProviderSecuritySettings.cs" />
<Compile Include="OAuth\ChannelElements\ITamperResistantOAuthMessage.cs" />
<Compile Include="OAuth\Messages\MessageBase.cs" />
diff --git a/src/DotNetOpenAuth.OpenIdOAuth/OAuth/ServiceProviderOpenIdProvider.cs b/src/DotNetOpenAuth.OpenIdOAuth/OAuth/ServiceProviderOpenIdProvider.cs
index f827857..1c0c5fb 100644
--- a/src/DotNetOpenAuth.OpenIdOAuth/OAuth/ServiceProviderOpenIdProvider.cs
+++ b/src/DotNetOpenAuth.OpenIdOAuth/OAuth/ServiceProviderOpenIdProvider.cs
@@ -41,7 +41,7 @@ namespace DotNetOpenAuth.OAuth {
/// </summary>
/// <param name="serviceDescription">The endpoints and behavior on the Service Provider.</param>
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
- public ServiceProviderOpenIdProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager)
+ public ServiceProviderOpenIdProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager)
: base(serviceDescription, tokenManager) {
}
@@ -51,7 +51,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="serviceDescription">The service description.</param>
/// <param name="tokenManager">The token manager.</param>
/// <param name="messageTypeProvider">The message type provider.</param>
- public ServiceProviderOpenIdProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, OAuthServiceProviderMessageFactory messageTypeProvider)
+ public ServiceProviderOpenIdProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager, OAuthServiceProviderMessageFactory messageTypeProvider)
: base(serviceDescription, tokenManager, messageTypeProvider) {
}
@@ -61,7 +61,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="serviceDescription">The service description.</param>
/// <param name="tokenManager">The token manager.</param>
/// <param name="nonceStore">The nonce store.</param>
- public ServiceProviderOpenIdProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore)
+ public ServiceProviderOpenIdProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore)
: base(serviceDescription, tokenManager, nonceStore) {
}
@@ -72,7 +72,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="tokenManager">The token manager.</param>
/// <param name="nonceStore">The nonce store.</param>
/// <param name="messageTypeProvider">The message type provider.</param>
- public ServiceProviderOpenIdProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore, OAuthServiceProviderMessageFactory messageTypeProvider)
+ public ServiceProviderOpenIdProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore, OAuthServiceProviderMessageFactory messageTypeProvider)
: base(serviceDescription, tokenManager, nonceStore, messageTypeProvider) {
}