diff options
Diffstat (limited to 'samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs')
-rw-r--r-- | samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs b/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs index 210e2ad..ff87267 100644 --- a/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs +++ b/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs @@ -8,6 +8,7 @@ using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.OAuth2; using DotNetOpenAuth.OAuth2.ChannelElements; + using DotNetOpenAuth.OAuth2.Messages; internal class OAuth2AuthorizationServer : IAuthorizationServer { internal static readonly RSAParameters AsymmetricKey; @@ -31,7 +32,7 @@ get { return secret; } } - public DotNetOpenAuth.Messaging.Bindings.INonceStore VerificationCodeNonceStore { + public INonceStore VerificationCodeNonceStore { get { return this.nonceStore; } } @@ -52,8 +53,57 @@ #endregion public bool IsAuthorizationValid(IAuthorizationDescription authorization) { - // We don't support revoking tokens yet. - return true; + return this.IsAuthorizationValid(authorization.Scope, authorization.ClientIdentifier, authorization.UtcIssued, authorization.User); + } + + public bool CanBeAutoApproved(EndUserAuthorizationRequest authorizationRequest) { + if (authorizationRequest == null) { + throw new ArgumentNullException("authorizationRequest"); + } + + // NEVER issue an auto-approval to a client that would end up getting an access token immediately + // (without a client secret), as that would allow ANY client to spoof an approved client's identity + // and obtain unauthorized access to user data. + if (authorizationRequest.ResponseType == EndUserAuthorizationResponseType.AuthorizationCode) { + // Never issue auto-approval if the client secret is blank, since that too makes it easy to spoof + // a client's identity and obtain unauthorized access. + var requestingClient = Global.DataContext.Clients.First(c => c.ClientIdentifier == authorizationRequest.ClientIdentifier); + if (!string.IsNullOrEmpty(requestingClient.ClientSecret)) { + return this.IsAuthorizationValid( + authorizationRequest.Scope, + authorizationRequest.ClientIdentifier, + DateTime.UtcNow, + HttpContext.Current.User.Identity.Name); + } + } + + // Default to not auto-approving. + return false; + } + + private bool IsAuthorizationValid(HashSet<string> requestedScopes, string clientIdentifier, DateTime issuedUtc, string username) { + var grantedScopeStrings = from auth in Global.DataContext.ClientAuthorizations + where + auth.Client.ClientIdentifier == clientIdentifier && + auth.CreatedOnUtc <= issuedUtc && + (!auth.ExpirationDateUtc.HasValue || auth.ExpirationDateUtc.Value >= DateTime.UtcNow) && + auth.User.OpenIDClaimedIdentifier == username + select auth.Scope; + + if (!grantedScopeStrings.Any()) { + // No granted authorizations prior to the issuance of this token, so it must have been revoked. + // Even if later authorizations restore this client's ability to call in, we can't allow + // access tokens issued before the re-authorization because the revoked authorization should + // effectively and permanently revoke all access and refresh tokens. + return false; + } + + var grantedScopes = new HashSet<string>(OAuthUtilities.ScopeStringComparer); + foreach (string scope in grantedScopeStrings) { + grantedScopes.UnionWith(OAuthUtilities.SplitScopes(scope)); + } + + return requestedScopes.IsSubsetOf(grantedScopes); } } }
\ No newline at end of file |