我创建了2个在Azure中托管的Web应用程序。一个应用程序(A)是IdentityServer4提供程序,另一个(B)是通过OpenId Connect将A用作外部登录提供程序的应用程序。在A的代码中,我将IdentityServer4配置为要求B的登录调用使用特定的重定向URI:
namespace A.IdentityServer4Config
{
public static class Clients
{
public static IEnumerable<Client> GetClients(IConfiguration configuration)
{
return new List<Client>
{
new Client
{
ClientId = "B",
ClientSecrets = {new Secret("hashed secret for B")},
AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
AllowedScopes = {"openid", "profile", ...},
RedirectUris = {"https://B.azurewebsites.net/Account/oidc-callback"},
RequireConsent = false,
AccessTokenLifetime = 10 * 60,
},
};
}
}
}
在Startup.ConfigureServices内:
var identityServerBuilder = services
.AddIdentityServer(options => {...})
...
.AddInMemoryClients(Clients.GetClients(configuration))
...;
请注意,我指定的重定向URI是HTTPS URI。
在B代码中,我使用Microsoft.Extensions.DependencyInjection.OpenIdConnectExtensions中的AddOpenIdConnect()重载之一来配置登录调用的进行方式:
services.AddAuthentication(options => {...})
...
.AddOpenIdConnect(
"oidc",
options =>
{
...
options.Authority = "https://A.azurewebsites.net";
options.RequireHttpsMetadata = true;
options.ClientId = "B";
options.ClientSecret = "secret for B";
options.ResponseType = "code";
options.CallbackPath = "/Account/oidc-callback"; // !!!
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
...
}
);
该行注释为“ !!!”是配置登录请求的重定向URI的位置。请注意,它必须是相对于应用程序域的路径。您无法完整指定URI(我尝试过;如果您这样做,则启动时应用程序崩溃)。由于您无法完整指定URI,因此无法使用此属性要求重定向URI为HTTPS。 (RemoteAuthenticationOptions.CallbackPath是Microsoft.AspNetCore.Http.PathString。在官方文档中对此进行了如下描述:“应用程序基本路径中的请求路径,将返回用户代理。请求到达时,中间件将处理此请求。 。”
当我尝试在B上登录时,我被带到A上的错误页面。当我查看由IdentityServer4在A上生成的日志时,很明显,错误的原因是由A请求的重定向URI。 B与预期的不匹配。这两个URI之间的唯一区别是,一个A希望看到的是一个HTTPS URI,另一个B则指定了一个HTTP(没有“ S”)URI:
2018-08-16 15:20:41.307 +00:00 [Error] IdentityServer4.Endpoints.AuthorizeEndpoint: Request validation failed
2018-08-16 15:20:41.307 +00:00 [Information] IdentityServer4.Endpoints.AuthorizeEndpoint: {
"ClientId": "B",
"AllowedRedirectUris": [
"https://B.azurewebsites.net/Account/oidc-callback"
],
"SubjectId": "anonymous",
"RequestedScopes": "",
"Raw": {
"client_id": "B",
"redirect_uri": "http://B.azurewebsites.net/Account/oidc-callback",
"response_type": "code",
"scope": "openid profile ...",
"response_mode": "form_post",
"nonce": "[omitted]",
"state": "[omitted]",
"x-client-SKU": "ID_NETSTANDARD1_4",
"x-client-ver": "5.2.0.0"
}
}
2018-08-16 15:20:41.307 +00:00 [Information] IdentityServer4.Events.DefaultEventService: {
"Name": "Token Issued Failure",
"Category": "Token",
"EventType": "Failure",
"Id": 2001,
"ClientId": "B",
"Endpoint": "Authorize",
"Scopes": "",
"Error": "unauthorized_client",
"ErrorDescription": "Invalid redirect_uri",
"ActivityId": "[omitted]",
"TimeStamp": "2018-08-16T15:20:41Z",
"ProcessId": 10408,
"LocalIpAddress": "[omitted]",
"RemoteIpAddress": "[omitted]"
}
我不知道为什么B对A的请求默认使用HTTP作为重定向URI。我不知道如何将其改为HTTPS。我可以放宽重定向URI为HTTPS的要求,但这似乎是错误的做法。我想知道如何让B在对A的请求中指定HTTPS URI。从文档中RemoteAuthenticationOptions.CallbackPath的描述中,我认为应该通过确保“应用程序的基本路径”为HTTPS来实现。 ;但是,我不知道该怎么做,并且搜索互联网也没有成功。
当我在本地运行这些应用程序时,一切正常,因为当B在本地运行时,它发出的请求指定一个HTTPS重定向URI(如我希望的那样)。我不知道为什么在本地运行和在Azure上运行时其行为会有所不同。
如上所述,我尝试完全指定重定向URI(而不是相对而言)。这不起作用-导致应用程序启动时崩溃。
我还尝试将CallbackPath类型设置为使用PathString.FromUriComponent()(使用各种绝对URI)构造的PathString。这没有用。如果我已将相对URI作为字符串传递,则URI的协议和域部分将被丢弃并替换为原来的内容(即“ http”和相应的域)。
我浏览了https://github.com/IdentityServer/IdentityServer4.Samples上各种示例MVC客户端中的Startup类。我没有发现任何明显可以解决此问题的方法。
答案 0 :(得分:1)
事实证明,在Azure上,生成的重定向URI是HTTP还是HTTPS是由SSL配置“刀片”中的“仅HTTPS”设置决定的。
在Azure Web门户中,选择应用程序服务(B)。在“设置”下,选择“ SSL设置”。 SSL配置“刀片”打开。出现的第一个选项是“仅HTTPS”。默认为“关闭”。将其更改为“开”。