diff options
Diffstat (limited to 'samples/OAuthServiceProvider/App_Code')
5 files changed, 104 insertions, 10 deletions
diff --git a/samples/OAuthServiceProvider/App_Code/DataApi.cs b/samples/OAuthServiceProvider/App_Code/DataApi.cs index a765159..00876f6 100644 --- a/samples/OAuthServiceProvider/App_Code/DataApi.cs +++ b/samples/OAuthServiceProvider/App_Code/DataApi.cs @@ -1,20 +1,26 @@ 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 Global.LoggedInUser 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; } - } - public int? GetAge() { - return AccessToken.User.Age; + return Global.LoggedInUser.Age; } public string GetName() { - return AccessToken.User.FullName; + return Global.LoggedInUser.FullName; } public string[] GetFavoriteSites() { - return AccessToken.User.FavoriteSites.Select(site => site.SiteUrl).ToArray(); + return Global.LoggedInUser.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..1ec2cb5 100644 --- a/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs +++ b/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs @@ -1,7 +1,10 @@ using System; +using System.Collections.Generic; +using System.IdentityModel.Policy; using System.Linq; using System.ServiceModel; using System.ServiceModel.Channels; +using System.ServiceModel.Security; using DotNetOpenAuth; using DotNetOpenAuth.OAuth; @@ -24,10 +27,22 @@ public class OAuthAuthorizationManager : ServiceAuthorizationManager { if (auth != null) { var accessToken = Global.DataContext.OAuthTokens.Single(token => token.Token == auth.AccessToken); + var policy = new OAuthPrincipalAuthorizationPolicy(sp.CreatePrincipal(auth)); + 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, + }; + } + // 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 ec9b31e..fc1d6c5 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 } |