diff options
Diffstat (limited to 'src')
8 files changed, 109 insertions, 29 deletions
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs index 5429b60..9840218 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs @@ -186,7 +186,7 @@ namespace DotNetOpenAuth.OAuth2 { switch (authorizationRequest.ResponseType) { case EndUserAuthorizationResponseType.AccessToken: var accessTokenResponse = new EndUserAuthorizationSuccessAccessTokenResponse(callback, authorizationRequest); - accessTokenResponse.Lifetime = this.AuthorizationServerServices.GetAccessTokenLifetime(authorizationRequest); + accessTokenResponse.Lifetime = this.AuthorizationServerServices.GetAccessTokenLifetime((EndUserAuthorizationImplicitRequest)authorizationRequest); response = accessTokenResponse; break; case EndUserAuthorizationResponseType.AuthorizationCode: diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/UserAgentClient.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/UserAgentClient.cs index d2ede6f..5131b10 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/UserAgentClient.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/UserAgentClient.cs @@ -64,15 +64,19 @@ namespace DotNetOpenAuth.OAuth2 { /// this client to access protected data at some resource server. /// </summary> /// <param name="authorization">The authorization state that is tracking this particular request. Optional.</param> + /// <param name="implicitResponseType"> + /// <c>true</c> to request an access token in the fragment of the response's URL; + /// <c>false</c> to authenticate to the authorization server and acquire the access token (and possibly a refresh token) via a private channel. + /// </param> /// <param name="state">The client state that should be returned with the authorization response.</param> /// <returns> /// A fully-qualified URL suitable to initiate the authorization flow. /// </returns> - public Uri RequestUserAuthorization(IAuthorizationState authorization, string state = null) { + public Uri RequestUserAuthorization(IAuthorizationState authorization, bool implicitResponseType = false, string state = null) { Requires.NotNull(authorization, "authorization"); Requires.ValidState(!string.IsNullOrEmpty(this.ClientIdentifier)); - var request = this.PrepareRequestUserAuthorization(authorization, state); + var request = this.PrepareRequestUserAuthorization(authorization, implicitResponseType, state); return this.Channel.PrepareResponse(request).GetDirectUriRequest(this.Channel); } @@ -130,11 +134,15 @@ namespace DotNetOpenAuth.OAuth2 { /// this client to access protected data at some resource server. /// </summary> /// <param name="authorization">The authorization state that is tracking this particular request. Optional.</param> + /// <param name="implicitResponseType"> + /// <c>true</c> to request an access token in the fragment of the response's URL; + /// <c>false</c> to authenticate to the authorization server and acquire the access token (and possibly a refresh token) via a private channel. + /// </param> /// <param name="state">The client state that should be returned with the authorization response.</param> /// <returns> /// A message to send to the authorization server. /// </returns> - internal EndUserAuthorizationRequest PrepareRequestUserAuthorization(IAuthorizationState authorization, string state = null) { + internal EndUserAuthorizationRequest PrepareRequestUserAuthorization(IAuthorizationState authorization, bool implicitResponseType = false, string state = null) { Requires.NotNull(authorization, "authorization"); Requires.ValidState(!string.IsNullOrEmpty(this.ClientIdentifier)); @@ -142,11 +150,10 @@ namespace DotNetOpenAuth.OAuth2 { authorization.Callback = new Uri("http://localhost/"); } - var request = new EndUserAuthorizationRequest(this.AuthorizationServer) { - ClientIdentifier = this.ClientIdentifier, - Callback = authorization.Callback, - ClientState = state, - }; + var request = implicitResponseType ? new EndUserAuthorizationImplicitRequest(this.AuthorizationServer) : new EndUserAuthorizationRequest(this.AuthorizationServer); + request.ClientIdentifier = this.ClientIdentifier; + request.Callback = authorization.Callback; + request.ClientState = state; request.Scope.ResetContents(authorization.Scope); return request; diff --git a/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj b/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj index 5c934b4..a9235ba 100644 --- a/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj +++ b/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj @@ -50,6 +50,7 @@ <Compile Include="OAuth2\Messages\AccessTokenRequestBase.cs" /> <Compile Include="OAuth2\Messages\AccessTokenClientCredentialsRequest.cs" /> <Compile Include="OAuth2\Messages\AuthenticatedClientRequestBase.cs" /> + <Compile Include="OAuth2\Messages\EndUserAuthorizationImplicitRequest.cs" /> <Compile Include="OAuth2\Messages\EndUserAuthorizationSuccessAccessTokenResponse.cs" /> <Compile Include="OAuth2\Messages\EndUserAuthorizationFailedResponse.cs" /> <Compile Include="OAuth2\Messages\EndUserAuthorizationSuccessAuthCodeResponse.cs" /> diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/ChannelElements/OAuth2ChannelBase.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/ChannelElements/OAuth2ChannelBase.cs index 06b3eec..117d526 100644 --- a/src/DotNetOpenAuth.OAuth2/OAuth2/ChannelElements/OAuth2ChannelBase.cs +++ b/src/DotNetOpenAuth.OAuth2/OAuth2/ChannelElements/OAuth2ChannelBase.cs @@ -28,6 +28,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { typeof(AccessTokenSuccessResponse), typeof(AccessTokenFailedResponse), typeof(EndUserAuthorizationRequest), + typeof(EndUserAuthorizationImplicitRequest), typeof(EndUserAuthorizationSuccessAuthCodeResponse), typeof(EndUserAuthorizationSuccessAccessTokenResponse), typeof(EndUserAuthorizationFailedResponse), diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/Messages/EndUserAuthorizationImplicitRequest.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/Messages/EndUserAuthorizationImplicitRequest.cs new file mode 100644 index 0000000..71a243e --- /dev/null +++ b/src/DotNetOpenAuth.OAuth2/OAuth2/Messages/EndUserAuthorizationImplicitRequest.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------- +// <copyright file="EndUserAuthorizationImplicitRequest.cs" company="Outercurve Foundation"> +// Copyright (c) Outercurve Foundation. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuth2.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth2.ChannelElements; + + /// <summary> + /// A message sent by a web application Client to the AuthorizationServer + /// via the user agent to obtain authorization from the user and prepare + /// to issue an access token to the client if permission is granted. + /// </summary> + [Serializable] + public class EndUserAuthorizationImplicitRequest : EndUserAuthorizationRequest, IAccessTokenRequest { + /// <summary> + /// Gets or sets the grant type that the client expects of the authorization server. + /// </summary> + /// <value>Always <see cref="EndUserAuthorizationResponseType.Token"/>. Other response types are not supported.</value> + [MessagePart(Protocol.response_type, IsRequired = true, Encoder = typeof(EndUserAuthorizationResponseTypeEncoder))] + private const EndUserAuthorizationResponseType ResponseTypeConst = EndUserAuthorizationResponseType.AccessToken; + + /// <summary> + /// Initializes a new instance of the <see cref="EndUserAuthorizationImplicitRequest"/> class. + /// </summary> + /// <param name="authorizationEndpoint">The Authorization Server's user authorization URL to direct the user to.</param> + /// <param name="version">The protocol version.</param> + internal EndUserAuthorizationImplicitRequest(Uri authorizationEndpoint, Version version) + : base(authorizationEndpoint, version) { + } + + /// <summary> + /// Initializes a new instance of the <see cref="EndUserAuthorizationImplicitRequest"/> class. + /// </summary> + /// <param name="authorizationServer">The authorization server.</param> + internal EndUserAuthorizationImplicitRequest(AuthorizationServerDescription authorizationServer) + : this(authorizationServer.AuthorizationEndpoint, authorizationServer.Version) { + } + + /// <summary> + /// Gets the grant type that the client expects of the authorization server. + /// </summary> + public override EndUserAuthorizationResponseType ResponseType { + get { return ResponseTypeConst; } + } + + /// <summary> + /// Gets a value indicating whether the client requesting the access token has authenticated itself. + /// </summary> + /// <value> + /// Always false because authorization requests only include the client_id, without a secret. + /// </value> + bool IAccessTokenRequest.ClientAuthenticated { + get { return false; } + } + } +} diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/Messages/EndUserAuthorizationRequest.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/Messages/EndUserAuthorizationRequest.cs index 438873b..45fa049 100644 --- a/src/DotNetOpenAuth.OAuth2/OAuth2/Messages/EndUserAuthorizationRequest.cs +++ b/src/DotNetOpenAuth.OAuth2/OAuth2/Messages/EndUserAuthorizationRequest.cs @@ -16,10 +16,17 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// <summary> /// A message sent by a web application Client to the AuthorizationServer /// via the user agent to obtain authorization from the user and prepare - /// to issue an access token to the Consumer if permission is granted. + /// to issue an access token to the client if permission is granted. /// </summary> [Serializable] - public class EndUserAuthorizationRequest : MessageBase, IAccessTokenRequest { + public class EndUserAuthorizationRequest : MessageBase { + /// <summary> + /// Gets the grant type that the client expects of the authorization server. + /// </summary> + /// <value>Always <see cref="EndUserAuthorizationResponseType.AuthorizationCode"/>. Other response types are not supported.</value> + [MessagePart(Protocol.response_type, IsRequired = true, Encoder = typeof(EndUserAuthorizationResponseTypeEncoder))] + private const EndUserAuthorizationResponseType ResponseTypeConst = EndUserAuthorizationResponseType.AuthorizationCode; + /// <summary> /// Initializes a new instance of the <see cref="EndUserAuthorizationRequest"/> class. /// </summary> @@ -31,7 +38,6 @@ namespace DotNetOpenAuth.OAuth2.Messages { Requires.NotNull(version, "version"); this.HttpMethods = HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.PostRequest; this.Scope = new HashSet<string>(OAuthUtilities.ScopeStringComparer); - this.ResponseType = EndUserAuthorizationResponseType.AuthorizationCode; } /// <summary> @@ -46,11 +52,11 @@ namespace DotNetOpenAuth.OAuth2.Messages { } /// <summary> - /// Gets or sets the grant type that the client expects of the authorization server. + /// Gets the grant type that the client expects of the authorization server. /// </summary> - /// <value>Always <see cref="EndUserAuthorizationResponseType.AuthorizationCode"/>. Other response types are not supported.</value> - [MessagePart(Protocol.response_type, IsRequired = true, Encoder = typeof(EndUserAuthorizationResponseTypeEncoder))] - public EndUserAuthorizationResponseType ResponseType { get; set; } + public virtual EndUserAuthorizationResponseType ResponseType { + get { return ResponseTypeConst; } + } /// <summary> /// Gets or sets the identifier by which this client is known to the Authorization Server. @@ -59,16 +65,6 @@ namespace DotNetOpenAuth.OAuth2.Messages { public string ClientIdentifier { get; set; } /// <summary> - /// Gets a value indicating whether the client requesting the access token has authenticated itself. - /// </summary> - /// <value> - /// Always false because authorization requests only include the client_id, without a secret. - /// </value> - bool IAccessTokenRequest.ClientAuthenticated { - get { return false; } - } - - /// <summary> /// Gets or sets the callback URL. /// </summary> /// <value> diff --git a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs index e31f3b1..f2d9c09 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs @@ -45,6 +45,17 @@ namespace DotNetOpenAuth.Test.OAuth2 { } [TestCase] + public void EndUserAuthorizationImplicitRequest() { + var fields = new Dictionary<string, string> { + { Protocol.response_type, "token" }, + { Protocol.client_id, "abc" }, + { Protocol.redirect_uri, "abc" }, + }; + IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + Assert.IsInstanceOf(typeof(EndUserAuthorizationImplicitRequest), request); + } + + [TestCase] public void EndUserAuthorizationSuccessResponseWithCode() { var fields = new Dictionary<string, string> { { Protocol.code, "abc" }, diff --git a/src/DotNetOpenAuth.Test/OAuth2/UserAgentClientAuthorizeTests.cs b/src/DotNetOpenAuth.Test/OAuth2/UserAgentClientAuthorizeTests.cs index 6494b13..c91049f 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/UserAgentClientAuthorizeTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/UserAgentClientAuthorizeTests.cs @@ -30,6 +30,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { Callback = ClientCallback, }; var request = client.PrepareRequestUserAuthorization(authState); + Assert.AreEqual(EndUserAuthorizationResponseType.AuthorizationCode, request.ResponseType); client.Channel.Respond(request); var incoming = client.Channel.ReadFromRequest(); var result = client.ProcessUserAuthorization(authState, incoming); @@ -59,8 +60,8 @@ namespace DotNetOpenAuth.Test.OAuth2 { var authState = new AuthorizationState { Callback = ClientCallback, }; - var request = client.PrepareRequestUserAuthorization(authState); - request.ResponseType = EndUserAuthorizationResponseType.AccessToken; + var request = client.PrepareRequestUserAuthorization(authState, implicitResponseType: true); + Assert.AreEqual(EndUserAuthorizationResponseType.AccessToken, request.ResponseType); client.Channel.Respond(request); var incoming = client.Channel.ReadFromRequest(); var result = client.ProcessUserAuthorization(authState, incoming); @@ -69,7 +70,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { }, server => { var request = server.ReadAuthorizationRequest(); - IAccessTokenRequest accessTokenRequest = request; + IAccessTokenRequest accessTokenRequest = (EndUserAuthorizationImplicitRequest)request; Assert.IsFalse(accessTokenRequest.ClientAuthenticated); server.ApproveAuthorizationRequest(request, Username); }); |