我们正在开发两个(新)ASP.NET应用程序,它们使用MVC / Razor视图作为模板引擎来处理I18N / L10N(当前文化存储在每个请求的cookie中,并从中检索;文本从资源加载。)
两个应用程序通过与MVC应用程序在同一ASP.NET应用程序中托管的单独WebApis来使用相同的WCF服务。 API并由基于Web的应用程序(HTML / JS)访问。
应用程序 A 目前使用表单身份验证(用户凭据由WCF服务根据我们的应用程序数据库进行验证),应用程序 B 使用Windows身份验证。
TL; DR摘要:我们需要了解WCF服务中关于网络用户的内容。
我们需要:
到目前为止,我对此的想法和印象一直是:
到目前为止,我有:
app.UseCookieAuthentication
和app.UseIdentityServerBearerTokenAuthentication
设置身份验证,但我不太确定究竟是什么原因所以我对此不太满意现在。TokenClient.RequestResourceOwnerPasswordAsync(username, password, scopes)
从IdentityServer请求(访问?)令牌,尝试通过访问userinfo来构建ClaimsIdentity
?端点并通过Request.GetOwinContext().Authentication.SignIn(id);
设置Cookie。我没有:
UseIdentityServerBearerTokenAuthentication
,UseOpenIdConnectAuthentication
等)实际上做了什么,应该如何以及何时使用它们以及具有哪些安全隐患。wS2007FederationHttpBinding
做了什么以及它用于什么,或者我必须在Startup.cs
中配置什么以及需要在web.config
或其他地方配置什么{ LI>
基本上,我已经阅读了很多关于WCF,WIF等的内容,我不清楚当前的信息是什么,最佳实践是什么以及如何实现符合我们所有要求的内容。 IdentityServer的例子并没有给我带来太多帮助,因为对我来说,他们无法解释任何事情。
即使您只是帮助我更好地理解术语和技术,我们将非常感谢您的帮助。
P.S。:我们正在运行.NET 4.6
更新
我设法从IdentityServer检索令牌并查询userinfo端点以获取声明。结果我使用ClaimTypes.Email
等而不是Constants.ClaimTypes.Email
- 只有身份范围会在userinfo端点上产生声明,我在资源范围内指定了它们。
我的下一步是试图找出UseIdentityServerBearerTokenAuthentication
如何阻止我访问任何内容以及如果我删除任何必需的范围,为什么它不会...
更新(2015-12-01) 我目前正尝试以某种方式透明地将令牌传输到WCF服务,并根据令牌使当前主体(或声明主体)可用。我还没有明确的方法来实现这一目标。
MVC和WebApi现在似乎工作正常:
使用OWIN cookie中间件保护MVC应用程序 - 在使用表单身份验证的登录时,我使用TokenClient
和资源所有者密码凭据流。然后,我查询userinfo
(通过UserInfoClient
)和introspection
(通过IntrospectionClient
)端点来构建声明,创建ClaimsIdentity
并将其保存在Cookie中。我还将访问令牌保存为声明。
var id = new ClaimsIdentity(listOfClaims, "Cookies");
this.Request.GetOwinContext().Authentication.SignIn(id);
陷阱:内省端点需要作为范围进行身份验证,而不是客户端 - 在样本中略有误导,客户端和范围具有相同的名称
要在每个请求上验证令牌,我将Provider
的{{1}}配置为CookieAuthenticationOptions
,我在new CookieAuthenticationProvider()
期间查询IdentityServer的内省端点:< / p>
OnValidateIdentity
通过扩展用于设置WebApi的app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
LoginPath = new PathString("/User/Login"),
LogoutPath = new PathString("/User/Logoff"),
// setup more options etc..
Provider = new CookieAuthenticationProvider()
{
OnValidateIdentity = async context =>
{
// validate etc. - and if it fails call: context.RejectIdentity();
}
}
}
,WebApi与cookie身份验证分离:
Register(HttpConfiguration config)
此外,我已经在owin启动中设置了// prevent use of owin cookie auth
config.SuppressDefaultHostAuthentication();
// need bearer token auth
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
(基本上,这是我对WebApi做的唯一一件事,因为我有几条途径到几个Apis并且无法设置多个地图通过Ninject依赖注入......)。
IdentityServerBearerTokenAuthentication
当然,仅此一点只意味着角度应用程序无法获取任何数据 - 因此在单页面应用程序视图中,我将令牌作为常量注入配置,并通过配置{设置默认标头{1}}:
查看:
app.Map(
"/api",
inner =>
{
inner.UseIdentityServerBearerTokenAuthentication(identityServerBearerTokenAuthenticationOptions);
});
应用程式:
$httpProvider
...所以我现在唯一的问题就是如何将令牌转移到WCF服务以及如何在服务上设置该令牌的声明身份(无需明确地做到这一点 - 即我不会&#39 ; t我的合约需要一个单独的参数)
P.S。:我只能在<script type="text/javascript">
angular.module("myApp").constant("authorizationHeader", "Bearer @Model");
</script>
中配置WCF服务,因为我们正在使用自托管WCF服务和Ninject ......
更新 2015-12-10 成功的情况下!
我将参考令牌传送到WCF服务,类似于Dominick Baier建议的做法:http://leastprivilege.com/2015/07/02/give-your-wcf-security-architecture-a-makeover-with-identityserver3/
基本上归结为:
myApp.config(["$httpProvider", "authorizationHeader", function ($httpProvider, authorizationHeader) {
$httpProvider.defaults.headers.common["Authorization"] = authorizationHeader;
}]);
app.config
中
Claim
ClaimsIdentity
SecurityTokenDescriptor
Saml2SecurityTokenHandler
创建频道(提示:缓存GenericXmlSecurityToken
但不缓存this.ChannelFactory.CreateChannelWithIssuedToken(xmlToken);
)这意味着我必须将绑定更改为ChannelFactory
,将所有网址更改为使用Channel
以及ws2007FederationHttpBinding
到https
范围内的端口,以便在localhost上进行开发(因为Windows为这些端口预先配置了证书和访问控制列表 - 对于部署,您必须添加证书并允许WCF主机用户在那里托管HTTP / SSL服务。
如果可以看到任何元数据端点,那么它们也必须使用HTTPS(44300
和44399
)
要使用该绑定,安全性必须为binding="mexHttpsBinding"
。
在WCF端,我删除了所有<serviceMetadata httpGetEnabled="false" />
并添加了我自己的TransportWithMessageCredentials
,它解包引用令牌并使用IdentityServer的SecurityTokenHandler
端点来构建身份(非常类似于IdentityServer中的示例) )。
可以在代码或app.config中完成(introspection
是我保留所有这些内容的程序集):
ServiceCommunication
对于授权,我定义了自己的<configSections>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
<system.identityModel>
<identityConfiguration name="identity">
<securityTokenHandlers>
<clear />
<add type="ServiceCommunication.Authentication.IdentityServerWrappedReferenceTokenHandler, ServiceCommunication" />
</securityTokenHandlers>
<claimsAuthorizationManager type="ServiceCommunication.Authorization.ClaimsAuthorizationManager, ServiceCommunication"/>
</identityConfiguration>
,它处理被覆盖的ClaimsAuthorizationManager
方法中的所有内容。注意:也为每个WCF合同方法调用该方法。
授权可以通过CheckAccess
通过任何普通代码进行,也可以通过ClaimsPrincipalPermissionAttribute
进行明确授权。甚至不必是WCF。在.NET 4.5中开箱即用
我在我的WCF服务中尽可能深入使用ClaimsPrincipalPermission
,并在MVC / API控制器操作上使用。{/ p>
现在,我已获得所有用户的身份验证,阻止访问未经身份验证的用户(使用重定向登录)并保证只有授权用户才能访问特定方法。 :)
答案 0 :(得分:1)
所以我终于解决了这一切:
app.UseCookieAuthentication
使用我自己的CookieAuthenticationProvider
验证MVC中的引用令牌,并像以前的表单身份验证一样处理登录app.UseIdentityServerBearerTokenAuthentication
(每个http请求必须设置带有值Authorize
的标头Bearer your-token-here
,大多数JS框架允许您全局设置它。身份验证针对IdentityServer,我已经配置了ClientId和ClientSecret(实际上是ScopeId和ScopeSecret),因此它使用了introspection-endpoint。 小心:您只能获得该特定范围的声明,而不是其他范围。IdentityModel
个客户端进行身份验证和验证(以及从userinfo和内省端点获取声明)Ws2007FederationHttpBinding
和TransportWithMessageCredentials
安全SecurityTokenHandler
在WCF服务上打开该令牌并验证它(并设置身份/主体)ClaimsAuthorizationManager
通过ClaimsPrincipalPermission
(Attribute
)答案 1 :(得分:0)
新的互联网安全协议(如OAuth2和OpenID Connect)与WCF SOAP服务不兼容。
授权服务器在使用OAuth2和OpenID Connect协议时会发出JWT令牌。但是,当您使用WS2007FederationHttpBinding
时,您的SOAP WCF服务需要在信封标头中使用SAML令牌。 IndentityServer does not issue SAML tokens
虽然可以使用JWT令牌的声明来发布和签署您自己的SAML令牌,但使用基于REST的服务替换WCF SOAP服务可能更容易,这些服务需要Authorization
标头中的JWT令牌
我不确定您为什么要使用资源所有者密码凭据流。您可能需要查看using IdentityServer with an existing database并使用身份验证代码流。
P.S。 IdentityServer和Katana(Microsoft的OWIN实现)都是开源的,因此您可以弄清楚所有这些代码实际上在做什么。