【发布时间】:2017-05-08 14:03:46
【问题描述】:
我之前问过question,得到的答案是正确的,但我越深入这个兔子洞,我就越意识到;我不认为我问的是正确的问题。
让我用最简单的术语解释一下……我有一个 AngularJS 单页应用程序(客户端),它指向一个 asp.net webapi (OWIN) 站点(资源服务器?),还有一个单独的asp.net“授权/身份验证”服务器。
身份验证服务器将为多个应用程序提供身份验证和授权。我需要能够在资源服务器中使用 Authorize 属性,以及从 angular 获取令牌。我还需要对所有内容使用 Windows 身份验证(集成),无需用户名或密码。索赔信息存储在数据库中,需要添加到令牌中。
我已经在 asp.net 核心中使用带有 JwtBearerToken 和“密码流”的 openiddict 完成了 SSO 风格的声明授权实现?并想尝试做类似的事情(令牌等)。从我之前的实现中,我对它的工作原理有了基本的了解,但是我完全迷失了试图弄清楚如何让 JWT 与 Windows Auth 一起工作。我上一个问题的答案提供了一些很好的建议,但我很难看到这在这种情况下如何应用。
目前我一直在尝试使用 WindowsAuthentication 扩展来让 IdentityServer3 执行此操作,主要是从示例中提取的。但我真的很难将它与客户联系在一起并真正得到一些工作。当前的客户端和服务器代码如下,请注意,我真的不知道这是否接近正确的解决方案。
客户:
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Passive,
AuthenticationType = "windows",
Authority = "http://localhost:21989",
ClientId = "mvc.owin.implicit",
ClientSecret = "api-secret",
RequiredScopes = new[] { "api" }
});
认证服务器:
app.Map("/windows", ConfigureWindowsTokenProvider);
app.Use(async (context, next) =>
{
if (context.Request.Uri.AbsolutePath.EndsWith("/token", StringComparison.OrdinalIgnoreCase))
{
if (context.Authentication.User == null ||
!context.Authentication.User.Identity.IsAuthenticated)
{
context.Response.StatusCode = 401;
return;
}
}
await next();
});
var factory = new IdentityServerServiceFactory()
.UseInMemoryClients(Clients.Get())
.UseInMemoryScopes(Scopes.Get());
var options = new IdentityServerOptions
{
SigningCertificate = Certificate.Load(),
Factory = factory,
AuthenticationOptions = new AuthenticationOptions
{
EnableLocalLogin = false,
IdentityProviders = ConfigureIdentityProviders
},
RequireSsl = false
};
app.UseIdentityServer(options);
private static void ConfigureWindowsTokenProvider(IAppBuilder app)
{
app.UseWindowsAuthenticationService(new WindowsAuthenticationOptions
{
IdpReplyUrl = "http://localhost:21989",
SigningCertificate = Certificate.Load(),
EnableOAuth2Endpoint = false
});
}
private void ConfigureIdentityProviders(IAppBuilder app, string signInAsType)
{
var wsFederation = new WsFederationAuthenticationOptions
{
AuthenticationType = "windows",
Caption = "Windows",
SignInAsAuthenticationType = signInAsType,
MetadataAddress = "http://localhost:21989",
Wtrealm = "urn:idsrv3"
};
app.UseWsFederationAuthentication(wsFederation);
}
编辑:我看到“/.well-known/openid-configuration”以及“/.well-known/jwks”的身份验证端点请求,并且我在正在调用的控制器操作上有 Authorize 属性,但我没有看到身份验证方面发生任何其他事情。我还在 usewindowsauthservice WindowsAuthenticationOptions 中添加了一个 ICustomClaimsProvider 实现,但它甚至没有被调用。
【问题讨论】:
-
如果您使用集成的 Windows 身份验证,为什么还需要令牌?使用 Windows 身份验证,您的域控制器就是您的“身份提供者”。在您的“资源服务器”上,您可以访问当前用户的身份,并且可以使用授权属性来限制访问等......也许我遗漏了一些东西,但您似乎添加了很多需要注意的安全基础设施由 Windows 身份验证。
-
因为我需要增加对来自数据库的自定义声明提供的令牌的声明。基本上,我需要匹配一些 AD 组成员资格并使用 AD 组从数据库中添加一些声明。有一个 WebAPI 端点需要授权某些操作,但我还需要在应用程序的客户端(角度)端使用令牌和声明。我有一些 js 代码可以解码 JWT 令牌以获取声明,因此我可以交互地提供一些表面级状态(角度 ui-router)授权,如果这有意义的话?
-
我还有一个自定义 AuthorizeAttribute,它接受一个字符串,其中包含允许访问该端点的声明的名称。那里的 cliams 校长似乎是正确的。
-
我可能没有听懂你所说的一切,但如果你的 web api 是由 windows auth 保护的,它可以知道当前用户,它的组成员身份,也可以去你的数据库进行其他决定。对我来说,这负责服务器端。从那里,我希望前端应用程序会从服务器获取授权信息(仅用于此目的的 api?),而不是尝试解码令牌等......
-
这实际上是它以前的工作方式,也是我试图取代的。我不能让 WebAPI 直接与安全数据库对话。身份验证服务器将被其他服务使用,基本上是单点登录系统,只使用用户当前的 Windows 帐户,而不需要用户名/密码。客户端(WebAPI 应用程序)是完全独立的应用程序,只需要检查 ClaimsPrincipal 上的声明是否存在。
标签: c# asp.net angularjs authentication asp.net-web-api