Fix base path issue with OAuthHandler
This commit is contained in:
parent
102f113e2b
commit
78cf7f99ff
|
|
@ -117,7 +117,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
|
||||||
{
|
{
|
||||||
Domain = Options.CookieDomain,
|
Domain = Options.CookieDomain,
|
||||||
HttpOnly = Options.CookieHttpOnly,
|
HttpOnly = Options.CookieHttpOnly,
|
||||||
Path = Options.CookiePath ?? (RequestPathBase.HasValue ? RequestPathBase.ToString() : "/"),
|
Path = Options.CookiePath ?? (OriginalPathBase.HasValue ? OriginalPathBase.ToString() : "/"),
|
||||||
};
|
};
|
||||||
if (Options.CookieSecure == CookieSecureOption.SameAsRequest)
|
if (Options.CookieSecure == CookieSecureOption.SameAsRequest)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -116,10 +116,7 @@ namespace Microsoft.AspNet.Authentication.OAuth
|
||||||
return new AuthenticationTicket(properties, Options.AuthenticationScheme);
|
return new AuthenticationTicket(properties, Options.AuthenticationScheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
var requestPrefix = Request.Scheme + "://" + Request.Host;
|
var tokens = await ExchangeCodeAsync(code, BuildRedirectUri(Options.CallbackPath));
|
||||||
var redirectUri = requestPrefix + RequestPathBase + Options.CallbackPath;
|
|
||||||
|
|
||||||
var tokens = await ExchangeCodeAsync(code, redirectUri);
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(tokens.AccessToken))
|
if (string.IsNullOrWhiteSpace(tokens.AccessToken))
|
||||||
{
|
{
|
||||||
|
|
@ -172,20 +169,16 @@ namespace Microsoft.AspNet.Authentication.OAuth
|
||||||
|
|
||||||
protected override Task<bool> HandleUnauthorizedAsync([NotNull] ChallengeContext context)
|
protected override Task<bool> HandleUnauthorizedAsync([NotNull] ChallengeContext context)
|
||||||
{
|
{
|
||||||
var baseUri = Request.Scheme + "://" + Request.Host + Request.PathBase;
|
|
||||||
var currentUri = baseUri + Request.Path + Request.QueryString;
|
|
||||||
var redirectUri = baseUri + Options.CallbackPath;
|
|
||||||
|
|
||||||
var properties = new AuthenticationProperties(context.Properties);
|
var properties = new AuthenticationProperties(context.Properties);
|
||||||
if (string.IsNullOrEmpty(properties.RedirectUri))
|
if (string.IsNullOrEmpty(properties.RedirectUri))
|
||||||
{
|
{
|
||||||
properties.RedirectUri = currentUri;
|
properties.RedirectUri = CurrentUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OAuth2 10.12 CSRF
|
// OAuth2 10.12 CSRF
|
||||||
GenerateCorrelationId(properties);
|
GenerateCorrelationId(properties);
|
||||||
|
|
||||||
var authorizationEndpoint = BuildChallengeUrl(properties, redirectUri);
|
var authorizationEndpoint = BuildChallengeUrl(properties, BuildRedirectUri(Options.CallbackPath));
|
||||||
|
|
||||||
var redirectContext = new OAuthApplyRedirectContext(
|
var redirectContext = new OAuthApplyRedirectContext(
|
||||||
Context, Options,
|
Context, Options,
|
||||||
|
|
|
||||||
|
|
@ -120,16 +120,13 @@ namespace Microsoft.AspNet.Authentication.Twitter
|
||||||
}
|
}
|
||||||
protected override async Task<bool> HandleUnauthorizedAsync([NotNull] ChallengeContext context)
|
protected override async Task<bool> HandleUnauthorizedAsync([NotNull] ChallengeContext context)
|
||||||
{
|
{
|
||||||
var requestPrefix = Request.Scheme + "://" + Request.Host;
|
|
||||||
var callBackUrl = requestPrefix + RequestPathBase + Options.CallbackPath;
|
|
||||||
|
|
||||||
var properties = new AuthenticationProperties(context.Properties);
|
var properties = new AuthenticationProperties(context.Properties);
|
||||||
if (string.IsNullOrEmpty(properties.RedirectUri))
|
if (string.IsNullOrEmpty(properties.RedirectUri))
|
||||||
{
|
{
|
||||||
properties.RedirectUri = requestPrefix + Request.PathBase + Request.Path + Request.QueryString;
|
properties.RedirectUri = CurrentUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
var requestToken = await ObtainRequestTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, callBackUrl, properties);
|
var requestToken = await ObtainRequestTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, BuildRedirectUri(Options.CallbackPath), properties);
|
||||||
if (requestToken.CallbackConfirmed)
|
if (requestToken.CallbackConfirmed)
|
||||||
{
|
{
|
||||||
var twitterAuthenticationEndpoint = AuthenticationEndpoint + requestToken.Token;
|
var twitterAuthenticationEndpoint = AuthenticationEndpoint + requestToken.Token;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Authentication
|
||||||
get { return Context.Response; }
|
get { return Context.Response; }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PathString RequestPathBase { get; private set; }
|
protected PathString OriginalPathBase { get; private set; }
|
||||||
|
|
||||||
protected ILogger Logger { get; private set; }
|
protected ILogger Logger { get; private set; }
|
||||||
|
|
||||||
|
|
@ -48,11 +48,19 @@ namespace Microsoft.AspNet.Authentication
|
||||||
|
|
||||||
public IAuthenticationHandler PriorHandler { get; set; }
|
public IAuthenticationHandler PriorHandler { get; set; }
|
||||||
|
|
||||||
|
protected string CurrentUri
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Request.Scheme + "://" + Request.Host + Request.PathBase + Request.Path + Request.QueryString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected async Task BaseInitializeAsync([NotNull] AuthenticationOptions options, [NotNull] HttpContext context, [NotNull] ILogger logger, [NotNull] IUrlEncoder encoder)
|
protected async Task BaseInitializeAsync([NotNull] AuthenticationOptions options, [NotNull] HttpContext context, [NotNull] ILogger logger, [NotNull] IUrlEncoder encoder)
|
||||||
{
|
{
|
||||||
_baseOptions = options;
|
_baseOptions = options;
|
||||||
Context = context;
|
Context = context;
|
||||||
RequestPathBase = Request.PathBase;
|
OriginalPathBase = Request.PathBase;
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
UrlEncoder = encoder;
|
UrlEncoder = encoder;
|
||||||
|
|
||||||
|
|
@ -70,6 +78,11 @@ namespace Microsoft.AspNet.Authentication
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected string BuildRedirectUri(string targetPath)
|
||||||
|
{
|
||||||
|
return Request.Scheme + "://" + Request.Host + OriginalPathBase + targetPath;
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task OnStartingCallback(object state)
|
private static async Task OnStartingCallback(object state)
|
||||||
{
|
{
|
||||||
var handler = (AuthenticationHandler)state;
|
var handler = (AuthenticationHandler)state;
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,10 @@ using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Builder;
|
using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.AspNet.Http.Authentication;
|
||||||
using Microsoft.AspNet.TestHost;
|
using Microsoft.AspNet.TestHost;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
using Microsoft.Framework.WebEncoders;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -61,6 +63,67 @@ namespace Microsoft.AspNet.Authentication.Facebook
|
||||||
query.ShouldContain("custom=test");
|
query.ShouldContain("custom=test");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task NestedMapWillNotAffectRedirect()
|
||||||
|
{
|
||||||
|
var server = CreateServer(app =>
|
||||||
|
app.Map("/base", map => {
|
||||||
|
map.UseFacebookAuthentication();
|
||||||
|
map.Map("/login", signoutApp => signoutApp.Run(context => context.Authentication.ChallengeAsync("Facebook", new AuthenticationProperties() { RedirectUri = "/" })));
|
||||||
|
}),
|
||||||
|
services =>
|
||||||
|
{
|
||||||
|
services.AddAuthentication();
|
||||||
|
services.ConfigureFacebookAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.AppId = "Test App Id";
|
||||||
|
options.AppSecret = "Test App Secret";
|
||||||
|
options.SignInScheme = "External";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handler: null);
|
||||||
|
var transaction = await server.SendAsync("http://example.com/base/login");
|
||||||
|
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||||
|
var location = transaction.Response.Headers.Location.AbsoluteUri;
|
||||||
|
location.ShouldContain("https://www.facebook.com/v2.2/dialog/oauth");
|
||||||
|
location.ShouldContain("response_type=code");
|
||||||
|
location.ShouldContain("client_id=");
|
||||||
|
location.ShouldContain("redirect_uri=" + UrlEncoder.Default.UrlEncode("http://example.com/base/signin-facebook"));
|
||||||
|
location.ShouldContain("scope=");
|
||||||
|
location.ShouldContain("state=");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MapWillNotAffectRedirect()
|
||||||
|
{
|
||||||
|
var server = CreateServer(
|
||||||
|
app =>
|
||||||
|
{
|
||||||
|
app.UseFacebookAuthentication();
|
||||||
|
app.Map("/login", signoutApp => signoutApp.Run(context => context.Authentication.ChallengeAsync("Facebook", new AuthenticationProperties() { RedirectUri = "/" })));
|
||||||
|
},
|
||||||
|
services =>
|
||||||
|
{
|
||||||
|
services.AddAuthentication();
|
||||||
|
services.ConfigureFacebookAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.AppId = "Test App Id";
|
||||||
|
options.AppSecret = "Test App Secret";
|
||||||
|
options.SignInScheme = "External";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handler: null);
|
||||||
|
var transaction = await server.SendAsync("http://example.com/login");
|
||||||
|
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||||
|
var location = transaction.Response.Headers.Location.AbsoluteUri;
|
||||||
|
location.ShouldContain("https://www.facebook.com/v2.2/dialog/oauth");
|
||||||
|
location.ShouldContain("response_type=code");
|
||||||
|
location.ShouldContain("client_id=");
|
||||||
|
location.ShouldContain("redirect_uri="+ UrlEncoder.Default.UrlEncode("http://example.com/signin-facebook"));
|
||||||
|
location.ShouldContain("scope=");
|
||||||
|
location.ShouldContain("state=");
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ChallengeWillTriggerRedirection()
|
public async Task ChallengeWillTriggerRedirection()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue