Skip to content
This repository has been archived by the owner on Sep 18, 2021. It is now read-only.

Fix for: Authorization Endpoint does not support POST #3909

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from
14 changes: 3 additions & 11 deletions ISSUE_TEMPLATE
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
- [ ] I read and understood how to enable [logging](https://identityserver.github.io/Documentation/docsv2/configuration/logging.html)

### Question / Issue



### Relevant parts of the log file

```
<log goes here>
```
## Note: This repository is no longer in active development or maintenance, other than reported security vulnerabilities.
## If you have questions and are seeking free support, see [here](http://docs.identityserver.io/en/release/intro/support.html#free-support) for more details.
## If you require commercial support, see [here](http://docs.identityserver.io/en/release/intro/support.html#commercial-support) for more details.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# IdentityServer3 #

## Note: This repository is no longer in active development or maintenance, other than reported security vulnerabilities.
## We highly encourage you to consider [IdentityServer4](https://github.com/IdentityServer/IdentityServer4/) instead.
## If you have questions and are seeking free support, see [here](http://docs.identityserver.io/en/release/intro/support.html#free-support) for more details.
## If you require commercial support, see [here](http://docs.identityserver.io/en/release/intro/support.html#commercial-support) for more details.


Dev build: [![Build status](https://ci.appveyor.com/api/projects/status/rtaj3nb7c60xg7cb/branch/dev?svg=true)](https://ci.appveyor.com/project/leastprivilege/thinktecture/branch/dev)
[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/IdentityServer/IdentityServer3?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Gitter](https://badges.gitter.im/JoinChat.svg)](https://gitter.im/IdentityServer/IdentityServer3?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

![openid_certified](https://cloud.githubusercontent.com/assets/1454075/7611268/4d19de32-f97b-11e4-895b-31b2455a7ca6.png)

Expand Down
10 changes: 9 additions & 1 deletion source/Core/Configuration/Hosting/WebApiConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;
using System.Web.Http.ExceptionHandling;
using System.Web.Http.Routing;

namespace IdentityServer3.Core.Configuration.Hosting
{
Expand Down Expand Up @@ -93,7 +95,13 @@ private static void ConfigureRoutes(IdentityServerOptions options, HttpConfigura
config.Routes.MapHttpRoute(
Constants.RouteNames.Oidc.Authorize,
Constants.RoutePaths.Oidc.Authorize,
new { controller = "AuthorizeEndpoint", action = "Get" });
new { controller = "AuthorizeEndpoint", action = "Get" },
new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) });
config.Routes.MapHttpRoute(
Constants.RouteNames.Oidc.Authorize + "POST",
Constants.RoutePaths.Oidc.Authorize,
new { controller = "AuthorizeEndpoint", action = "Post" },
new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) });
config.Routes.MapHttpRoute(
Constants.RouteNames.Oidc.Consent,
Constants.RoutePaths.Oidc.Consent,
Expand Down
39 changes: 37 additions & 2 deletions source/Core/Endpoints/Connect/AuthorizeEndpointController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,41 @@ public AuthorizeEndpointController(
_clientListCookie = clientListCookie;
}

/// <summary>
/// POST
/// </summary>
/// <param name="request">The request.</param>
/// <returns></returns>
[HttpPost]
public async Task<IHttpActionResult> Post(HttpRequestMessage request)
{
Logger.Info("Start authorize request POST");

if (!request.Content.IsFormData())
{
return StatusCode(System.Net.HttpStatusCode.UnsupportedMediaType);
}

NameValueCollection parameters = request.RequestUri.ParseQueryString();

NameValueCollection parametersContent = await request.Content.ReadAsFormDataAsync();
parameters.Add(parametersContent);
// TODO Check if it has existing names?
//foreach (string name in parametersContent)
//{
// if (string.IsNullOrEmpty(parameters[name]))
// {
// var value = parametersContent[name];
// parameters.Add(name, value);
// }
//}

var response = await ProcessRequestAsync(parameters);

Logger.Info("End authorize request POST");
return response;
}

/// <summary>
/// GET
/// </summary>
Expand All @@ -111,7 +146,7 @@ private async Task<IHttpActionResult> ProcessRequestAsync(NameValueCollection pa
{
// validate request
var result = await _validator.ValidateAsync(parameters, User as ClaimsPrincipal);

if (result.IsError)
{
return await this.AuthorizeErrorAsync(
Expand Down Expand Up @@ -227,7 +262,7 @@ private IHttpActionResult CreateConsentResult(
loginWithDifferentAccountUrl = Url.Route(Constants.RouteNames.Oidc.SwitchUser, null)
.AddQueryString(requestParameters.ToQueryString());
}

var env = Request.GetOwinEnvironment();
var consentModel = new ConsentViewModel
{
Expand Down
2 changes: 1 addition & 1 deletion source/Core/Resources/T4resx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class EventIds
public const string PreLoginSuccess = "PreLoginSuccess";
public const string ResourceOwnerFlowLoginFailure = "ResourceOwnerFlowLoginFailure";
public const string ResourceOwnerFlowLoginSuccess = "ResourceOwnerFlowLoginSuccess";
public const string TokenRevoked = "TokenRevoked";
public const string TokenRevoked = "TokenRevoked";
}
public class MessageIds
{
Expand Down
29 changes: 29 additions & 0 deletions source/Tests/UnitTests/Conformance/Basic/RedirectUriTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,35 @@ public void Preserves_query_parameters_in_redirect_uri()
query["baz"].ToString().Should().Be("quux");
}

[Fact]
[Trait("Category", Category)]
public void POST_allowed_to_authorization_endpoint()
{
host.Login();

var disco = host.GetDiscoveryDocument();
var url = disco["authorization_endpoint"].ToString();


var nonce = Guid.NewGuid().ToString();
var state = Guid.NewGuid().ToString();

var data = new Dictionary<string, string>
{
{"client_id", client_id },
{"redirect_uri", redirect_uri },
{"scope", "openid" },
{"response_type", "code" },
{"state", state },
{"nonce", nonce},
};

var result = host.Client.PostAsync(url, new FormUrlEncodedContent(data)).Result;
result.StatusCode.Should().Be(HttpStatusCode.Redirect);
result.Headers.Location.AbsoluteUri.Should().StartWith("https://code_client/callback");
result.Headers.Location.AbsolutePath.Should().Be("/callback");
}

[Fact]
[Trait("Category", Category)]
public void Rejects_redirect_uri_when_query_parameter_does_not_match()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,12 @@ public void PostConsent_NoBody_ReturnsErrorPage()
var resp = PostForm(Constants.RoutePaths.Oidc.Consent, (object)null);
resp.AssertPage("error");
}

[Fact]
public void PostAuthorize_Json_ReturnsError()
{
var response = client.PostAsJsonAsync(Url(Constants.RoutePaths.Oidc.Authorize), new { foo = "bar" }).Result;
response.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType);
}
}
}