summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2010-08-01 07:37:21 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2010-08-01 08:58:43 -0700
commit222762e7b5d664f3e86683a55be6ea84710efc69 (patch)
treea37153096500bb86d4f8fbea4045f3cce93dfbc7
parente7743dd039bab3788e682833368ca5a376b22354 (diff)
downloadDotNetOpenAuth-222762e7b5d664f3e86683a55be6ea84710efc69.zip
DotNetOpenAuth-222762e7b5d664f3e86683a55be6ea84710efc69.tar.gz
DotNetOpenAuth-222762e7b5d664f3e86683a55be6ea84710efc69.tar.bz2
Some user-notification enhancements to the OAuth 2 samples.
-rw-r--r--samples/OAuthAuthorizationServer/Controllers/OAuthController.cs16
-rw-r--r--samples/OAuthClient/SampleWcf2.aspx20
-rw-r--r--samples/OAuthClient/SampleWcf2.aspx.cs27
-rw-r--r--src/DotNetOpenAuth/OAuth2/ClientBase.cs6
4 files changed, 52 insertions, 17 deletions
diff --git a/samples/OAuthAuthorizationServer/Controllers/OAuthController.cs b/samples/OAuthAuthorizationServer/Controllers/OAuthController.cs
index 98fac04..0eb7c83 100644
--- a/samples/OAuthAuthorizationServer/Controllers/OAuthController.cs
+++ b/samples/OAuthAuthorizationServer/Controllers/OAuthController.cs
@@ -40,7 +40,18 @@
public ActionResult Token() {
var request = this.authorizationServer.ReadAccessTokenRequest();
if (request != null) {
- var response = this.authorizationServer.PrepareAccessTokenResponse(request, ResourceServerEncryptionPublicKey);
+ // Just for the sake of the sample, we use a short-lived token. This can be useful to mitigate the security risks
+ // of access tokens that are used over standard HTTP.
+ // But this is just the lifetime of the access token. The client can still renew it using their refresh token until
+ // the authorization itself expires.
+ TimeSpan accessTokenLifetime = TimeSpan.FromMinutes(2);
+
+ // Also take into account the remaining life of the authorization and artificially shorten the access token's lifetime
+ // to account for that if necessary.
+ // TODO: code here
+
+ // Prepare the refresh and access tokens.
+ var response = this.authorizationServer.PrepareAccessTokenResponse(request, ResourceServerEncryptionPublicKey, accessTokenLifetime);
return this.authorizationServer.Channel.PrepareResponse(response).AsActionResult();
}
@@ -80,6 +91,9 @@
IDirectedProtocolMessage response;
if (isApproved) {
+ // The authorization we file in our database lasts until the user explicitly revokes it.
+ // You can cause the authorization to expire by setting the ExpirationDateUTC
+ // property in the below created ClientAuthorization.
var client = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier);
client.ClientAuthorizations.Add(
new ClientAuthorization {
diff --git a/samples/OAuthClient/SampleWcf2.aspx b/samples/OAuthClient/SampleWcf2.aspx
index b19ae69..cfacaf1 100644
--- a/samples/OAuthClient/SampleWcf2.aspx
+++ b/samples/OAuthClient/SampleWcf2.aspx
@@ -1,13 +1,24 @@
-<%@ Page Title="OAuth 2.0 client (web server flow)" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthClient.SampleWcf2" Codebehind="SampleWcf2.aspx.cs" %>
+<%@ Page Title="OAuth 2.0 client (web server flow)" Language="C#" MasterPageFile="~/MasterPage.master"
+ AutoEventWireup="true" Inherits="OAuthClient.SampleWcf2" CodeBehind="SampleWcf2.aspx.cs" %>
<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
<fieldset title="Authorization">
+ <p>
+ Check off the operations you&#39;d like to authorization this client to make on
+ behalf of your account on the resource server.<br />
+ Note that an authorization request may not actually result in you being prompted
+ to grant authorization if you&#39;ve granted it previously.&nbsp; The authorization
+ server remembers what you&#39;ve already approved.&nbsp; But even if you&#39;ve
+ requested and received authorization for all three scopes above, you can request
+ access tokens for subsets of this set of scopes to limit what you can do below.
+ </p>
<asp:CheckBoxList runat="server" ID="scopeList">
<asp:ListItem Value="http://tempuri.org/IDataApi/GetName">GetName</asp:ListItem>
<asp:ListItem Value="http://tempuri.org/IDataApi/GetAge">GetAge</asp:ListItem>
<asp:ListItem Value="http://tempuri.org/IDataApi/GetFavoriteSites">GetFavoriteSites</asp:ListItem>
</asp:CheckBoxList>
- <asp:Button ID="getAuthorizationButton" runat="server" Text="Request Authorization" OnClick="getAuthorizationButton_Click" />
+ <asp:Button ID="getAuthorizationButton" runat="server" Text="Request Authorization"
+ OnClick="getAuthorizationButton_Click" />
<asp:Label ID="authorizationLabel" runat="server" />
</fieldset>
<br />
@@ -17,7 +28,6 @@
<asp:Button ID="getAgeButton" runat="server" Text="Get Age" OnClick="getAgeButton_Click" />
<asp:Label ID="ageLabel" runat="server" />
<br />
- <asp:Button ID="getFavoriteSites" runat="server" Text="Get Favorite Sites"
- onclick="getFavoriteSites_Click" />
+ <asp:Button ID="getFavoriteSites" runat="server" Text="Get Favorite Sites" OnClick="getFavoriteSites_Click" />
<asp:Label ID="favoriteSitesLabel" runat="server" />
-</asp:Content> \ No newline at end of file
+</asp:Content>
diff --git a/samples/OAuthClient/SampleWcf2.aspx.cs b/samples/OAuthClient/SampleWcf2.aspx.cs
index 41f2896..7e0ea10 100644
--- a/samples/OAuthClient/SampleWcf2.aspx.cs
+++ b/samples/OAuthClient/SampleWcf2.aspx.cs
@@ -56,16 +56,22 @@
// We are receiving an authorization response. Store it and associate it with this user.
Authorization = authorization;
Response.Redirect(Request.Path); // get rid of the /?code= parameter
- } else {
- if (Authorization != null) {
- // Indicate to the user that we have already obtained authorization on some of these.
- foreach (var li in this.scopeList.Items.OfType<ListItem>().Where(li => Authorization.Scope.Contains(li.Value))) {
- li.Selected = true;
- }
- authorizationLabel.Text = "Authorization received!";
- }
}
}
+
+ if (Authorization != null) {
+ // Indicate to the user that we have already obtained authorization on some of these.
+ foreach (var li in this.scopeList.Items.OfType<ListItem>().Where(li => Authorization.Scope.Contains(li.Value))) {
+ li.Selected = true;
+ }
+ authorizationLabel.Text = "Authorization received!";
+ if (Authorization.AccessTokenExpirationUtc.HasValue) {
+ TimeSpan timeLeft = Authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
+ authorizationLabel.Text += string.Format(CultureInfo.CurrentCulture, " (access token expires in {0} minutes)", Math.Round(timeLeft.TotalMinutes, 1));
+ }
+ }
+
+ this.getNameButton.Enabled = this.getAgeButton.Enabled = this.getFavoriteSites.Enabled = Authorization != null;
}
protected void getAuthorizationButton_Click(object sender, EventArgs e) {
@@ -111,7 +117,10 @@
// Refresh the access token if it expires and if its lifetime is too short to be of use.
if (Authorization.AccessTokenExpirationUtc.HasValue) {
- Client.RefreshToken(Authorization, TimeSpan.FromMinutes(1));
+ if (Client.RefreshToken(Authorization, TimeSpan.FromSeconds(30))) {
+ TimeSpan timeLeft = Authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
+ authorizationLabel.Text += string.Format(CultureInfo.CurrentCulture, " - just renewed for {0} more minutes)", Math.Round(timeLeft.TotalMinutes, 1));
+ }
}
var httpRequest = (HttpWebRequest)WebRequest.Create(wcfClient.Endpoint.Address.Uri);
diff --git a/src/DotNetOpenAuth/OAuth2/ClientBase.cs b/src/DotNetOpenAuth/OAuth2/ClientBase.cs
index d9d9232..845d24c 100644
--- a/src/DotNetOpenAuth/OAuth2/ClientBase.cs
+++ b/src/DotNetOpenAuth/OAuth2/ClientBase.cs
@@ -94,7 +94,8 @@ namespace DotNetOpenAuth.OAuth2 {
/// </summary>
/// <param name="authorization">The authorization to update.</param>
/// <param name="skipIfUsefulLifeExceeds">If given, the access token will <em>not</em> be refreshed if its remaining lifetime exceeds this value.</param>
- public void RefreshToken(IAuthorizationState authorization, TimeSpan? skipIfUsefulLifeExceeds = null) {
+ /// <returns>A value indicating whether the access token was actually renewed; <c>true</c> if it was renewed, or <c>false</c> if it still had useful life remaining.</returns>
+ public bool RefreshToken(IAuthorizationState authorization, TimeSpan? skipIfUsefulLifeExceeds = null) {
Contract.Requires<ArgumentNullException>(authorization != null, "authorization");
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(authorization.RefreshToken));
@@ -103,7 +104,7 @@ namespace DotNetOpenAuth.OAuth2 {
if (usefulLifeRemaining > skipIfUsefulLifeExceeds.Value) {
// There is useful life remaining in the access token. Don't refresh.
Logger.OAuth.DebugFormat("Skipping token refresh step because access token's remaining life is {0}, which exceeds {1}.", usefulLifeRemaining, skipIfUsefulLifeExceeds.Value);
- return;
+ return false;
}
}
@@ -129,6 +130,7 @@ namespace DotNetOpenAuth.OAuth2 {
}
authorization.SaveChanges();
+ return true;
}
/// <summary>