summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs12
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj4
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingUtilities.cs4
-rw-r--r--src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs9
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs15
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs4
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs14
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/GrantTypeEncoder.cs8
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/IAuthorizationCarryingRequest.cs (renamed from src/DotNetOpenAuth/OAuth2/ChannelElements/ITokenCarryingRequest.cs)4
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2ChannelBase.cs1
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2ResourceServerChannel.cs79
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/ScopeEncoder.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/ClientBase.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessProtectedResourceRequest.cs86
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAssertionRequest.cs49
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs8
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessTokenClientCredentialsRequest.cs4
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs9
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRequestBase.cs8
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessTokenResourceOwnerPasswordCredentialsRequest.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessTokenSuccessResponse.cs11
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs10
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationRequest.cs10
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationResponseType.cs12
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs32
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs8
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/GrantType.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/OAuth 2 Messages.cd177
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/ScopedAccessTokenRequest.cs34
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/UnauthorizedResponse.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs4
-rw-r--r--src/DotNetOpenAuth/OAuth2/Protocol.cs47
32 files changed, 276 insertions, 397 deletions
diff --git a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs
index 0e82154..e6237ca 100644
--- a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs
+++ b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs
@@ -122,18 +122,6 @@ namespace DotNetOpenAuth.Test.OAuth2 {
Assert.IsInstanceOf(typeof(AccessTokenClientCredentialsRequest), request);
}
- [TestCase]
- public void AccessTokenAssertionRequest() {
- var fields = new Dictionary<string, string> {
- { Protocol.client_id, "abc" },
- { Protocol.assertion_type, "abc" },
- { Protocol.assertion, "abc" },
- { Protocol.grant_type, "assertion" },
- };
- IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields);
- Assert.IsInstanceOf(typeof(AccessTokenAssertionRequest), request);
- }
-
#endregion
}
}
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
index 8123d7a..60f2b8e 100644
--- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj
+++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
@@ -370,7 +370,7 @@ http://opensource.org/licenses/ms-pl.html
<Compile Include="OAuth2\ChannelElements\ScopeEncoder.cs" />
<Compile Include="Messaging\UriStyleMessageFormatter.cs" />
<Compile Include="OAuth2\ChannelElements\IAuthorizationDescription.cs" />
- <Compile Include="OAuth2\ChannelElements\ITokenCarryingRequest.cs" />
+ <Compile Include="OAuth2\ChannelElements\IAuthorizationCarryingRequest.cs" />
<Compile Include="OAuth2\ChannelElements\OAuth2ResourceServerChannel.cs" />
<Compile Include="Messaging\StandardMessageFactoryChannel.cs" />
<Compile Include="OAuth2\ChannelElements\RefreshToken.cs" />
@@ -385,7 +385,6 @@ http://opensource.org/licenses/ms-pl.html
<Compile Include="OAuth2\IClientAuthorizationTracker.cs" />
<Compile Include="OAuth2\IConsumerDescription.cs" />
<Compile Include="OAuth2\Messages\AccessProtectedResourceRequest.cs" />
- <Compile Include="OAuth2\Messages\AccessTokenAssertionRequest.cs" />
<Compile Include="OAuth2\Messages\AccessTokenAuthorizationCodeRequest.cs" />
<Compile Include="OAuth2\Messages\AccessTokenResourceOwnerPasswordCredentialsRequest.cs" />
<Compile Include="OAuth2\Messages\AccessTokenRequestBase.cs" />
@@ -398,6 +397,7 @@ http://opensource.org/licenses/ms-pl.html
<Compile Include="OAuth2\Messages\AccessTokenRefreshRequest.cs" />
<Compile Include="OAuth2\Messages\EndUserAuthorizationResponseType.cs" />
<Compile Include="OAuth2\Messages\IMessageWithClientState.cs" />
+ <Compile Include="OAuth2\Messages\ScopedAccessTokenRequest.cs" />
<Compile Include="OAuth2\Messages\UnauthorizedResponse.cs" />
<Compile Include="OAuth2\Messages\AccessTokenFailedResponse.cs" />
<Compile Include="OAuth2\Messages\AccessTokenSuccessResponse.cs" />
diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
index 4be9eb5..8fc691f 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
@@ -421,10 +421,10 @@ namespace DotNetOpenAuth.Messaging {
string prefix = scheme + " ";
if (authorizationHeader != null) {
// The authorization header may have multiple sections. Look for the appropriate one.
- string[] authorizationSections = authorizationHeader.Split(';'); // TODO: is this the right delimiter?
+ string[] authorizationSections = new string[] { authorizationHeader }; // what is the right delimiter, if any?
foreach (string authorization in authorizationSections) {
string trimmedAuth = authorization.Trim();
- if (trimmedAuth.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) {
+ if (trimmedAuth.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { // RFC 2617 says this is case INsensitive
string data = trimmedAuth.Substring(prefix.Length);
return from element in data.Split(CommaArray)
let parts = element.Split(EqualsArray, 2)
diff --git a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs
index ea8be94..e95835c 100644
--- a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs
+++ b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs
@@ -187,12 +187,11 @@ namespace DotNetOpenAuth.OAuth2 {
var client = this.AuthorizationServerServices.GetClientOrThrow(authorizationRequest.ClientIdentifier);
EndUserAuthorizationSuccessResponseBase response;
- switch (EndUserAuthorizationRequest.ResponseType) {
- case EndUserAuthorizationResponseTypes.AccessToken:
+ switch (authorizationRequest.ResponseType) {
+ case EndUserAuthorizationResponseType.AccessToken:
response = new EndUserAuthorizationSuccessAccessTokenResponse(callback, authorizationRequest);
break;
- case EndUserAuthorizationResponseTypes.Both:
- case EndUserAuthorizationResponseTypes.AuthorizationCode:
+ case EndUserAuthorizationResponseType.AuthorizationCode:
response = new EndUserAuthorizationSuccessAuthCodeResponse(callback, authorizationRequest);
break;
default:
@@ -221,7 +220,7 @@ namespace DotNetOpenAuth.OAuth2 {
Contract.Requires<ArgumentNullException>(request != null);
Contract.Requires<ArgumentNullException>(accessTokenEncryptingPublicKey != null);
- var tokenRequest = (ITokenCarryingRequest)request;
+ var tokenRequest = (IAuthorizationCarryingRequest)request;
using (var crypto = this.AuthorizationServerServices.CreateAccessTokenSigningCryptoServiceProvider()) {
var accessTokenFormatter = AccessToken.CreateFormatter(crypto, accessTokenEncryptingPublicKey);
var accessToken = new AccessToken(tokenRequest.AuthorizationDescription, accessTokenLifetime);
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs
index b772c0e..0210bd1 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs
@@ -53,7 +53,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
/// </remarks>
public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
- var response = message as ITokenCarryingRequest;
+ var response = message as IAuthorizationCarryingRequest;
if (response != null) {
switch (response.CodeOrTokenType) {
case CodeOrTokenType.AuthorizationCode:
@@ -72,7 +72,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
if (accessTokenResponse != null) {
var directResponseMessage = (IDirectResponseProtocolMessage)accessTokenResponse;
var accessTokenRequest = (AccessTokenRequestBase)directResponseMessage.OriginatingRequest;
- ErrorUtilities.VerifyProtocol(accessTokenRequest.GrantType != GrantType.None || accessTokenResponse.RefreshToken == null, OAuthStrings.NoGrantNoRefreshToken);
+ ErrorUtilities.VerifyProtocol(accessTokenRequest.GrantType != GrantType.ClientCredentials || accessTokenResponse.RefreshToken == null, OAuthStrings.NoGrantNoRefreshToken);
}
return null;
@@ -96,7 +96,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
/// </remarks>
public override MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
- var tokenRequest = message as ITokenCarryingRequest;
+ var tokenRequest = message as IAuthorizationCarryingRequest;
if (tokenRequest != null) {
try {
switch (tokenRequest.CodeOrTokenType) {
@@ -124,10 +124,13 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
// Check that the client secret is correct.
var client = this.AuthorizationServer.GetClientOrThrow(accessRequest.ClientIdentifier);
- ErrorUtilities.VerifyProtocol(string.Equals(client.Secret, accessRequest.ClientSecret, StringComparison.Ordinal), Protocol.incorrect_client_credentials);
+ ErrorUtilities.VerifyProtocol(MessagingUtilities.EqualsConstantTime(client.Secret, accessRequest.ClientSecret), Protocol.incorrect_client_credentials);
- // Make sure the scope the client is requesting does not exceed the scope in the grant.
- ErrorUtilities.VerifyProtocol(accessRequest.Scope.IsSubsetOf(tokenRequest.AuthorizationDescription.Scope), OAuthStrings.AccessScopeExceedsGrantScope, accessRequest.Scope, tokenRequest.AuthorizationDescription.Scope);
+ var scopedAccessRequest = accessRequest as ScopedAccessTokenRequest;
+ if (scopedAccessRequest != null) {
+ // Make sure the scope the client is requesting does not exceed the scope in the grant.
+ ErrorUtilities.VerifyProtocol(scopedAccessRequest.Scope.IsSubsetOf(tokenRequest.AuthorizationDescription.Scope), OAuthStrings.AccessScopeExceedsGrantScope, scopedAccessRequest.Scope, tokenRequest.AuthorizationDescription.Scope);
+ }
}
// Make sure the authorization this token represents hasn't already been revoked.
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs
index 58f3d42..31322a0 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs
@@ -59,7 +59,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
if (response != null) {
var directResponse = (IDirectResponseProtocolMessage)response;
var request = (EndUserAuthorizationRequest)directResponse.OriginatingRequest;
- ITokenCarryingRequest tokenCarryingResponse = response;
+ IAuthorizationCarryingRequest tokenCarryingResponse = response;
tokenCarryingResponse.AuthorizationDescription = new AuthorizationCode(request.ClientIdentifier, request.Callback, request.Scope, response.AuthorizingUsername);
return MessageProtections.None;
@@ -88,7 +88,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
public override MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
var request = message as AccessTokenAuthorizationCodeRequest;
if (request != null) {
- ITokenCarryingRequest tokenRequest = request;
+ IAuthorizationCarryingRequest tokenRequest = request;
((AuthorizationCode)tokenRequest.AuthorizationDescription).VerifyCallback(request.Callback);
return MessageProtections.None;
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs
index 33986c7..139025d 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs
@@ -30,14 +30,12 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// The <paramref name="value"/> in string form, ready for message transport.
/// </returns>
public string Encode(object value) {
- var responseType = (EndUserAuthorizationResponseTypes)value;
+ var responseType = (EndUserAuthorizationResponseType)value;
switch (responseType)
{
- case EndUserAuthorizationResponseTypes.Both:
- return Protocol.ResponseTypes.CodeAndToken;
- case EndUserAuthorizationResponseTypes.AccessToken:
+ case EndUserAuthorizationResponseType.AccessToken:
return Protocol.ResponseTypes.Token;
- case EndUserAuthorizationResponseTypes.AuthorizationCode:
+ case EndUserAuthorizationResponseType.AuthorizationCode:
return Protocol.ResponseTypes.Code;
default:
throw ErrorUtilities.ThrowFormat(MessagingStrings.UnexpectedMessagePartValue, Protocol.response_type, value);
@@ -54,12 +52,10 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// <exception cref="FormatException">Thrown when the string value given cannot be decoded into the required object type.</exception>
public object Decode(string value) {
switch (value) {
- case Protocol.ResponseTypes.CodeAndToken:
- return EndUserAuthorizationResponseTypes.Both;
case Protocol.ResponseTypes.Token:
- return EndUserAuthorizationResponseTypes.AccessToken;
+ return EndUserAuthorizationResponseType.AccessToken;
case Protocol.ResponseTypes.Code:
- return EndUserAuthorizationResponseTypes.AuthorizationCode;
+ return EndUserAuthorizationResponseType.AuthorizationCode;
default:
throw ErrorUtilities.ThrowFormat(MessagingStrings.UnexpectedMessagePartValue, Protocol.response_type, value);
}
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/GrantTypeEncoder.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/GrantTypeEncoder.cs
index bd1c614..78ed975 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/GrantTypeEncoder.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/GrantTypeEncoder.cs
@@ -33,8 +33,8 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
var responseType = (GrantType)value;
switch (responseType)
{
- case GrantType.None:
- return Protocol.GrantTypes.None;
+ case GrantType.ClientCredentials:
+ return Protocol.GrantTypes.ClientCredentials;
case GrantType.AuthorizationCode:
return Protocol.GrantTypes.AuthorizationCode;
case GrantType.RefreshToken:
@@ -58,8 +58,8 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// <exception cref="FormatException">Thrown when the string value given cannot be decoded into the required object type.</exception>
public object Decode(string value) {
switch (value) {
- case Protocol.GrantTypes.None:
- return GrantType.None;
+ case Protocol.GrantTypes.ClientCredentials:
+ return GrantType.ClientCredentials;
case Protocol.GrantTypes.Assertion:
return GrantType.Assertion;
case Protocol.GrantTypes.Password:
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/ITokenCarryingRequest.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/IAuthorizationCarryingRequest.cs
index 4c8d33f..e450131 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/ITokenCarryingRequest.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/IAuthorizationCarryingRequest.cs
@@ -1,5 +1,5 @@
//-----------------------------------------------------------------------
-// <copyright file="ITokenCarryingRequest.cs" company="Andrew Arnott">
+// <copyright file="IAuthorizationCarryingRequest.cs" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
@@ -33,7 +33,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// <summary>
/// A message that carries some kind of token from the client to the authorization or resource server.
/// </summary>
- internal interface ITokenCarryingRequest : IDirectedProtocolMessage {
+ internal interface IAuthorizationCarryingRequest : IDirectedProtocolMessage {
/// <summary>
/// Gets or sets the verification code or refresh/access token.
/// </summary>
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2ChannelBase.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2ChannelBase.cs
index d53e7ef..a646f51 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2ChannelBase.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2ChannelBase.cs
@@ -24,7 +24,6 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
typeof(AccessTokenRefreshRequest),
typeof(AccessTokenAuthorizationCodeRequest),
typeof(AccessTokenResourceOwnerPasswordCredentialsRequest),
- typeof(AccessTokenAssertionRequest),
typeof(AccessTokenClientCredentialsRequest),
typeof(AccessTokenSuccessResponse),
typeof(AccessTokenFailedResponse),
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2ResourceServerChannel.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2ResourceServerChannel.cs
index 60e464c..a292977 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2ResourceServerChannel.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2ResourceServerChannel.cs
@@ -49,39 +49,11 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// The deserialized message, if one is found. Null otherwise.
/// </returns>
protected override IDirectedProtocolMessage ReadFromRequestCore(HttpRequestInfo request) {
- // First search the Authorization header.
- var fields = MessagingUtilities.ParseAuthorizationHeader(
- Protocol.HttpAuthorizationScheme,
- request.Headers[HttpRequestHeader.Authorization]).ToDictionary();
-
- // Failing that, try the query string (for GET or POST or any other method)
- if (fields.Count == 0) {
- if (request.QueryStringBeforeRewriting["oauth_token"] != null) {
- // We're only interested in the oauth_token parameter -- not the others that can appear in an Authorization header.
- // Note that we intentionally change the name of the key here
- // because depending on the method used to obtain the token, the token's key changes
- // but we need to consolidate to one name so it works with the rest of the system.
- fields.Add("token", request.QueryStringBeforeRewriting["oauth_token"]);
- }
- }
-
- // Failing that, scan the entity
- if (fields.Count == 0) {
- // The spec calls out that this is allowed only for these three HTTP methods.
- if (request.HttpMethod == "POST" || request.HttpMethod == "DELETE" || request.HttpMethod == "PUT") {
- if (!string.IsNullOrEmpty(request.Headers[HttpRequestHeader.ContentType])) {
- var contentType = new ContentType(request.Headers[HttpRequestHeader.ContentType]);
- if (string.Equals(contentType.MediaType, HttpFormUrlEncoded, StringComparison.Ordinal)) {
- if (request.Form["oauth_token"] != null) {
- // We're only interested in the oauth_token parameter -- not the others that can appear in an Authorization header.
- // Note that we intentionally change the name of the key here
- // because depending on the method used to obtain the token, the token's key changes
- // but we need to consolidate to one name so it works with the rest of the system.
- fields.Add("token", request.Form["oauth_token"]);
- }
- }
- }
- }
+ var fields = new Dictionary<string, string>();
+ string accessToken;
+ if ((accessToken = SearchForBearerAccessTokenInRequest(request)) != null) {
+ fields["token_type"] = Protocol.AccessTokenTypes.Bearer;
+ fields["access_token"] = accessToken;
}
if (fields.Count > 0) {
@@ -93,9 +65,6 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
return null;
}
- // TODO: remove this after signatures are supported.
- ErrorUtilities.VerifyProtocol(!fields.ContainsKey("signature"), "OAuth signatures not supported yet.");
-
// Deserialize the message using all the data we've collected.
var message = (IDirectedProtocolMessage)this.Receive(fields, recipient);
return message;
@@ -145,8 +114,44 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
// Now serialize all the message parts into the WWW-Authenticate header.
var fields = this.MessageDescriptions.GetAccessor(response);
- webResponse.Headers[HttpResponseHeader.WwwAuthenticate] = MessagingUtilities.AssembleAuthorizationHeader(Protocol.HttpAuthorizationScheme, fields);
+ webResponse.Headers[HttpResponseHeader.WwwAuthenticate] = MessagingUtilities.AssembleAuthorizationHeader(Protocol.BearerHttpAuthorizationScheme, fields);
return webResponse;
}
+
+ /// <summary>
+ /// Searches for a bearer access token in the request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <returns>The bearer access token, if one exists. Otherwise <c>null</c>.</returns>
+ private static string SearchForBearerAccessTokenInRequest(HttpRequestInfo request) {
+ Contract.Requires<ArgumentNullException>(request != null, "request");
+
+ // First search the authorization header.
+ string authorizationHeader = request.Headers[HttpRequestHeader.Authorization];
+ if (authorizationHeader.StartsWith(Protocol.BearerHttpAuthorizationSchemeWithTrailingSpace, StringComparison.OrdinalIgnoreCase)) {
+ return authorizationHeader.Substring(Protocol.BearerHttpAuthorizationSchemeWithTrailingSpace.Length);
+ }
+
+ // Failing that, scan the entity
+ if (!string.IsNullOrEmpty(request.Headers[HttpRequestHeader.ContentType])) {
+ var contentType = new ContentType(request.Headers[HttpRequestHeader.ContentType]);
+ if (string.Equals(contentType.MediaType, HttpFormUrlEncoded, StringComparison.Ordinal)) {
+ if (request.Form[Protocol.BearerTokenEncodedUrlParameterName] != null) {
+ // We're only interested in the oauth_token parameter -- not the others that can appear in an Authorization header.
+ // Note that we intentionally change the name of the key here
+ // because depending on the method used to obtain the token, the token's key changes
+ // but we need to consolidate to one name so it works with the rest of the system.
+ return request.Form[Protocol.BearerTokenEncodedUrlParameterName];
+ }
+ }
+ }
+
+ // Finally, check the least desirable location: the query string
+ if (!String.IsNullOrEmpty(request.QueryStringBeforeRewriting[Protocol.BearerTokenEncodedUrlParameterName])) {
+ return request.QueryStringBeforeRewriting[Protocol.BearerTokenEncodedUrlParameterName];
+ }
+
+ return null;
+ }
}
}
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/ScopeEncoder.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/ScopeEncoder.cs
index d35f982..7ae5fbf 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/ScopeEncoder.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/ScopeEncoder.cs
@@ -33,7 +33,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
public string Encode(object value) {
var scopes = (IEnumerable<string>)value;
ErrorUtilities.VerifyProtocol(!scopes.Any(scope => scope.Contains(" ")), OAuthStrings.ScopesMayNotContainSpaces);
- return scopes != null ? string.Join(" ", scopes.ToArray()) : null;
+ return (scopes != null && scopes.Any()) ? string.Join(" ", scopes.ToArray()) : null;
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OAuth2/ClientBase.cs b/src/DotNetOpenAuth/OAuth2/ClientBase.cs
index 045fdf2..f91b1f5 100644
--- a/src/DotNetOpenAuth/OAuth2/ClientBase.cs
+++ b/src/DotNetOpenAuth/OAuth2/ClientBase.cs
@@ -66,7 +66,7 @@ namespace DotNetOpenAuth.OAuth2 {
Contract.Requires<ArgumentNullException>(request != null);
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(accessToken));
- OAuthUtilities.AuthorizeWithOAuthWrap(request, accessToken);
+ OAuthUtilities.AuthorizeWithBearerToken(request, accessToken);
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessProtectedResourceRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessProtectedResourceRequest.cs
index 410592f..2e94156 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessProtectedResourceRequest.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessProtectedResourceRequest.cs
@@ -15,7 +15,12 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// <summary>
/// A message that accompanies an HTTP request to a resource server that provides authorization.
/// </summary>
- internal class AccessProtectedResourceRequest : MessageBase, ITokenCarryingRequest {
+ /// <remarks>
+ /// In its current form, this class only accepts bearer access tokens.
+ /// When support for additional access token types is added, this class should probably be refactored
+ /// into derived types, where each derived type supports a particular access token type.
+ /// </remarks>
+ internal class AccessProtectedResourceRequest : MessageBase, IAuthorizationCarryingRequest {
/// <summary>
/// Initializes a new instance of the <see cref="AccessProtectedResourceRequest"/> class.
/// </summary>
@@ -29,7 +34,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets the type of the code or token.
/// </summary>
/// <value>The type of the code or token.</value>
- CodeOrTokenType ITokenCarryingRequest.CodeOrTokenType {
+ CodeOrTokenType IAuthorizationCarryingRequest.CodeOrTokenType {
get { return CodeOrTokenType.AccessToken; }
}
@@ -37,7 +42,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets or sets the verification code or refresh/access token.
/// </summary>
/// <value>The code or token.</value>
- string ITokenCarryingRequest.CodeOrToken {
+ string IAuthorizationCarryingRequest.CodeOrToken {
get { return this.AccessToken; }
set { this.AccessToken = value; }
}
@@ -45,75 +50,24 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// <summary>
/// Gets or sets the authorization that the token describes.
/// </summary>
- IAuthorizationDescription ITokenCarryingRequest.AuthorizationDescription { get; set; }
+ IAuthorizationDescription IAuthorizationCarryingRequest.AuthorizationDescription { get; set; }
/// <summary>
- /// Gets or sets the access token.
- /// </summary>
- /// <value>The access token.</value>
- [MessagePart("token", IsRequired = true)]
- internal string AccessToken { get; set; }
-
- /// <summary>
- /// Gets or sets the nonce.
- /// </summary>
- /// <value>The nonce.</value>
- [MessagePart("nonce")]
- internal string Nonce { get; set; }
-
- /// <summary>
- /// Gets or sets the timestamp.
- /// </summary>
- /// <value>The timestamp.</value>
- [MessagePart("timestamp", Encoder = typeof(TimestampEncoder))]
- internal DateTime? Timestamp { get; set; }
-
- /// <summary>
- /// Gets or sets the signature.
+ /// Gets the type of the access token.
/// </summary>
- /// <value>The signature.</value>
- [MessagePart("signature")]
- internal string Signature { get; set; }
-
- /// <summary>
- /// Gets or sets the algorithm.
- /// </summary>
- /// <value>The algorithm.</value>
- [MessagePart("algorithm")]
- internal string Algorithm { get; set; }
-
- /// <summary>
- /// Gets a value indicating whether this request is signed.
- /// </summary>
- internal bool SignedRequest {
- get { return this.Signature != null; }
+ /// <value>
+ /// Always "bearer".
+ /// </value>
+ [MessagePart("token_type", IsRequired = true)]
+ internal string TokenType {
+ get { return Protocol.AccessTokenTypes.Bearer; }
}
/// <summary>
- /// Checks the message state for conformity to the protocol specification
- /// and throws an exception if the message is invalid.
+ /// Gets or sets the access token.
/// </summary>
- /// <remarks>
- /// <para>Some messages have required fields, or combinations of fields that must relate to each other
- /// in specialized ways. After deserializing a message, this method checks the state of the
- /// message to see if it conforms to the protocol.</para>
- /// <para>Note that this property should <i>not</i> check signatures or perform any state checks
- /// outside this scope of this particular message.</para>
- /// </remarks>
- /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception>
- protected override void EnsureValidMessage() {
- base.EnsureValidMessage();
-
- // If any of the optional parameters are present, all of them are required.
- if (this.Signature == null) {
- ErrorUtilities.VerifyProtocol(this.Algorithm == null, this, MessagingStrings.UnexpectedMessagePartValue, "algorithm", this.Algorithm);
- ErrorUtilities.VerifyProtocol(!this.Timestamp.HasValue, this, MessagingStrings.UnexpectedMessagePartValue, "timestamp", this.Timestamp);
- ErrorUtilities.VerifyProtocol(this.Nonce == null, this, MessagingStrings.UnexpectedMessagePartValue, "nonce", this.Nonce);
- } else {
- ErrorUtilities.VerifyProtocol(this.Algorithm != null, this, MessagingStrings.RequiredParametersMissing, "algorithm");
- ErrorUtilities.VerifyProtocol(this.Timestamp.HasValue, this, MessagingStrings.RequiredParametersMissing, "timestamp");
- ErrorUtilities.VerifyProtocol(this.Nonce != null, this, MessagingStrings.RequiredParametersMissing, "nonce");
- }
- }
+ /// <value>The access token.</value>
+ [MessagePart("access_token", IsRequired = true)]
+ internal string AccessToken { get; set; }
}
}
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAssertionRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAssertionRequest.cs
deleted file mode 100644
index fa50f6b..0000000
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAssertionRequest.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="AccessTokenAssertionRequest.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth2.Messages {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// A request from a Client to an Authorization Server to exchange some assertion for an access token.
- /// </summary>
- internal class AccessTokenAssertionRequest : AccessTokenRequestBase {
- /// <summary>
- /// Initializes a new instance of the <see cref="AccessTokenAssertionRequest"/> class.
- /// </summary>
- /// <param name="tokenEndpoint">The Authorization Server's access token endpoint URL.</param>
- /// <param name="version">The version.</param>
- internal AccessTokenAssertionRequest(Uri tokenEndpoint, Version version)
- : base(tokenEndpoint, version) {
- }
-
- /// <summary>
- /// Gets or sets the format of the assertion as defined by the Authorization Server.
- /// </summary>
- /// <value>The assertion format.</value>
- [MessagePart(Protocol.assertion_type, IsRequired = true)]
- internal Uri AssertionType { get; set; }
-
- /// <summary>
- /// Gets or sets the assertion.
- /// </summary>
- /// <value>The assertion.</value>
- [MessagePart(Protocol.assertion, IsRequired = true)]
- internal string Assertion { get; set; }
-
- /// <summary>
- /// Gets the type of the grant.
- /// </summary>
- /// <value>The type of the grant.</value>
- internal override GrantType GrantType {
- get { return GrantType.Assertion; }
- }
- }
-}
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs
index 3c7202e..b45b7ad 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs
@@ -17,7 +17,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// <summary>
/// A request from a Client to an Authorization Server to exchange an authorization code for an access token.
/// </summary>
- internal class AccessTokenAuthorizationCodeRequest : AccessTokenRequestBase, ITokenCarryingRequest {
+ internal class AccessTokenAuthorizationCodeRequest : AccessTokenRequestBase, IAuthorizationCarryingRequest {
/// <summary>
/// Initializes a new instance of the <see cref="AccessTokenAuthorizationCodeRequest"/> class.
/// </summary>
@@ -41,7 +41,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets the type of the code or token.
/// </summary>
/// <value>The type of the code or token.</value>
- CodeOrTokenType ITokenCarryingRequest.CodeOrTokenType {
+ CodeOrTokenType IAuthorizationCarryingRequest.CodeOrTokenType {
get { return CodeOrTokenType.AuthorizationCode; }
}
@@ -49,7 +49,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets or sets the verification code or refresh/access token.
/// </summary>
/// <value>The code or token.</value>
- string ITokenCarryingRequest.CodeOrToken {
+ string IAuthorizationCarryingRequest.CodeOrToken {
get { return this.AuthorizationCode; }
set { this.AuthorizationCode = value; }
}
@@ -57,7 +57,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// <summary>
/// Gets or sets the authorization that the token describes.
/// </summary>
- IAuthorizationDescription ITokenCarryingRequest.AuthorizationDescription { get; set; }
+ IAuthorizationDescription IAuthorizationCarryingRequest.AuthorizationDescription { get; set; }
/// <summary>
/// Gets the type of the grant.
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenClientCredentialsRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenClientCredentialsRequest.cs
index 475a170..01e1633 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenClientCredentialsRequest.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenClientCredentialsRequest.cs
@@ -19,7 +19,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// <remarks>
/// This is somewhat analogous to 2-legged OAuth.
/// </remarks>
- internal class AccessTokenClientCredentialsRequest : AccessTokenRequestBase {
+ internal class AccessTokenClientCredentialsRequest : ScopedAccessTokenRequest {
/// <summary>
/// Initializes a new instance of the <see cref="AccessTokenClientCredentialsRequest"/> class.
/// </summary>
@@ -35,7 +35,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// </summary>
/// <value>The type of the grant.</value>
internal override GrantType GrantType {
- get { return Messages.GrantType.None; }
+ get { return Messages.GrantType.ClientCredentials; }
}
}
}
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs
index c193392..22354e4 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.OAuth2.Messages {
using System;
+ using System.Collections.Generic;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth2.ChannelElements;
@@ -13,7 +14,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// A request from the client to the token endpoint for a new access token
/// in exchange for a refresh token that the client has previously obtained.
/// </summary>
- internal class AccessTokenRefreshRequest : AccessTokenRequestBase, ITokenCarryingRequest {
+ internal class AccessTokenRefreshRequest : ScopedAccessTokenRequest, IAuthorizationCarryingRequest {
/// <summary>
/// Initializes a new instance of the <see cref="AccessTokenRefreshRequest"/> class.
/// </summary>
@@ -35,7 +36,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets the type of the code or token.
/// </summary>
/// <value>The type of the code or token.</value>
- CodeOrTokenType ITokenCarryingRequest.CodeOrTokenType {
+ CodeOrTokenType IAuthorizationCarryingRequest.CodeOrTokenType {
get { return CodeOrTokenType.RefreshToken; }
}
@@ -43,7 +44,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets or sets the verification code or refresh/access token.
/// </summary>
/// <value>The code or token.</value>
- string ITokenCarryingRequest.CodeOrToken {
+ string IAuthorizationCarryingRequest.CodeOrToken {
get { return this.RefreshToken; }
set { this.RefreshToken = value; }
}
@@ -51,7 +52,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// <summary>
/// Gets or sets the authorization that the token describes.
/// </summary>
- IAuthorizationDescription ITokenCarryingRequest.AuthorizationDescription { get; set; }
+ IAuthorizationDescription IAuthorizationCarryingRequest.AuthorizationDescription { get; set; }
/// <summary>
/// Gets or sets the refresh token.
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRequestBase.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRequestBase.cs
index 55387a6..a71dc70 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRequestBase.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRequestBase.cs
@@ -25,7 +25,6 @@ namespace DotNetOpenAuth.OAuth2.Messages {
protected AccessTokenRequestBase(Uri tokenEndpoint, Version version)
: base(tokenEndpoint, version) {
this.HttpMethods = HttpDeliveryMethods.PostRequest;
- this.Scope = new HashSet<string>(OAuthUtilities.ScopeStringComparer);
}
/// <summary>
@@ -36,13 +35,6 @@ namespace DotNetOpenAuth.OAuth2.Messages {
internal abstract GrantType GrantType { get; }
/// <summary>
- /// Gets the set of scopes the Client would like the access token to provide access to.
- /// </summary>
- /// <value>A set of scopes. Never null.</value>
- [MessagePart(Protocol.scope, IsRequired = false, Encoder = typeof(ScopeEncoder))]
- internal HashSet<string> Scope { get; private set; }
-
- /// <summary>
/// Checks the message state for conformity to the protocol specification
/// and throws an exception if the message is invalid.
/// </summary>
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenResourceOwnerPasswordCredentialsRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenResourceOwnerPasswordCredentialsRequest.cs
index ed22843..82febe9 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenResourceOwnerPasswordCredentialsRequest.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenResourceOwnerPasswordCredentialsRequest.cs
@@ -15,7 +15,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// <summary>
/// A request from a Client to an Authorization Server to exchange the user's username and password for an access token.
/// </summary>
- internal class AccessTokenResourceOwnerPasswordCredentialsRequest : AccessTokenRequestBase {
+ internal class AccessTokenResourceOwnerPasswordCredentialsRequest : ScopedAccessTokenRequest {
/// <summary>
/// Initializes a new instance of the <see cref="AccessTokenResourceOwnerPasswordCredentialsRequest"/> class.
/// </summary>
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenSuccessResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenSuccessResponse.cs
index bae2dd9..b7d8dea 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenSuccessResponse.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenSuccessResponse.cs
@@ -26,6 +26,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
internal AccessTokenSuccessResponse(AccessTokenRequestBase request)
: base(request) {
this.Scope = new HashSet<string>(OAuthUtilities.ScopeStringComparer);
+ this.TokenType = Protocol.AccessTokenTypes.Bearer;
}
/// <summary>
@@ -57,6 +58,16 @@ namespace DotNetOpenAuth.OAuth2.Messages {
public string AccessToken { get; internal set; }
/// <summary>
+ /// Gets or sets the token type.
+ /// </summary>
+ /// <value>Usually "bearer".</value>
+ /// <remarks>
+ /// Described in OAuth 2.0 section 7.1.
+ /// </remarks>
+ [MessagePart(Protocol.token_type, IsRequired = true)]
+ public string TokenType { get; internal set; }
+
+ /// <summary>
/// Gets or sets the lifetime of the access token.
/// </summary>
/// <value>The lifetime.</value>
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs
index fc11831..5497e1b 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs
@@ -42,7 +42,15 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// <summary>
/// Gets or sets the error.
/// </summary>
- /// <value>One of the values given in <see cref="Protocol.EndUserAuthorizationRequestErrorCodes"/>.</value>
+ /// <value>
+ /// One of the values given in <see cref="Protocol.EndUserAuthorizationRequestErrorCodes"/>.
+ /// OR a numerical HTTP status code from the 4xx or 5xx
+ /// range, with the exception of the 400 (Bad Request) and
+ /// 401 (Unauthorized) status codes. For example, if the
+ /// service is temporarily unavailable, the authorization
+ /// server MAY return an error response with "error" set to
+ /// "503".
+ /// </value>
[MessagePart(Protocol.error, IsRequired = true)]
public string Error { get; set; }
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationRequest.cs
index fa270ee..802aed6 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationRequest.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationRequest.cs
@@ -31,6 +31,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
Contract.Requires<ArgumentNullException>(version != null);
this.HttpMethods = HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.PostRequest;
this.Scope = new HashSet<string>(OAuthUtilities.ScopeStringComparer);
+ this.ResponseType = EndUserAuthorizationResponseType.AuthorizationCode;
}
/// <summary>
@@ -45,14 +46,11 @@ namespace DotNetOpenAuth.OAuth2.Messages {
}
/// <summary>
- /// Gets the grant type that the client expects of the authorization server.
+ /// Gets or sets the grant type that the client expects of the authorization server.
/// </summary>
- /// <value>Always <see cref="EndUserAuthorizationResponseTypes.AuthorizationCode"/>. Other response types are not supported.</value>
+ /// <value>Always <see cref="EndUserAuthorizationResponseType.AuthorizationCode"/>. Other response types are not supported.</value>
[MessagePart(Protocol.response_type, IsRequired = true, Encoder = typeof(EndUserAuthorizationResponseTypeEncoder))]
- public static EndUserAuthorizationResponseTypes ResponseType
- {
- get { return EndUserAuthorizationResponseTypes.AuthorizationCode; }
- }
+ public EndUserAuthorizationResponseType ResponseType { get; set; }
/// <summary>
/// Gets or sets the identifier by which this client is known to the Authorization Server.
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationResponseType.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationResponseType.cs
index 814f625..815fef6 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationResponseType.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationResponseType.cs
@@ -11,21 +11,15 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// An indication of what kind of response the client is requesting from the authorization server
/// after the user has granted authorized access.
/// </summary>
- [Flags]
- public enum EndUserAuthorizationResponseTypes {
+ public enum EndUserAuthorizationResponseType {
/// <summary>
/// An access token should be returned immediately.
/// </summary>
- AccessToken = 0x1,
+ AccessToken,
/// <summary>
/// An authorization code should be returned, which can later be exchanged for refresh and access tokens.
/// </summary>
- AuthorizationCode = 0x2,
-
- /// <summary>
- /// Both an access token and an authorization code should be returned.
- /// </summary>
- Both = AccessToken | AuthorizationCode,
+ AuthorizationCode,
}
}
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs
index 46bbc87..f5edfa8 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs
@@ -19,7 +19,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// to indicate that user authorization was granted, carrying only an access token,
/// and to return the user to the Client where they started their experience.
/// </summary>
- internal class EndUserAuthorizationSuccessAccessTokenResponse : EndUserAuthorizationSuccessResponseBase, ITokenCarryingRequest {
+ internal class EndUserAuthorizationSuccessAccessTokenResponse : EndUserAuthorizationSuccessResponseBase, IAuthorizationCarryingRequest, IHttpIndirectResponse {
/// <summary>
/// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessAccessTokenResponse"/> class.
/// </summary>
@@ -49,7 +49,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets or sets the verification code or refresh/access token.
/// </summary>
/// <value>The code or token.</value>
- string ITokenCarryingRequest.CodeOrToken {
+ string IAuthorizationCarryingRequest.CodeOrToken {
get { return this.AccessToken; }
set { this.AccessToken = value; }
}
@@ -58,7 +58,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets the type of the code or token.
/// </summary>
/// <value>The type of the code or token.</value>
- CodeOrTokenType ITokenCarryingRequest.CodeOrTokenType {
+ CodeOrTokenType IAuthorizationCarryingRequest.CodeOrTokenType {
get { return CodeOrTokenType.AccessToken; }
}
@@ -66,15 +66,37 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets or sets the authorization that the token describes.
/// </summary>
/// <value></value>
- IAuthorizationDescription ITokenCarryingRequest.AuthorizationDescription { get; set; }
+ IAuthorizationDescription IAuthorizationCarryingRequest.AuthorizationDescription { get; set; }
#endregion
+ #region IHttpIndirectResponse Members
+
+ /// <summary>
+ /// Gets a value indicating whether the payload for the message should be included
+ /// in the redirect fragment instead of the query string or POST entity.
+ /// </summary>
+ bool IHttpIndirectResponse.Include301RedirectPayloadInFragment {
+ get { return true; }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Gets or sets the token type.
+ /// </summary>
+ /// <value>Usually "bearer".</value>
+ /// <remarks>
+ /// Described in OAuth 2.0 section 7.1.
+ /// </remarks>
+ [MessagePart(Protocol.token_type, IsRequired = true)]
+ public string TokenType { get; internal set; }
+
/// <summary>
/// Gets or sets the access token.
/// </summary>
/// <value>The access token.</value>
[MessagePart(Protocol.access_token, IsRequired = true)]
- internal string AccessToken { get; set; }
+ public string AccessToken { get; set; }
}
}
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs
index 6302304..af7f913 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs
@@ -16,7 +16,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// to indicate that user authorization was granted, carrying an authorization code and possibly an access token,
/// and to return the user to the Client where they started their experience.
/// </summary>
- internal class EndUserAuthorizationSuccessAuthCodeResponse : EndUserAuthorizationSuccessResponseBase, ITokenCarryingRequest {
+ internal class EndUserAuthorizationSuccessAuthCodeResponse : EndUserAuthorizationSuccessResponseBase, IAuthorizationCarryingRequest {
/// <summary>
/// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessAuthCodeResponse"/> class.
/// </summary>
@@ -46,7 +46,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets or sets the verification code or refresh/access token.
/// </summary>
/// <value>The code or token.</value>
- string ITokenCarryingRequest.CodeOrToken {
+ string IAuthorizationCarryingRequest.CodeOrToken {
get { return this.AuthorizationCode; }
set { this.AuthorizationCode = value; }
}
@@ -55,14 +55,14 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets the type of the code or token.
/// </summary>
/// <value>The type of the code or token.</value>
- CodeOrTokenType ITokenCarryingRequest.CodeOrTokenType {
+ CodeOrTokenType IAuthorizationCarryingRequest.CodeOrTokenType {
get { return CodeOrTokenType.AuthorizationCode; }
}
/// <summary>
/// Gets or sets the authorization that the token describes.
/// </summary>
- IAuthorizationDescription ITokenCarryingRequest.AuthorizationDescription { get; set; }
+ IAuthorizationDescription IAuthorizationCarryingRequest.AuthorizationDescription { get; set; }
#endregion
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/GrantType.cs b/src/DotNetOpenAuth/OAuth2/Messages/GrantType.cs
index c119ffd..4580a7f 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/GrantType.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/GrantType.cs
@@ -37,6 +37,6 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// <remarks>
/// When requesting an access token using the none access grant type (no access grant is included), the client is requesting access to the protected resources under its control, or those of another resource owner which has been previously arranged with the authorization server (the method of which is beyond the scope of this specification).
/// </remarks>
- None,
+ ClientCredentials,
}
}
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/OAuth 2 Messages.cd b/src/DotNetOpenAuth/OAuth2/Messages/OAuth 2 Messages.cd
index 86a0335..9ddd0cc 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/OAuth 2 Messages.cd
+++ b/src/DotNetOpenAuth/OAuth2/Messages/OAuth 2 Messages.cd
@@ -1,68 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<ClassDiagram MajorVersion="1" MinorVersion="1">
<Class Name="DotNetOpenAuth.OAuth2.Messages.MessageBase" Collapsed="true">
- <Position X="0.5" Y="4" Width="1.5" />
+ <Position X="0.5" Y="0.5" Width="1.5" />
<TypeIdentifier>
<HashCode>IAAMACQAQAAAgAkAAAAIAAYACgAAIAAAIACAACAAAIA=</HashCode>
<FileName>OAuth2\Messages\MessageBase.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
- <Class Name="DotNetOpenAuth.OAuth2.Messages.AccessTokenAssertionRequest" Collapsed="true">
- <Position X="11" Y="5.5" Width="2.25" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.AccessTokenRequestBase" ManuallyRouted="true" FixedFromPoint="true">
- <Path>
- <Point X="9.75" Y="7.562" />
- <Point X="10.771" Y="7.562" />
- <Point X="10.771" Y="5.846" />
- <Point X="11" Y="5.846" />
- </Path>
- </InheritanceLine>
- <TypeIdentifier>
- <HashCode>AAAIAAAAAAAAAAAAAgAAAAAQAAAAAAAAAAAAAAAAAAA=</HashCode>
- <FileName>OAuth2\Messages\AccessTokenAssertionRequest.cs</FileName>
- </TypeIdentifier>
- </Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.AccessTokenAuthorizationCodeRequest" Collapsed="true">
- <Position X="11" Y="6.5" Width="3" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.AccessTokenRequestBase" ManuallyRouted="true" FixedFromPoint="true">
- <Path>
- <Point X="9.75" Y="7.562" />
- <Point X="10.781" Y="7.562" />
- <Point X="10.781" Y="6.846" />
- <Point X="11" Y="6.846" />
- </Path>
- </InheritanceLine>
+ <Position X="6.75" Y="6.75" Width="3" />
<TypeIdentifier>
- <HashCode>CCAAAAAAAAACAAAAAAAAAAAQAAAAAAAAAAAAAAAAQAA=</HashCode>
+ <HashCode>ACAAEAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAgAAAARAA=</HashCode>
<FileName>OAuth2\Messages\AccessTokenAuthorizationCodeRequest.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.AccessTokenClientCredentialsRequest" Collapsed="true">
- <Position X="11" Y="3.75" Width="2.75" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.AccessTokenRequestBase" FixedFromPoint="true">
- <Path>
- <Point X="9.75" Y="7.562" />
- <Point X="10.76" Y="7.562" />
- <Point X="10.76" Y="4.096" />
- <Point X="11" Y="4.096" />
- </Path>
- </InheritanceLine>
+ <Position X="8.5" Y="8.75" Width="2.75" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>OAuth2\Messages\AccessTokenClientCredentialsRequest.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.AccessTokenFailedResponse" Collapsed="true">
- <Position X="3.25" Y="1.75" Width="2.25" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.MessageBase" FixedToPoint="true">
- <Path>
- <Point X="1.25" Y="4" />
- <Point X="1.25" Y="2.062" />
- <Point X="3.25" Y="2.062" />
- </Path>
- </InheritanceLine>
+ <Position X="3.25" Y="8.5" Width="2.25" />
<TypeIdentifier>
<HashCode>AAAAAIAAAAAAAQAAAABAAAQAAAAAAAEQAAAAAAAAAAA=</HashCode>
<FileName>OAuth2\Messages\AccessTokenFailedResponse.cs</FileName>
@@ -70,87 +32,44 @@
<Lollipop Position="0.2" />
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.AccessTokenRefreshRequest" Collapsed="true">
- <Position X="11" Y="4.75" Width="2.25" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.AccessTokenRequestBase" FixedFromPoint="true">
- <Path>
- <Point X="9.75" Y="7.562" />
- <Point X="10.76" Y="7.562" />
- <Point X="10.76" Y="5.096" />
- <Point X="11" Y="5.096" />
- </Path>
- </InheritanceLine>
+ <Position X="8.5" Y="9.75" Width="2.25" />
<TypeIdentifier>
- <HashCode>CCAAAAAAQAACAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=</HashCode>
+ <HashCode>AAAAEAAAQAAAAAAAAAAAAAAQAAAAAAAAAAAgAAAABAA=</HashCode>
<FileName>OAuth2\Messages\AccessTokenRefreshRequest.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.AccessTokenRequestBase" Collapsed="true">
- <Position X="7.75" Y="7.25" Width="2" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.AuthenticatedClientRequestBase" FixedFromPoint="true">
- <Path>
- <Point X="5.5" Y="7.625" />
- <Point X="7.75" Y="7.625" />
- </Path>
- </InheritanceLine>
+ <Position X="5.75" Y="5.75" Width="2" />
<TypeIdentifier>
- <HashCode>AAAAAAAAQAAAACAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=</HashCode>
+ <HashCode>AAAAAAAAQAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>OAuth2\Messages\AccessTokenRequestBase.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.AccessTokenResourceOwnerPasswordCredentialsRequest" Collapsed="true">
- <Position X="11" Y="7.25" Width="4" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.AccessTokenRequestBase" ManuallyRouted="true" FixedFromPoint="true">
- <Path>
- <Point X="9.75" Y="7.562" />
- <Point X="10.711" Y="7.562" />
- <Point X="10.711" Y="7.752" />
- <Point X="11" Y="7.752" />
- </Path>
- </InheritanceLine>
+ <Position X="8.5" Y="10.5" Width="4" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAACAQAAAAAAAAA=</HashCode>
<FileName>OAuth2\Messages\AccessTokenResourceOwnerPasswordCredentialsRequest.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.AccessTokenSuccessResponse" Collapsed="true">
- <Position X="3.25" Y="2.75" Width="2.25" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.MessageBase" FixedToPoint="true">
- <Path>
- <Point X="1.25" Y="4" />
- <Point X="1.25" Y="3.125" />
- <Point X="3.25" Y="3.125" />
- </Path>
- </InheritanceLine>
+ <Position X="3.25" Y="7.5" Width="2.25" />
<TypeIdentifier>
- <HashCode>AAAAAAAAQAAAACAAAAAAAAQAEAAAAAAQAEAAAAAAAAA=</HashCode>
+ <HashCode>AAAAAAAAQAAAACAAAAAAAAQAEAAAAAAQAEAAAAAAAgA=</HashCode>
<FileName>OAuth2\Messages\AccessTokenSuccessResponse.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.AuthenticatedClientRequestBase" Collapsed="true">
- <Position X="3.25" Y="7.25" Width="2.25" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.MessageBase" FixedToPoint="true">
- <Path>
- <Point X="1.25" Y="4.562" />
- <Point X="1.25" Y="7.688" />
- <Point X="3.25" Y="7.688" />
- </Path>
- </InheritanceLine>
+ <Position X="3.25" Y="5.25" Width="2.25" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAA=</HashCode>
<FileName>OAuth2\Messages\AuthenticatedClientRequestBase.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationFailedResponse" Collapsed="true">
- <Position X="3.25" Y="6.5" Width="2.75" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.MessageBase" FixedToPoint="true">
- <Path>
- <Point X="1.25" Y="4.562" />
- <Point X="1.25" Y="6.875" />
- <Point X="3.25" Y="6.875" />
- </Path>
- </InheritanceLine>
+ <Position X="3.25" Y="4.5" Width="2.75" />
<TypeIdentifier>
<HashCode>AAAAAIAAAAAAAQAAAAAAAAgAAAAAAAEAAAAAAAAAAAA=</HashCode>
<FileName>OAuth2\Messages\EndUserAuthorizationFailedResponse.cs</FileName>
@@ -158,53 +77,30 @@
<Lollipop Position="0.2" />
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationRequest" Collapsed="true">
- <Position X="3.25" Y="5.5" Width="2.25" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.MessageBase" FixedToPoint="true">
- <Path>
- <Point X="1.25" Y="4.562" />
- <Point X="1.25" Y="5.812" />
- <Point X="3.25" Y="5.812" />
- </Path>
- </InheritanceLine>
+ <Position X="3.25" Y="0.5" Width="2.25" />
<TypeIdentifier>
<HashCode>AAAAAAAAQAAAACAAAAAAAACAAAQAAAQAAAAAAAAAQAA=</HashCode>
<FileName>OAuth2\Messages\EndUserAuthorizationRequest.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationSuccessAccessTokenResponse" Collapsed="true">
- <Position X="6.75" Y="4.25" Width="3.75" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationSuccessResponseBase" FixedFromPoint="true">
- <Path>
- <Point X="6" Y="4.062" />
- <Point X="6.375" Y="4.062" />
- <Point X="6.375" Y="4.596" />
- <Point X="6.75" Y="4.596" />
- </Path>
- </InheritanceLine>
+ <Position X="6.25" Y="3.75" Width="3.75" />
<TypeIdentifier>
- <HashCode>CCAAAAAAAAACAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAA=</HashCode>
+ <HashCode>AAAAEAAAAAAAAAAAAAAAAAACEAAAAAAAAAAgAAAABgA=</HashCode>
<FileName>OAuth2\Messages\EndUserAuthorizationSuccessAccessTokenResponse.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationSuccessAuthCodeResponse" Collapsed="true">
- <Position X="6.75" Y="3.25" Width="3.5" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationSuccessResponseBase" FixedFromPoint="true">
- <Path>
- <Point X="6" Y="4.062" />
- <Point X="6.375" Y="4.062" />
- <Point X="6.375" Y="3.596" />
- <Point X="6.75" Y="3.596" />
- </Path>
- </InheritanceLine>
+ <Position X="6.25" Y="2.5" Width="3.5" />
<TypeIdentifier>
- <HashCode>CCAAAAAAAAACAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAA=</HashCode>
+ <HashCode>ACAAEAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAgAAAABAA=</HashCode>
<FileName>OAuth2\Messages\EndUserAuthorizationSuccessAuthCodeResponse.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationSuccessResponseBase" Collapsed="true">
- <Position X="3.25" Y="3.75" Width="2.75" />
+ <Position X="3.25" Y="1.5" Width="2.75" />
<TypeIdentifier>
<HashCode>AAACAAAAAAAAACAAAAAAAAgAAAAAAAAAAEAAAAAAAAA=</HashCode>
<FileName>OAuth2\Messages\EndUserAuthorizationSuccessResponseBase.cs</FileName>
@@ -212,35 +108,28 @@
<Lollipop Position="0.2" />
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.AccessProtectedResourceRequest" Collapsed="true">
- <Position X="3.25" Y="4.75" Width="2.5" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.MessageBase" FixedToPoint="true">
- <Path>
- <Point X="1.25" Y="4.562" />
- <Point X="1.25" Y="5.125" />
- <Point X="3.25" Y="5.125" />
- </Path>
- </InheritanceLine>
+ <Position X="3.25" Y="9.75" Width="2.5" />
<TypeIdentifier>
- <HashCode>CCAAAAAAQAACAAAAAAACAAAAEAAAAAAAAAEAAAQACAE=</HashCode>
+ <HashCode>AAAAEAAAQAAAAAAAAAACAAAAEAAAAAAAAAEgAAQADAE=</HashCode>
<FileName>OAuth2\Messages\AccessProtectedResourceRequest.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Class Name="DotNetOpenAuth.OAuth2.Messages.UnauthorizedResponse" Collapsed="true">
- <Position X="3.25" Y="0.75" Width="2" />
- <InheritanceLine Type="DotNetOpenAuth.OAuth2.Messages.MessageBase" FixedToPoint="true">
- <Path>
- <Point X="1.25" Y="4" />
- <Point X="1.25" Y="1.125" />
- <Point X="3.25" Y="1.125" />
- </Path>
- </InheritanceLine>
+ <Position X="3.25" Y="10.75" Width="2" />
<TypeIdentifier>
<HashCode>AUABAAAAAAAAACAAAAAAAAQIAAAAAAAQAAAAAAAAABA=</HashCode>
<FileName>OAuth2\Messages\UnauthorizedResponse.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
+ <Class Name="DotNetOpenAuth.OAuth2.Messages.ScopedAccessTokenRequest" Collapsed="true">
+ <Position X="6.75" Y="7.75" Width="2.25" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>OAuth2\Messages\ScopedAccessTokenRequest.cs</FileName>
+ </TypeIdentifier>
+ </Class>
<Interface Name="DotNetOpenAuth.OAuth2.Messages.IMessageWithClientState">
<Position X="11.5" Y="0.5" Width="2" />
<TypeIdentifier>
@@ -248,17 +137,17 @@
<FileName>OAuth2\Messages\IMessageWithClientState.cs</FileName>
</TypeIdentifier>
</Interface>
- <Enum Name="DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationResponseTypes">
+ <Enum Name="DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationResponseType">
<Position X="8" Y="0.5" Width="3" />
<TypeIdentifier>
- <HashCode>ACAAAAAAAAAAAAAAAgAAAAAAEAAAAAAAAAAAAAAAAAA=</HashCode>
+ <HashCode>ACAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>OAuth2\Messages\EndUserAuthorizationResponseType.cs</FileName>
</TypeIdentifier>
</Enum>
<Enum Name="DotNetOpenAuth.OAuth2.Messages.GrantType">
<Position X="6.25" Y="0.5" Width="1.5" />
<TypeIdentifier>
- <HashCode>ACAAAAAAQAAAAAAAAgAAAAAAAAAAAAACAAAAAAEAAAA=</HashCode>
+ <HashCode>ACAAAAAAQAAAAAQAAgAAAAAAAAAAAAACAAAAAAAAAAA=</HashCode>
<FileName>OAuth2\Messages\GrantType.cs</FileName>
</TypeIdentifier>
</Enum>
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/ScopedAccessTokenRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/ScopedAccessTokenRequest.cs
new file mode 100644
index 0000000..0e0329b
--- /dev/null
+++ b/src/DotNetOpenAuth/OAuth2/Messages/ScopedAccessTokenRequest.cs
@@ -0,0 +1,34 @@
+//-----------------------------------------------------------------------
+// <copyright file="ScopedAccessTokenRequest.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OAuth2.Messages {
+ using System;
+ using System.Collections.Generic;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth2.ChannelElements;
+
+ /// <summary>
+ /// An access token request that includes a scope parameter.
+ /// </summary>
+ internal abstract class ScopedAccessTokenRequest : AccessTokenRequestBase {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ScopedAccessTokenRequest"/> class.
+ /// </summary>
+ /// <param name="tokenEndpoint">The Authorization Server's access token endpoint URL.</param>
+ /// <param name="version">The version.</param>
+ internal ScopedAccessTokenRequest(Uri tokenEndpoint, Version version)
+ : base(tokenEndpoint, version) {
+ this.Scope = new HashSet<string>(OAuthUtilities.ScopeStringComparer);
+ }
+
+ /// <summary>
+ /// Gets the set of scopes the Client would like the access token to provide access to.
+ /// </summary>
+ /// <value>A set of scopes. Never null.</value>
+ [MessagePart(Protocol.scope, IsRequired = false, Encoder = typeof(ScopeEncoder))]
+ internal HashSet<string> Scope { get; private set; }
+ }
+}
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/UnauthorizedResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/UnauthorizedResponse.cs
index 34da922..d79c00b 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/UnauthorizedResponse.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/UnauthorizedResponse.cs
@@ -63,7 +63,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
WebHeaderCollection IHttpDirectResponse.Headers {
get {
return new WebHeaderCollection() {
- { HttpResponseHeader.WwwAuthenticate, Protocol.HttpAuthorizationScheme },
+ { HttpResponseHeader.WwwAuthenticate, Protocol.BearerHttpAuthorizationScheme },
};
}
}
diff --git a/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs b/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs
index 74d5791..c2b2f5f 100644
--- a/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs
+++ b/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs
@@ -90,14 +90,14 @@ namespace DotNetOpenAuth.OAuth2 {
/// </summary>
/// <param name="request">The request to authorize.</param>
/// <param name="accessToken">The access token previously obtained from the Authorization Server.</param>
- internal static void AuthorizeWithOAuthWrap(this HttpWebRequest request, string accessToken) {
+ internal static void AuthorizeWithBearerToken(this HttpWebRequest request, string accessToken) {
Contract.Requires<ArgumentNullException>(request != null);
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(accessToken));
ErrorUtilities.VerifyProtocol(accessToken.All(ch => accessTokenAuthorizationHeaderAllowedCharacters.IndexOf(ch) >= 0), "The access token contains characters that must not appear in the HTTP Authorization header.");
request.Headers[HttpRequestHeader.Authorization] = string.Format(
CultureInfo.InvariantCulture,
- Protocol.HttpAuthorizationHeaderFormat,
+ Protocol.BearerHttpAuthorizationHeaderFormat,
accessToken);
}
diff --git a/src/DotNetOpenAuth/OAuth2/Protocol.cs b/src/DotNetOpenAuth/OAuth2/Protocol.cs
index 12b9f5e..d9d7dd2 100644
--- a/src/DotNetOpenAuth/OAuth2/Protocol.cs
+++ b/src/DotNetOpenAuth/OAuth2/Protocol.cs
@@ -24,14 +24,25 @@ namespace DotNetOpenAuth.OAuth2 {
/// </summary>
internal class Protocol {
/// <summary>
- /// The HTTP authorization scheme "OAuth";
+ /// The HTTP authorization scheme "Bearer";
/// </summary>
- internal const string HttpAuthorizationScheme = "OAuth";
+ internal const string BearerHttpAuthorizationScheme = "Bearer";
/// <summary>
- /// The format of the HTTP Authorization header value that authorizes OAuth 2.0 requests.
+ /// The HTTP authorization scheme "Bearer ";
/// </summary>
- internal const string HttpAuthorizationHeaderFormat = "OAuth token=\"{0}\"";
+ internal const string BearerHttpAuthorizationSchemeWithTrailingSpace = BearerHttpAuthorizationScheme + " ";
+
+ /// <summary>
+ /// The format of the HTTP Authorization header value that authorizes OAuth 2.0 requests using bearer access tokens.
+ /// </summary>
+ internal const string BearerHttpAuthorizationHeaderFormat = BearerHttpAuthorizationSchemeWithTrailingSpace + "{0}";
+
+ /// <summary>
+ /// The name of the parameter whose value is an OAuth 2.0 bearer access token, as it is defined
+ /// in a URL-encoded POST entity or URL query string.
+ /// </summary>
+ internal const string BearerTokenEncodedUrlParameterName = "bearer_token";
/// <summary>
/// The "type" string.
@@ -124,6 +135,11 @@ namespace DotNetOpenAuth.OAuth2 {
internal const string access_token_secret = "access_token_secret";
/// <summary>
+ /// The "token_type" string.
+ /// </summary>
+ internal const string token_type = "token_type";
+
+ /// <summary>
/// The "refresh_token" string.
/// </summary>
internal const string refresh_token = "refresh_token";
@@ -230,11 +246,20 @@ namespace DotNetOpenAuth.OAuth2 {
}
}
+ /// <summary>
+ /// Values for the "response_type" parameter.
+ /// </summary>
internal static class ResponseTypes
{
+ /// <summary>
+ /// The string "code".
+ /// </summary>
internal const string Code = "code";
+
+ /// <summary>
+ /// The string "token".
+ /// </summary>
internal const string Token = "token";
- internal const string CodeAndToken = "code_and_token";
}
internal static class GrantTypes
@@ -247,7 +272,7 @@ namespace DotNetOpenAuth.OAuth2 {
internal const string RefreshToken = "refresh_token";
- internal const string None = "none";
+ internal const string ClientCredentials = "client_credentials";
}
/// <summary>
@@ -311,5 +336,15 @@ namespace DotNetOpenAuth.OAuth2 {
/// </summary>
internal const string InvalidScope = "invalid_scope";
}
+
+ /// <summary>
+ /// Recognized access token types.
+ /// </summary>
+ internal static class AccessTokenTypes {
+ /// <summary>
+ /// The "bearer" token type.
+ /// </summary>
+ internal const string Bearer = "bearer";
+ }
}
}