summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OAuth2.AuthorizationServer
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.OAuth2.AuthorizationServer')
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj3
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs19
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedAuthorizationCheckResponse.cs40
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedUserAuthorizationCheckResponse.cs42
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs15
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs4
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs46
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/Messages/AccessTokenResult.cs50
8 files changed, 182 insertions, 37 deletions
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj
index 34d59ee..73c563b 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj
@@ -27,6 +27,8 @@
<DependentUpon>AuthServerStrings.resx</DependentUpon>
</Compile>
<Compile Include="OAuth2\AuthServerUtilities.cs" />
+ <Compile Include="OAuth2\AutomatedAuthorizationCheckResponse.cs" />
+ <Compile Include="OAuth2\AutomatedUserAuthorizationCheckResponse.cs" />
<Compile Include="OAuth2\ChannelElements\AggregatingClientCredentialReader.cs" />
<Compile Include="OAuth2\ChannelElements\ClientCredentialHttpBasicReader.cs" />
<Compile Include="OAuth2\ChannelElements\ClientCredentialMessagePartReader.cs" />
@@ -42,6 +44,7 @@
<Compile Include="OAuth2\IAuthorizationServerHost.cs" />
<Compile Include="OAuth2\Messages\AccessTokenAuthorizationCodeRequestAS.cs" />
<Compile Include="OAuth2\Messages\AccessTokenRefreshRequestAS.cs" />
+ <Compile Include="OAuth2\Messages\AccessTokenResult.cs" />
<Compile Include="OAuth2\Messages\EndUserAuthorizationSuccessAuthCodeResponseAS.cs" />
<Compile Include="OAuth2\Messages\IAuthorizationCodeCarryingRequest.cs" />
<Compile Include="OAuth2\Messages\IRefreshTokenCarryingRequest.cs" />
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs
index 1e404e7..050a4ab 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs
@@ -265,6 +265,25 @@ namespace DotNetOpenAuth.OAuth2 {
}
/// <summary>
+ /// Decodes a refresh token into its authorization details.
+ /// </summary>
+ /// <param name="refreshToken">The encoded refresh token as it would appear to the client.</param>
+ /// <returns>A description of the authorization represented by the refresh token.</returns>
+ /// <exception cref="ProtocolException">Thrown if the refresh token is not valid due to expiration, corruption or not being authentic.</exception>
+ /// <remarks>
+ /// This can be useful if the authorization server supports the client revoking its own access (on uninstall, for example).
+ /// Outside the scope of the OAuth 2 spec, the client may contact the authorization server host requesting that its refresh
+ /// token be revoked. The authorization server would need to decode the refresh token so it knows which authorization in
+ /// the database to delete.
+ /// </remarks>
+ public IAuthorizationDescription DecodeRefreshToken(string refreshToken) {
+ var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServerServices.CryptoKeyStore);
+ var token = new RefreshToken();
+ refreshTokenFormatter.Deserialize(token, refreshToken);
+ return token;
+ }
+
+ /// <summary>
/// Gets the redirect URL to use for a particular authorization request.
/// </summary>
/// <param name="authorizationRequest">The authorization request.</param>
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedAuthorizationCheckResponse.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedAuthorizationCheckResponse.cs
new file mode 100644
index 0000000..0179d05
--- /dev/null
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedAuthorizationCheckResponse.cs
@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------
+// <copyright file="AutomatedAuthorizationCheckResponse.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OAuth2 {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.OAuth2.Messages;
+
+ /// <summary>
+ /// Describes the result of an automated authorization check, such as for client credential or resource owner password grants.
+ /// </summary>
+ public class AutomatedAuthorizationCheckResponse {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AutomatedAuthorizationCheckResponse" /> class.
+ /// </summary>
+ /// <param name="accessRequest">The access token request.</param>
+ /// <param name="approved">A value indicating whether the authorization should be approved.</param>
+ public AutomatedAuthorizationCheckResponse(IAccessTokenRequest accessRequest, bool approved) {
+ Requires.NotNull(accessRequest, "accessRequest");
+
+ this.IsApproved = approved;
+ this.ApprovedScope = new HashSet<string>(accessRequest.Scope);
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the authorization should be approved.
+ /// </summary>
+ public bool IsApproved { get; private set; }
+
+ /// <summary>
+ /// Gets the scope to be granted.
+ /// </summary>
+ public HashSet<string> ApprovedScope { get; private set; }
+ }
+}
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedUserAuthorizationCheckResponse.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedUserAuthorizationCheckResponse.cs
new file mode 100644
index 0000000..b62807c
--- /dev/null
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedUserAuthorizationCheckResponse.cs
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------
+// <copyright file="AutomatedUserAuthorizationCheckResponse.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OAuth2 {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+
+ using DotNetOpenAuth.OAuth2.Messages;
+
+ /// <summary>
+ /// Describes the result of an automated authorization check for resource owner grants.
+ /// </summary>
+ public class AutomatedUserAuthorizationCheckResponse : AutomatedAuthorizationCheckResponse {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AutomatedUserAuthorizationCheckResponse" /> class.
+ /// </summary>
+ /// <param name="accessRequest">The access token request.</param>
+ /// <param name="approved">A value indicating whether the authorization should be approved.</param>
+ /// <param name="canonicalUserName">
+ /// Canonical username of the authorizing user (resource owner), as the resource server would recognize it.
+ /// Ignored if <paramref name="approved"/> is false.
+ /// </param>
+ public AutomatedUserAuthorizationCheckResponse(IAccessTokenRequest accessRequest, bool approved, string canonicalUserName)
+ : base(accessRequest, approved) {
+ if (approved) {
+ Requires.NotNullOrEmpty(canonicalUserName, "canonicalUserName");
+ }
+
+ this.CanonicalUserName = canonicalUserName;
+ }
+
+ /// <summary>
+ /// Gets the canonical username of the authorizing user (resource owner).
+ /// </summary>
+ public string CanonicalUserName { get; private set; }
+ }
+}
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
index 27b71db..3eac5a6 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
@@ -120,11 +120,13 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
// Check that any resource owner password credential is correct.
if (resourceOwnerPasswordCarrier != null) {
try {
- string canonicalUserName;
- if (this.AuthorizationServer.TryAuthorizeResourceOwnerCredentialGrant(resourceOwnerPasswordCarrier.UserName, resourceOwnerPasswordCarrier.Password, resourceOwnerPasswordCarrier, out canonicalUserName)) {
- ErrorUtilities.VerifyHost(!string.IsNullOrEmpty(canonicalUserName), "TryAuthorizeResourceOwnerCredentialGrant did not initialize out parameter.");
+ var authorizeResult =
+ this.AuthorizationServer.CheckAuthorizeResourceOwnerCredentialGrant(
+ resourceOwnerPasswordCarrier.UserName, resourceOwnerPasswordCarrier.Password, resourceOwnerPasswordCarrier);
+ if (authorizeResult.IsApproved) {
resourceOwnerPasswordCarrier.CredentialsValidated = true;
- resourceOwnerPasswordCarrier.UserName = canonicalUserName;
+ resourceOwnerPasswordCarrier.UserName = authorizeResult.CanonicalUserName;
+ resourceOwnerPasswordCarrier.Scope.ResetContents(authorizeResult.ApprovedScope);
} else {
Logger.OAuth.ErrorFormat(
"Resource owner password credential for user \"{0}\" rejected by authorization server host.",
@@ -140,12 +142,15 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
applied = true;
} else if (clientCredentialOnly != null) {
try {
- if (!this.AuthorizationServer.TryAuthorizeClientCredentialsGrant(clientCredentialOnly)) {
+ var authorizeResult = this.AuthorizationServer.CheckAuthorizeClientCredentialsGrant(clientCredentialOnly);
+ if (!authorizeResult.IsApproved) {
Logger.OAuth.ErrorFormat(
"Client credentials grant access request for client \"{0}\" rejected by authorization server host.",
clientCredentialOnly.ClientIdentifier);
throw new TokenEndpointProtocolException(accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.UnauthorizedClient);
}
+
+ clientCredentialOnly.Scope.ResetContents(authorizeResult.ApprovedScope);
} catch (NotSupportedException) {
throw new TokenEndpointProtocolException(accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.UnsupportedGrantType);
} catch (NotImplementedException) {
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs
index 494a10b..5a1dbae 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs
@@ -103,7 +103,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
if (authCodeCarrier != null) {
var authorizationCodeFormatter = AuthorizationCode.CreateFormatter(this.AuthorizationServer);
var authorizationCode = new AuthorizationCode();
- authorizationCodeFormatter.Deserialize(authorizationCode, message, authCodeCarrier.Code, Protocol.code);
+ authorizationCodeFormatter.Deserialize(authorizationCode, authCodeCarrier.Code, message, Protocol.code);
authCodeCarrier.AuthorizationDescription = authorizationCode;
}
@@ -111,7 +111,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
if (refreshTokenCarrier != null) {
var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServer.CryptoKeyStore);
var refreshToken = new RefreshToken();
- refreshTokenFormatter.Deserialize(refreshToken, message, refreshTokenCarrier.RefreshToken, Protocol.refresh_token);
+ refreshTokenFormatter.Deserialize(refreshToken, refreshTokenCarrier.RefreshToken, message, Protocol.refresh_token);
refreshTokenCarrier.AuthorizationDescription = refreshToken;
}
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs
index b75cb29..b9b5725 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs
@@ -91,17 +91,11 @@ namespace DotNetOpenAuth.OAuth2 {
/// The access request the credentials came with.
/// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request.
/// </param>
- /// <param name="canonicalUserName">
- /// Receives the canonical username (normalized for the resource server) of the user, for valid credentials;
- /// Or <c>null</c> if the return value is false.
- /// </param>
- /// <returns>
- /// <c>true</c> if the given credentials are valid and the authorization granted; otherwise, <c>false</c>.
- /// </returns>
+ /// <returns>A value that describes the result of the authorization check.</returns>
/// <exception cref="NotSupportedException">
/// May be thrown if the authorization server does not support the resource owner password credential grant type.
/// </exception>
- bool TryAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest, out string canonicalUserName);
+ AutomatedUserAuthorizationCheckResponse CheckAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest);
/// <summary>
/// Determines whether an access token request given a client credential grant should be authorized
@@ -112,17 +106,15 @@ namespace DotNetOpenAuth.OAuth2 {
/// The access request the credentials came with.
/// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request.
/// </param>
- /// <returns>
- /// <c>true</c> if the given credentials are valid and the authorization granted; otherwise, <c>false</c>.
- /// </returns>
+ /// <returns>A value that describes the result of the authorization check.</returns>
/// <exception cref="NotSupportedException">
/// May be thrown if the authorization server does not support the client credential grant type.
/// </exception>
- bool TryAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest);
+ AutomatedAuthorizationCheckResponse CheckAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest);
}
/// <summary>
- /// Code Contract for the <see cref="IAuthorizationServerHost"/> interface.
+ /// Code Contract for the <see cref="IAuthorizationServerHost" /> interface.
/// </summary>
[ContractClassFor(typeof(IAuthorizationServerHost))]
internal abstract class IAuthorizationServerHostContract : IAuthorizationServerHost {
@@ -203,40 +195,34 @@ namespace DotNetOpenAuth.OAuth2 {
/// The access request the credentials came with.
/// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request.
/// </param>
- /// <param name="canonicalUserName">
- /// Receives the canonical username (normalized for the resource server) of the user, for valid credentials;
- /// Or <c>null</c> if the return value is false.
- /// </param>
/// <returns>
- /// <c>true</c> if the given credentials are valid and the authorization granted; otherwise, <c>false</c>.
+ /// A value that describes the result of the authorization check.
/// </returns>
/// <exception cref="NotSupportedException">
/// May be thrown if the authorization server does not support the resource owner password credential grant type.
/// </exception>
- bool IAuthorizationServerHost.TryAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest, out string canonicalUserName) {
+ AutomatedUserAuthorizationCheckResponse IAuthorizationServerHost.CheckAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest) {
Contract.Requires(!string.IsNullOrEmpty(userName));
Contract.Requires(password != null);
Contract.Requires(accessRequest != null);
- Contract.Ensures(!Contract.Result<bool>() || !string.IsNullOrEmpty(Contract.ValueAtReturn<string>(out canonicalUserName)));
+ Contract.Ensures(Contract.Result<AutomatedUserAuthorizationCheckResponse>() != null);
throw new NotImplementedException();
}
/// <summary>
/// Determines whether an access token request given a client credential grant should be authorized
- /// and if so records an authorization entry such that subsequent calls to <see cref="IAuthorizationServerHost.IsAuthorizationValid"/> would
+ /// and if so records an authorization entry such that subsequent calls to <see cref="IAuthorizationServerHost.IsAuthorizationValid" /> would
/// return <c>true</c>.
/// </summary>
- /// <param name="accessRequest">
- /// The access request the credentials came with.
- /// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request.
- /// </param>
+ /// <param name="accessRequest">The access request the credentials came with.
+ /// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request.</param>
/// <returns>
- /// <c>true</c> if the given credentials are valid and the authorization granted; otherwise, <c>false</c>.
+ /// A value that describes the result of the authorization check.
/// </returns>
- /// <exception cref="NotSupportedException">
- /// May be thrown if the authorization server does not support the client credential grant type.
- /// </exception>
- bool IAuthorizationServerHost.TryAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest) {
+ /// <exception cref="NotSupportedException">May be thrown if the authorization server does not support the client credential grant type.</exception>
+ AutomatedAuthorizationCheckResponse IAuthorizationServerHost.CheckAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest) {
+ Contract.Requires(accessRequest != null);
+ Contract.Ensures(Contract.Result<AutomatedAuthorizationCheckResponse>() != null);
throw new NotImplementedException();
}
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/Messages/AccessTokenResult.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/Messages/AccessTokenResult.cs
new file mode 100644
index 0000000..4297165
--- /dev/null
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/Messages/AccessTokenResult.cs
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------
+// <copyright file="AccessTokenResult.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OAuth2 {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Security.Cryptography;
+ using System.Text;
+
+ /// <summary>
+ /// Describes the parameters to be fed into creating a response to an access token request.
+ /// </summary>
+ public class AccessTokenResult : IAccessTokenResult {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AccessTokenResult"/> class.
+ /// </summary>
+ /// <param name="accessToken">The access token to include in this result.</param>
+ public AccessTokenResult(AuthorizationServerAccessToken accessToken) {
+ Requires.NotNull(accessToken, "accessToken");
+ this.AllowRefreshToken = true;
+ this.AccessToken = accessToken;
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to provide the client with a refresh token, when applicable.
+ /// </summary>
+ /// <value>The default value is <c>true</c>.</value>
+ /// <remarks>>
+ /// The refresh token will never be provided when this value is false.
+ /// The refresh token <em>may</em> be provided when this value is true.
+ /// </remarks>
+ public bool AllowRefreshToken { get; set; }
+
+ /// <summary>
+ /// Gets the access token.
+ /// </summary>
+ public AuthorizationServerAccessToken AccessToken { get; private set; }
+
+ /// <summary>
+ /// Gets the access token.
+ /// </summary>
+ AccessToken IAccessTokenResult.AccessToken {
+ get { return this.AccessToken; }
+ }
+ }
+}