summaryrefslogtreecommitdiffstats
path: root/samples/OAuthServiceProvider/App_Code
diff options
context:
space:
mode:
Diffstat (limited to 'samples/OAuthServiceProvider/App_Code')
-rw-r--r--samples/OAuthServiceProvider/App_Code/DataApi.cs21
-rw-r--r--samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs10
-rw-r--r--samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs24
-rw-r--r--samples/OAuthServiceProvider/App_Code/OAuthPrincipalAuthorizationPolicy.cs45
-rw-r--r--samples/OAuthServiceProvider/App_Code/OAuthToken.cs22
-rw-r--r--samples/OAuthServiceProvider/App_Code/Utilities.cs26
6 files changed, 140 insertions, 8 deletions
diff --git a/samples/OAuthServiceProvider/App_Code/DataApi.cs b/samples/OAuthServiceProvider/App_Code/DataApi.cs
index a765159..d5adb10 100644
--- a/samples/OAuthServiceProvider/App_Code/DataApi.cs
+++ b/samples/OAuthServiceProvider/App_Code/DataApi.cs
@@ -1,20 +1,31 @@
using System.Linq;
using System.ServiceModel;
+/// <summary>
+/// The WCF service API.
+/// </summary>
+/// <remarks>
+/// Note how there is no code here that is bound to OAuth or any other
+/// credential/authorization scheme. That's all part of the channel/binding elsewhere.
+/// And the reference to OperationContext.Current.ServiceSecurityContext.PrimaryIdentity
+/// is the user being impersonated by the WCF client.
+/// In the OAuth case, it is the user who authorized the OAuth access token that was used
+/// to gain access to the service.
+/// </remarks>
public class DataApi : IDataApi {
- private static OAuthToken AccessToken {
- get { return OperationContext.Current.IncomingMessageProperties["OAuthAccessToken"] as OAuthToken; }
+ private User User {
+ get { return OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.GetUser(); }
}
public int? GetAge() {
- return AccessToken.User.Age;
+ return User.Age;
}
public string GetName() {
- return AccessToken.User.FullName;
+ return User.FullName;
}
public string[] GetFavoriteSites() {
- return AccessToken.User.FavoriteSites.Select(site => site.SiteUrl).ToArray();
+ return User.FavoriteSites.Select(site => site.SiteUrl).ToArray();
}
}
diff --git a/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs b/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs
index 8ca4539..710508d 100644
--- a/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs
+++ b/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs
@@ -26,7 +26,15 @@ public class DatabaseTokenManager : IServiceProviderTokenManager {
public IServiceProviderRequestToken GetRequestToken(string token) {
try {
- return Global.DataContext.OAuthTokens.First(t => t.Token == token);
+ return Global.DataContext.OAuthTokens.First(t => t.Token == token && t.State != TokenAuthorizationState.AccessToken);
+ } catch (InvalidOperationException ex) {
+ throw new KeyNotFoundException("Unrecognized token", ex);
+ }
+ }
+
+ public IServiceProviderAccessToken GetAccessToken(string token) {
+ try {
+ return Global.DataContext.OAuthTokens.First(t => t.Token == token && t.State == TokenAuthorizationState.AccessToken);
} catch (InvalidOperationException ex) {
throw new KeyNotFoundException("Unrecognized token", ex);
}
diff --git a/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs b/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs
index fce1ad4..8589932 100644
--- a/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs
+++ b/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs
@@ -1,7 +1,11 @@
using System;
+using System.Collections.Generic;
+using System.IdentityModel.Policy;
using System.Linq;
+using System.Security.Principal;
using System.ServiceModel;
using System.ServiceModel.Channels;
+using System.ServiceModel.Security;
using DotNetOpenAuth;
using DotNetOpenAuth.OAuth;
@@ -24,10 +28,28 @@ public class OAuthAuthorizationManager : ServiceAuthorizationManager {
if (auth != null) {
var accessToken = Global.DataContext.OAuthTokens.Single(token => token.Token == auth.AccessToken);
+ var principal = sp.CreatePrincipal(auth);
+ var policy = new OAuthPrincipalAuthorizationPolicy(principal);
+ var policies = new List<IAuthorizationPolicy> {
+ policy,
+ };
+
+ var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
+ if (operationContext.IncomingMessageProperties.Security != null) {
+ operationContext.IncomingMessageProperties.Security.ServiceSecurityContext = securityContext;
+ } else {
+ operationContext.IncomingMessageProperties.Security = new SecurityMessageProperty {
+ ServiceSecurityContext = securityContext,
+ };
+ }
+
+ securityContext.AuthorizationContext.Properties["Identities"] = new List<IIdentity> {
+ principal.Identity,
+ };
+
// Only allow this method call if the access token scope permits it.
string[] scopes = accessToken.Scope.Split('|');
if (scopes.Contains(operationContext.IncomingMessageHeaders.Action)) {
- operationContext.IncomingMessageProperties["OAuthAccessToken"] = accessToken;
return true;
}
}
diff --git a/samples/OAuthServiceProvider/App_Code/OAuthPrincipalAuthorizationPolicy.cs b/samples/OAuthServiceProvider/App_Code/OAuthPrincipalAuthorizationPolicy.cs
new file mode 100644
index 0000000..5bd6b05
--- /dev/null
+++ b/samples/OAuthServiceProvider/App_Code/OAuthPrincipalAuthorizationPolicy.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.IdentityModel.Claims;
+using System.IdentityModel.Policy;
+using System.Linq;
+using System.Web;
+using DotNetOpenAuth.OAuth.ChannelElements;
+
+public class OAuthPrincipalAuthorizationPolicy : IAuthorizationPolicy {
+ private readonly Guid uniqueId = Guid.NewGuid();
+ private readonly OAuthPrincipal principal;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="OAuthPrincipalAuthorizationPolicy"/> class.
+ /// </summary>
+ /// <param name="principal">The principal.</param>
+ public OAuthPrincipalAuthorizationPolicy(OAuthPrincipal principal) {
+ this.principal = principal;
+ }
+
+ #region IAuthorizationComponent Members
+
+ /// <summary>
+ /// Gets a unique ID for this instance.
+ /// </summary>
+ public string Id {
+ get { return this.uniqueId.ToString(); }
+ }
+
+ #endregion
+
+ #region IAuthorizationPolicy Members
+
+ public ClaimSet Issuer {
+ get { return ClaimSet.System; }
+ }
+
+ public bool Evaluate(EvaluationContext evaluationContext, ref object state) {
+ evaluationContext.AddClaimSet(this, new DefaultClaimSet(Claim.CreateNameClaim(this.principal.Identity.Name)));
+ evaluationContext.Properties["Principal"] = this.principal;
+ return true;
+ }
+
+ #endregion
+}
diff --git a/samples/OAuthServiceProvider/App_Code/OAuthToken.cs b/samples/OAuthServiceProvider/App_Code/OAuthToken.cs
index 2f26799..ea18b2b 100644
--- a/samples/OAuthServiceProvider/App_Code/OAuthToken.cs
+++ b/samples/OAuthServiceProvider/App_Code/OAuthToken.cs
@@ -10,7 +10,7 @@ using System.Linq;
using System.Web;
using DotNetOpenAuth.OAuth.ChannelElements;
-public partial class OAuthToken : IServiceProviderRequestToken {
+public partial class OAuthToken : IServiceProviderRequestToken, IServiceProviderAccessToken {
#region IServiceProviderRequestToken Members
string IServiceProviderRequestToken.Token {
@@ -41,4 +41,24 @@ public partial class OAuthToken : IServiceProviderRequestToken {
}
#endregion
+
+ #region IServiceProviderAccessToken Members
+
+ string IServiceProviderAccessToken.Token {
+ get { return this.Token; }
+ }
+
+ DateTime? IServiceProviderAccessToken.ExpirationDate {
+ get { return null; }
+ }
+
+ string IServiceProviderAccessToken.Username {
+ get { return this.User.OpenIDClaimedIdentifier; }
+ }
+
+ string[] IServiceProviderAccessToken.Roles {
+ get { return this.Scope.Split('|'); }
+ }
+
+ #endregion
}
diff --git a/samples/OAuthServiceProvider/App_Code/Utilities.cs b/samples/OAuthServiceProvider/App_Code/Utilities.cs
new file mode 100644
index 0000000..2c25fe8
--- /dev/null
+++ b/samples/OAuthServiceProvider/App_Code/Utilities.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Principal;
+using System.Web;
+
+/// <summary>
+/// Extension methods and other helpful utility methods.
+/// </summary>
+public static class Utilities {
+ /// <summary>
+ /// Gets the database entity representing the user identified by a given <see cref="IIdentity"/> instance.
+ /// </summary>
+ /// <param name="identity">The identity of the user.</param>
+ /// <returns>
+ /// The database object for that user; or <c>null</c> if the user could not
+ /// be found or if <paramref name="identity"/> is <c>null</c> or represents an anonymous identity.
+ /// </returns>
+ public static User GetUser(this IIdentity identity) {
+ if (identity == null || !identity.IsAuthenticated) {
+ return null;
+ }
+
+ return Global.DataContext.Users.SingleOrDefault(user => user.OpenIDClaimedIdentifier == identity.Name);
+ }
+}