對於其他人可能會遇到這樣的問題:問題是,當你取(複製)ApplicationOAuthProvider.cs
從Visual Studio SPA模板,它的存在,其中這個代碼是:
public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
if (context.ClientId == _publicClientId)
{
var expectedRootUri = new Uri(context.Request.Uri, "/");
if (expectedRootUri.AbsoluteUri == context.RedirectUri)
{
context.Validated();
}
}
return Task.FromResult<object>(null);
}
這顯然會阻止任何redirect_uri
看起來不像http://localhost/
或http://domain.com/
,因此例如http://domain.com/home
將不起作用。
現在這下面是卡塔納爲InvokeAuthorizeEndpointAsync
的來源,完成所有的工作,你可以看到它調用到可能被註冊此MVC /網絡API的應用程序(此登記通常發生在Startup.Auth.cs
)的任何自定義OAuthProvider
:
private async Task<bool> InvokeAuthorizeEndpointAsync()
{
var authorizeRequest = new AuthorizeEndpointRequest(Request.Query);
var clientContext = new OAuthValidateClientRedirectUriContext(
Context,
Options,
authorizeRequest.ClientId,
authorizeRequest.RedirectUri);
if (!String.IsNullOrEmpty(authorizeRequest.RedirectUri))
{
bool acceptableUri = true;
Uri validatingUri;
if (!Uri.TryCreate(authorizeRequest.RedirectUri, UriKind.Absolute, out validatingUri))
{
// The redirection endpoint URI MUST be an absolute URI
// http://tools.ietf.org/html/rfc6749#section-3.1.2
acceptableUri = false;
}
else if (!String.IsNullOrEmpty(validatingUri.Fragment))
{
// The endpoint URI MUST NOT include a fragment component.
// http://tools.ietf.org/html/rfc6749#section-3.1.2
acceptableUri = false;
}
else if (!Options.AllowInsecureHttp &&
String.Equals(validatingUri.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase))
{
// The redirection endpoint SHOULD require the use of TLS
// http://tools.ietf.org/html/rfc6749#section-3.1.2.1
acceptableUri = false;
}
if (!acceptableUri)
{
clientContext.SetError(Constants.Errors.InvalidRequest);
return await SendErrorRedirectAsync(clientContext, clientContext);
}
}
await Options.Provider.ValidateClientRedirectUri(clientContext);
if (!clientContext.IsValidated)
{
_logger.WriteVerbose("Unable to validate client information");
return await SendErrorRedirectAsync(clientContext, clientContext);
}
var validatingContext = new OAuthValidateAuthorizeRequestContext(
Context,
Options,
authorizeRequest,
clientContext);
if (string.IsNullOrEmpty(authorizeRequest.ResponseType))
{
_logger.WriteVerbose("Authorize endpoint request missing required response_type parameter");
validatingContext.SetError(Constants.Errors.InvalidRequest);
}
else if (!authorizeRequest.IsAuthorizationCodeGrantType &&
!authorizeRequest.IsImplicitGrantType)
{
_logger.WriteVerbose("Authorize endpoint request contains unsupported response_type parameter");
validatingContext.SetError(Constants.Errors.UnsupportedResponseType);
}
else
{
await Options.Provider.ValidateAuthorizeRequest(validatingContext);
}
if (!validatingContext.IsValidated)
{
// an invalid request is not processed further
return await SendErrorRedirectAsync(clientContext, validatingContext);
}
_clientContext = clientContext;
_authorizeEndpointRequest = authorizeRequest;
var authorizeEndpointContext = new OAuthAuthorizeEndpointContext(Context, Options);
await Options.Provider.AuthorizeEndpoint(authorizeEndpointContext);
return authorizeEndpointContext.IsRequestCompleted;
}
這點很關鍵:
await Options.Provider.ValidateClientRedirectUri(clientContext);
所以您的解決方案是改變ValidateClientRedirectUri
如何執行驗證 - 默認SPA實現,因爲你可以看到,非常天真。
有很多ppl與SPA有關的問題,主要是因爲它缺少任何有用的信息,我的意思是無論是ASP.NET Identity還是OWIN的東西,以及關於KnockoutJS實現中發生的事情。
我希望微軟能爲這些模板提供更全面的文檔,因爲任何嘗試做更復雜的事情都會遇到問題。
我花了數小時的時間,挖掘到OWIN(Katana)源代碼,認爲它是上述實現阻止我的重定向URI,但它不是,希望可以幫助其他人。
HTH
我們需要請參閱'AccountController'中'ExternalLogin'操作的代碼 - 這就是重定向發生的地方 – trailmax
@trailmax實際上,如果您在ASP.NET項目對話框中選擇單頁面應用程序模板並在演示中更改返回URL,則會發生同樣的問題'/'類似於JavaScript文件中的/測試。謝謝! – doorman