我在用oidc-client
角度。遵循本教程
import { UserManager, UserManagerSettings, User } from 'oidc-client';
我的客户:
export function getClientSettings(): UserManagerSettings {
return {
authority: 'https://localhost:44305/',
client_id: 'angular_spa',
redirect_uri: 'http://localhost:4200/auth-callback',
post_logout_redirect_uri: 'http://localhost:4200/',
response_type: 'id_token token',
scope: 'openid profile api1',
filterProtocolClaims: true,
loadUserInfo: true,
automaticSilentRenew: false
};
在Identity Server中,我正在使用 Assembly Microsoft.AspNetCore.Identity.UI, Version=2.1.3.0
我正在添加默认身份,如下所示:
[assembly:
HostingStartup(typeof(WebApp.Areas.Identity.IdentityHostingStartup))]
namespace WebApp.Areas.Identity
{
public class IdentityHostingStartup: IHostingStartup {
public void Configure(IWebHostBuilder builder) {
builder.ConfigureServices((context, services) => {
services.AddDbContext < WebAppContext > (options =>
options.UseSqlite(context.Configuration.GetConnectionString("WebAppContextConnection")));
services.AddDefaultIdentity < WebAppUser > ()
.AddEntityFrameworkStores < WebAppContext > ();
});
}
}
}
WebAppUser
来自 IdentityUser
Startup.cs:
public class Startup
{
private ILogger<DefaultCorsPolicyService> _logger;
private IHostingEnvironment _env;
public Startup(ILoggerFactory loggerFactory, IHostingEnvironment env)
{
_logger = loggerFactory.CreateLogger<DefaultCorsPolicyService>();
_env = env;
}
private static void SetupIdentityServer(IdentityServerOptions identityServerOptions)
{
identityServerOptions.UserInteraction.LoginUrl = new PathString("/Identity/Account/Login");
// identityServerOptions.Cors.CorsPolicyName = "CorsPolicy";
}
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
{
builder
.WithOrigins("https://localhost:44305")
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
// services.AddMvc();
var cors = new DefaultCorsPolicyService(_logger)
{
AllowAll = true
};
var cert = new X509Certificate2(Path.Combine(_env.ContentRootPath, "mycert.pfx"), "xxxxx");
services.AddIdentityServer(SetupIdentityServer)//SetupIdentityServer
.AddSigningCredential(cert)
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
// .AddTestUsers(TestUsers.Users)
.AddInMemoryIdentityResources(Config.GetIdentityResources());
services.AddSingleton<ICorsPolicyService>(cors);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//loggerFactory.AddConsole();
app.UseDeveloperExceptionPage();
app.Map("/api", api =>
{
api.UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
api.UseAuthentication();
api.Run(async context =>
{
var result = await context.AuthenticateAsync("api");
if (!result.Succeeded)
{
context.Response.StatusCode = 401;
return;
}
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonConvert.SerializeObject("API Response!"));
});
});
app.UseIdentityServer();
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
//Run these PMC commands after this.
//Add - Migration CreateIdentitySchema
//Update - Database
}
}
在身份服务器4中,我已启用https
。因此,问题在于,如果我尝试使用受保护的应用程序,则从我的Angular应用程序URL
导航到身份服务登录页面。看起来它正在针对数据库中的用户正确进行身份验证。但随后它仅刷新登录页面,而不重定向到回调URL
。
这里有一些日志可能会有所帮助
2019-03-07 01:19:30.553-06:00 [INF]启动IdentityServer4版本2.3 .2 .0 2019-03-07 01:19:30.632-06:00 [INF]您正在使用内存中版本如果您在生产中使用这些功能中的任何功能,则希望切换到其他存储实现。2019-03-07 01:19:30.643-06:00 [INF]为IdentityServer使用默认身份验证方案idsrv 2019-03-07 01:19:30.644-06:00 [DBG]使用idsrv作为默认ASP.NET Core用于身份验证的方案2019-03-07 01:19:30.644-06:00 [DBG]使用Identity.External作为默认的ASP.NET Core方案进行签名-在2019-03-07 01:19:30.645-06:00 [ DBG]使用Identity.External作为默认ASP。授权请求中没有用户存在2019-03-07 01:19:31.945-06:00 [DBG]开始授权请求协议验证2019-03-07 01:19:31.983-06:00 [DBG]客户端的客户端配置验证angular_spa成功。2019年3月7日01:19:32.069-06:00 [DBG]调用自定义验证器:IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator 2019年3月7日01:19:32.099-06:00 [INF] ValidatedAuthorizeRequest {“ ClientId”: “ angular_spa”,“ ClientName”:“ Angular 4 Client”,“ RedirectUri”:“ http:// localhost:4200 / auth-callback ”,“ AllowedRedirectUris”:[“ http:// localhost:4200 / auth-callback ” ,“ http:// localhost:4200 / silent-refresh.html“],” SubjectId“:”匿名“,” ResponseType“:” id_token令牌“,” ResponseMode“:”片段“,” GrantType“:”隐式“,” RequestedScopes“:” openid配置文件api1“,”状态“: “ cd6df66e397546d3aab62533de28a2d2”,“ UiLocales”:null,“ Nonce”:“ 8b3af6331d784e9a9cad076555f16174”,“ AuthenticationContextReferenceClasses”:null,“ DisplayMode”:null,“ PromptMode”:null,“ MaxAgeH”:null,“ Login “:null,” Raw“:{” client_id“:” angular_spa“,” redirect_uri“:” http:// localhost:4200 / auth-callback844-06:00 [INF] idsrv未通过身份验证。故障消息:取消保护票证失败2019-03-07 01:19:41.517-06:00 [INF] AuthenticationScheme:Identity.Application已登录。2019-03-07 07:19:41.518-06:00 [INF]用户登录了。2019-03-07 01:19:41.528-06:00 [INF] idsrv未通过身份验证。失败消息:Unprotect票证失败2019-03-07 01:19:41.528-06:00 [INF] idsrv未通过身份验证。失败消息:取消保护票证失败2019-03-07 01:19:41.528-06:00 [DBG]请求路径/连接/授权/回调与端点类型匹配授权2019-03-03-07:19:41.529-06:00 [DBG]启用端点:授权,成功创建的处理程序:IdentityServer4.Endpoints.AuthorizeCallbackEndpoint 2019-03-07 01:19:41.529-06:00 [INF]调用IdentityServer端点:IdentityServer4.Endpoints。用于/连接/授权/回调的AuthorizeCallbackEndpoint 2019-03-07 01:19:41.535-06:00 [DBG]开始授权回调请求2019-03-07 01:19:41.536-06:00 [INF] idsrv未通过身份验证。失败消息:取消保护票证失败2019-03-07 01:19:41.541-06:00 [DBG]授权请求中没有用户2019-03-03-07:19:41.541-06:00 [DBG]开始授权请求协议验证2019-03-07 01:19:41.541-06:00客户端angular_spa的[DBG]客户端配置验证成功。2019年3月7日01:19:41.541-06:00 [DBG]调用自定义验证器:IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator 2019年3月7日01:19:41.541-06:00 [INF] ValidatedAuthorizeRequest {“ ClientId”: “ angular_spa”,“ ClientName”:“ Angular 4 Client”,“http:// localhost:4200 / auth-callback “,” AllowedRedirectUris“:[” http:// localhost:4200 / auth-callback “,” http:// localhost:4200 / silent-refresh.html “],” SubjectId”:“匿名”,“ ResponseType”:“ id_token令牌”,“ ResponseMode”:“片段”,“ GrantType”:“隐式”,“ RequestedScopes”:“ openid个人资料api1”,“ State”:“ cd6df66e397546d3aab62533de28a2d2”, “ UiLocales”:空,“ Nonce”:“ 8b3af6331d784e9a9cad076555f16174”,“ AuthenticationContextReferenceClasses”:空,“ DisplayMode”:空,“ PromptMode”:空,“ MaxAge”:空,“ LoginHint”:空,“ SessionId”:空,“ Raw”:{“ client_id”:“ angular_spa”,“ redirect_uri”:“ http:// localhost:4200 / auth-callback“,” response_type“:” id_token令牌“,” scope“:” openid个人资料api1“,” state“:” cd6df66e397546d3aab62533de28a2d2“,” nonce“:” 8b3af6331d784e9a9cad076555f16174“}},” $ type“:”验证请求“ -07 01:19:41.541-06:00 [INF]显示登录名:用户未通过身份验证2019-03-07 01:19:41.552-06:00 [INF] idsrv未通过身份验证。失败消息:取消保护票证失败2019 -03-07 01:19:41.553-06:00 [INF] idsrv未通过身份验证。失败消息:Unprotect票证失败2019-03-07 01:19:41.553-06:00 [INF] AuthenticationScheme:Identity.External签名出来。
抱歉,我试图正确格式化日志,但是没有用。
更新
我的服务器端配置看起来像这样
public class Config
{
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api1", "My API")
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientSecrets =
{
new Secret("superSecretPassword".Sha256())
},
ClientId = "angular_spa",
ClientName = "Angular 4 Client",
AllowedGrantTypes = GrantTypes.ImplicitAndClientCredentials , //implicit
AllowedScopes = new List<string> { "openid", "profile", "userInfo", "api1" },
//AllowedScopes = new List<string> { StandardScopes.OpenId, StandardScopes.Profile, StandardScopes.Email },
RedirectUris = new List<string> {"http://localhost:4200/auth-callback", "http://localhost:4200/silent-refresh.html"},
PostLogoutRedirectUris = new List<string> { "http://localhost:4200/" },
AllowedCorsOrigins = new List<string> { "http://localhost:4200" },
AllowAccessTokensViaBrowser = true,
Enabled = true,
AllowOfflineAccess = true
}
};
}
public static List<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile() // <-- usefull
};
}
}
我的项目结构如下所示
it doesn't have any controllers. Should it have ?
UPDATE 2 looks like i figured out whats wrong.
The returnUrl
is not resolving properly on the POST
method. it is coming as the complete URL
. if i force it to a proper return URL
it works
var redirect_uri = HttpUtility.ParseQueryString(returnUrl).Get("redirect_uri");
I did as above and used variable 'redirect_uri' in Redirect function. it works but it looks like a hack. Should it automatically get the right thing ?
with this i get 'No state in response' error on Angular side and oidc-client
have no user after redirect.
UPDATE
Looks like I'm using some different nuget
package. HttpContext.SignInAsync
has following constructors.
My HttpContext
seems to be defined in
Microsoft.AspNetCore.Mvc.RazorPages
looks like i have wrong Nugets or something. i am trying to supply a proper ClaimsPrincipal as well but not working.
I see there's a bit of confusion concerning the difference between the returnUrl and the redirect_uri. Although the end goal is a redirect to the client's redirect_uri, after authentication the client must actually redirect to the authorize endpoint for further processing (hence the reason why the url is different). You shouldn't need to change the returnUrl at all and can leave it the way it was.
您现在面临的问题是,在HttpContext.SignInAsync
成功进行身份验证后您无法拨打电话。该SignInAsync
方法用于管理包含用户信息的cookie,该信息告诉returnUrl的端点用户已成功通过身份验证,并且可以将令牌返回给redirect_uri。有很多重载SignInAsync
,但我发现最容易使用的是HttpContext.SignInAsync(string subject, params Claim[] claims)
。完成此操作后,您应该能够完成身份验证。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句