asp.net-core - 带有 docker-compose 的 Identity Server 4 在 /connect/authorize/callback 之后重定向到登录页面
问题描述
我目前在尝试从使用 docker 容器化的 IdentityServer4 实例中获取访问令牌时遇到问题。奇怪的是,当我在本地运行 IdentityServer 实例时它可以工作。我正在使用 AspNetCoreIdentity 模板。
输入登录信息后,应用程序会将我重定向到登录页面。它发生在 Redirect(model.ReturnUrl) 行,ReturnUrl 值为“ /connect/authorize/callback?response_type=code&state&client_id=postman-api&scope=postman.api&redirect_uri=https%3A%2F%2Fwww.getpostman.com%2Foauth2% 2F回调"
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginInputModel model, string button)
{
var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);
...
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberLogin, lockoutOnFailure: true);
if (result.Succeeded)
{
var user = await _userManager.FindByNameAsync(model.Username);
await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName, clientId: context?.ClientId));
if (context != null)
{
...
return Redirect(model.ReturnUrl);
}
...
}
下面是代码和配置文件:
客户端和api配置:
public static IEnumerable<ApiResource> GetApis() { return new ApiResource[] { new ApiResource("basket.api", "Basket Api"), new ApiResource("postman.api", "Postman Test Resource") }; } public static IEnumerable<Client> GetClients() { return new[] { new Client { ClientId = "postman-api", ClientName = "Postman client", AllowAccessTokensViaBrowser = true, RequireConsent = false, RedirectUris = {"https://www.getpostman.com/oauth2/callback"}, PostLogoutRedirectUris = {"https://www.getpostman.com"}, AllowedCorsOrigins = {"https://www.getpostman.com"}, EnableLocalLogin = true, AllowedGrantTypes = GrantTypes.Code, ClientSecrets = { new Secret("SomeValue".Sha256()) }, AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "postman.api", "basket.api" } } }; }
码头工人文件
FROM mcr.microsoft.com/dotnet/core/aspnet:2.1-stretch-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:2.1-stretch AS build
WORKDIR /src
COPY ["Auth2.2/Auth2.2.csproj", "Auth2.2/"]
RUN dotnet restore "Auth2.2/Auth2.2.csproj"
COPY . .
WORKDIR "/src/Auth2.2"
RUN dotnet build "Auth2.2.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Auth2.2.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Auth2.2.dll"]
- 来自 docker-compose 文件的 IdentityServer docker 配置:
auth2.2:
image: ${DOCKER_REGISTRY-}auth22
build:
context: .
dockerfile: Auth2.2/Dockerfile
ports:
- "5000:80"
解决方案
我也遇到了这个问题,今天下午解决了。希望这对你也有帮助。
最近在 19 年 12 月对 Chrome 和 Chromium 进行了更新,更改了 SameSite cookie 属性的允许值。这造成了不兼容,不允许 cookie 在 Postman 中正确存储,在我的情况下,由于 .Net Core 的版本控制问题。在此线程中的最后一条评论中提供了简要说明: https ://community.getpostman.com/t/using-postman-to-test-identityserver4-oauth-authentication-code-flow/9524
我为解决这个问题所做的是:
1) 更新我的 Identity Server 中使用的 .net core 版本。就我而言,我使用的是 .Net Core 2.0,我将其更新为 2.2.8
2) 在我的 startup.cs 文件中更新我的 Cookie 策略选项:
//Setup samesite cookie handling
private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (DisallowsSameSiteNone(userAgent))
{
//.net core >3.0 should change value to SameSiteMode.Unspecified
options.SameSite = (SameSiteMode)(-1);
}
}
}
private static bool DisallowsSameSiteNone(string userAgent)
{
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the
// iOS networking stack.
// Notes from Thinktecture:
// Regarding https://caniuse.com/#search=samesite iOS versions lower
// than 12 are not supporting SameSite at all. Starting with version 13
// unknown values are NOT treated as strict anymore. Therefore we only
// need to check version 12.
if (userAgent.Contains("CPU iPhone OS 12")
|| userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack.
// This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// because they do not use the Mac OS networking stack.
// Notes from Thinktecture:
// Regarding https://caniuse.com/#search=samesite MacOS X versions lower
// than 10.14 are not supporting SameSite at all. Starting with version
// 10.15 unknown values are NOT treated as strict anymore. Therefore we
// only need to check version 10.14.
if (userAgent.Contains("Safari")
&& userAgent.Contains("Macintosh; Intel Mac OS X 10_14")
&& userAgent.Contains("Version/"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
// Notes from Thinktecture:
// We can not validate this assumption, but we trust Microsofts
// evaluation. And overall not sending a SameSite value equals to the same
// behavior as SameSite=None for these old versions anyways.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
...
//set cookie policies
services.Configure<CookiePolicyOptions>(options =>
{
//.net core >3.0 should change value to SameSiteMode.Unspecified
options.MinimumSameSitePolicy = (SameSiteMode)(-1);
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
//set cookie policy before authentication/authorization setup
app.UseCookiePolicy();
//use identity and identityserver to serve tokens
app.UseAuthentication();
app.UseIdentityServer();
...
}
3) 将我的站点重新部署到 Azure。
这使我能够与 Postman 联系以接收令牌。希望您现在已经解决了您的问题,并希望这将帮助像我一样迷失了几天试图找出问题所在的其他人。
可以在以下资源中找到更多信息:
https ://community.getpostman.com/t/using-postman-to-test-identityserver4-oauth-authentication-code-flow/9524
https://devblogs.microsoft.com/ aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/
https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore- 3.1
推荐阅读
- docker - 使用 JDBC 输入插件在 Docker 上的 Logstash 不会从 SQL Server 获取所有行
- flutter - 如何突出显示我在字符串中搜索的确切单词,而不仅仅是字符串的开头?
- flutter - 如何实时获取文档长度
- javascript - Reactjs 从获取请求中返回一个对象
- javascript - Nginx 正在尝试打开文件而不是重定向到代理
- python - _joint_log_likelihood 给我错误的值
- sql - 如何按日期获取最后一件商品的价格
- python-3.x - 定期执行功能而不停止其他操作
- r - 使用 R 从 PDF 表单到数据框的文本挖掘
- r - 如果 r 中出现错误,则转到 lapply() 的下一次迭代