.net n 层身份和服务架构中的授权
我正在构建一个应用程序,其中的要求似乎是标准问题(至少对我来说)...我有一个基于 asp .net mvc & 的 Web.UI。来自 iPhone、Andriod 和 Android 的客户黑莓。
因此,明智的做法是将所有业务逻辑移动到可以通过 http 访问的服务层中。该服务层必须接受具有用户上下文(身份)的请求,并以某种良好的方式一致地执行授权,无论哪种类型的客户端与之通信(我希望?)。
在一年多的时间里,我做了一次为期 3 个月的工作,在本地和本地混合环境中使用了 WIF(Windows Identity Foundation)。云架构。我喜欢它。引起共鸣的三件事是 (1) 将身份验证外部化,而不关心它是如何完成的,(2) 从业务逻辑中删除授权逻辑,(3) 基于声明的授权。
在过去的一年里,我听说并看到了有关休息服务的“新酷嬉皮做事方式”。所以我觉得很好,让我们尝试一下。当我开始玩&当我开始编码时,我开始变得非常困惑(随后昨天读了大约 10 个小时,但没有再写一行 c#)。我仍然对所有 SOAP 与 REST、WS.* 与 Http、SAML 与 SWT 的胡言乱语感到困惑。我真的不希望这个帖子是关于这个的,因为 stackoverflow 上已经有足够多的讨论了,但我觉得我可以在两个阵营之间做出选择,而我并不真正想要其中一个但每个人的比特?
对我来说,我上面提到的关于 WIF 的 3 点似乎不应该与 WS.* 联系在一起的概念?但我感觉它们,或者至少是 WIF 目前的方式使得它们,没有经过一些专家的调整(例如,我发现了几天前才写的这篇文章 - http://zamd.net/2011/02/08/using-simple-web-令牌-swt-with-wif/)。
我不太了解的其他领域是我的客户端(iphone、andriod、黑莓)能够使用 WIF,是否是同一个 STS 向它们抛出 SAML 令牌,它们的行为就像浏览器一样并将其传回像其他客户端一样在标头中?是的,我必须找出答案,但如果这是与 WIF 的交易破坏者,并且我在发布此内容后立即发现,那么至少我可以将注意力从它身上移开。
最后再添加一件事。我真的不想考虑这些。我想使用第三方身份验证/身份提供商 - http://www.janrain.com/products/engage - 我相信它使用 OpenID。这可以适合 WIF 还是我只是从 OpenID 创建一个新的 SAML 令牌并从那时起使用 WIF。
我想在这篇废话结束时,我想回到我开始的地方,因为我问的问题越多,考虑的选择越多,事情就会变得越来越复杂。
拥有一个与需要身份上下文和授权的不同非 .net 客户端通信的服务层(在 WCF 上)很奇怪吗?如果您已经构建了这样的东西,您是如何实现的?
I'm building an application where the requirements seem standard issue (at least to me)... I have a Web.UI based on asp .net mvc & clients from iphone, andriod & blackberry.
So the sensible thing to do is to move all my business logic into a services layer that can be accesses over http. This services layer must accept requests with a user context (identity) and in some nice way perform authorization consistently no matter which type of client is communicating with it (I hope?).
Over a year a go I did a 3 month gig that employed W.I.F. (Windows Identity Foundation) in a hybrid on-premises & cloud architecture. I liked it. The 3 things that struck a chord were (1) externalizing authentication and not caring how it was done, (2) removing authorization logic from business logic, (3) Claims based authorization.
Over the last year I've heard and watch all about Rest Services the 'new cool hippy way of doing things'. So I though great, let's try that. After I started to play around & get coding, I started getting really confused (and subsequently read for about 10 hours yesterday without writing another line of c#). I'm still confused about all the SOAP vs REST, WS.* vs Http, SAML vs SWT babble. I don't really want this thread to be about that because there is enough of that speak on stackoverflow, but I feel like I've got a choice between two camps, when it doesn't really feel like I want one or the other but bits from each?
To me the 3 points I mentioned above about WIF don't seem like concepts that should be tied to WS.* ? But I'm getting the feeling that they, or at least how WIF comes at the moment makes them, without some expert tweaking (e.g. I came across this post only written a few days ago - http://zamd.net/2011/02/08/using-simple-web-token-swt-with-wif/).
The other areas I don't know much about is are my clients (iphone, andriod, blackberry) capable of playing with WIF, is it the same STS that throws a SAML token to them and they behave just like a browser and pass it back in a header just like any other client? Yes I'm going to have to find out, but if this is a deal breaker with W.I.F and I find out straight after posting this, then at least I can focus away from it.
Finally to throw one more thing in the mix. I don't really want to think about any of this. I want to use a 3rd party authentication / identity provider - http://www.janrain.com/products/engage - which I believe uses OpenID. Can this fit into W.I.F. or do I just create a new SAML token from the OpenID and use WIF from that moment on.
I guess at the end of this babble, I want to come back to where I started because it's getting more and more complicated the more questions I ask and the more options I consider.
Is having a services layer (on WCF) that talks to different non-.net clients that requires identity context and authorization so strange? If you've build something like this, how did you approach it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您拥有许多设备时,让相同的解决方案在所有设备上运行的一种方法是瞄准最低公分母。
假设您的所有客户端都支持 cookie。实现此目的的一种方法是:
不像使用 SAML 令牌那么优雅,但它确实可以跨平台/设备工作。
iPhone 支持 cookies http://support.apple.com/kb/HT1675
Blackberry 支持 cookies http://docs.blackberry.com/en/developers/deliverables/11844/feature_cookie_storage_438273_11 .jsp
When you have many devices, one way to get the same solution working across all of them, is to target the lowest common denominator.
Assuming that all your clients support cookies. One way of doing this would:
Not quite as elegant as using SAML tokens, but it does work cross platform / devices.
IPhone supports cookies http://support.apple.com/kb/HT1675
Blackberry supports cookies http://docs.blackberry.com/en/developers/deliverables/11844/feature_cookie_storage_438273_11.jsp
我将尝试稍微更抽象地回答您的问题...
在开始之前,我的背景是 MS 偏见,因此其他来源可能有相同(或更好)的选择。
我发现两个非常有用的参考:
1) 基于声明的身份和访问控制指南
http://msdn.microsoft.com/en-us/library/ff423674.aspx
2) 编程 Windows Identity Foundation
作者:Vittorio Bertocci
提供 Kindle 格式的硬拷贝
还有很多其他来源,但这两个来源涵盖了几种情况,并为任何想要加快入门速度的人提供了良好的背景信息。
我鼓励其他发帖者填补任何空白或错误陈述:)
我掩盖了许多技术细节,以专注于所提出的问题。
我分解联合身份的方式大致如下:
STS 负责验证用户的身份并为某些声明提供担保。
它通过提供 (1) 包含声明的签名 blob 或 (2) 第三方可用于查找声明的唯一标识符来实现此目的。
想要向用户提供服务的应用程序可以“信任”STS 为其提供可用于与用户适当协作的声明,从而减轻其验证用户的责任(除其他事项外,例如维护集中式元数据,但我离题了)。
STS 还具有“信任”另一个 STS 的能力,基本上是说“如果你说这个人是 Joe Smith,并且他们有 X、Y 和 Z 角色,那么我将为你所说的保证!”
因此,换句话来说:
应用程序“信任”一个 STS { 反过来又可以“信任”另一个 STS } 来提供它/它们 声明
** 切换装置 **
SOAP 与 REST
归根结底,SOAP 和REST 都是服务类型,我们称它们为声明消费者。他们都希望有人给他们装满索赔的桶,这样他们就可以完成工作并寄回一些东西。
此外,两种服务类型都可以通过使用令牌的查询字符串(假设服务可以处理某些 URL 重写)或通过标头(用于 REST 的 HTTP 和用于 SOAP 服务的 SOAP)来提供声明。无论哪种方式,目标都是相同的:将声明或 UID 传输到应用程序。
WS* 与 HTTP
这些(以及 TCP/IP、SSL、秘密解码器环等)是来回传递信息的方法,尽管中间人无法找到模拟用户的方法,但有不同程度的确定性。
SAML 与 SWT
这些(以及 Base 64 编码、xml、简单文本等)都是序列化声明的方法。这两个恰好符合其他人不符合的标准,因此每个人都可以说相同的语言。
** 回到正题 **
这些技术组合中的每一种都是有效的(取决于应用程序,有些不太安全,有些更容易实现,有些在较低级别的设备上工作得更好,等等)并且只是一个人的方式做自己的工作和别人的工作。
因此,如果我有一个 .Net 应用程序,该应用程序已通过 WS* 管道以 SAML 格式提供一组声明,则最终结果是该应用程序具有 [SAML 中的声明]。
通过一些处理,这些可以转化为[SWT 中的声明]。
然后可以将新声明打包并通过 HTTP/SSL 发送到 Java 应用程序。
如果 Java 应用程序“信任”同一个 STS(或“信任”.Net 应用程序 STS 的 STS),那么它就会打开声明并执行其工作。
你提到的专家调整必须发生,问题只是由谁进行以及透明度如何
在不同的平台/设备/应用程序/等上提供服务的想法一点也不奇怪,这正是所有这些东西正在构建的场景,以解决
我正在尝试构建类似您所询问的内容的过程,所以我一直在做同样的事情我自己也有这样的问题。
您提到的 Engage 服务允许您将应用程序的用户与外部源关联起来,并可用于对这些用户进行身份验证...
ala“我看到您通过 Google 进行了身份验证,身份为 [电子邮件受保护],我知道你是 John Walker,id 为 4321,哦,看,你把你在 google 中最喜欢的颜色设置更改为蓝色......继续!”
它不做的是向您的应用程序提供特定于您的应用程序的声明(除非您需要知道的所有内容都来自 google 数据,在这种情况下您可能构建的是混搭而不是 LOB 应用程序...
另一个场景:
更 喜欢蓝色?” Microsoft 提供的 AppFabric 访问控制服务 (http://msdn.microsoft.com/en-us/library/ee732536.aspx)
免责声明:我还没有使用过它,但是,它看起来就像您正在寻找的那种翻译,并且为您隐藏了很多内容。
I'm going to take a crack at answering your question slightly more abstractly...
Before I begin, my background is MS biased so there may be equal (or better) options available from other sources.
Two references that I found very useful:
1) A Guide to Claims-based Identity and Access Control
http://msdn.microsoft.com/en-us/library/ff423674.aspx
2) Programming Windows Identity Foundation
Author: Vittorio Bertocci
Available in hard copy of kindle formats
There are alot of other sources but these two cover several scenarios and give good background info for anyone that wants to get up to speed with your starting point.
I encourage other posters to fill in any gaps or mistatements :)
I'm glossing over a slew of technical details to focus on the question asked.
The way I break federated identity down is, roughly, as follows:
An STS is responsible for verifying the identity of a user and vouching for some claims.
It does this by either providing (1) a signed blob containing the claims or (2) a unique identifier that a 3rd party can use to lookup the claims.
An application that wants to provide a user with a service can "trust" an STS to provide it with claims it can use to work with the user appropriately, thus aleviating it of the responsibility of verifying the user (among other things such as maintaining centralized meta-data but I digress).
There is also the ability for an STS to "trust" another STS, basically saying "If you say this person is Joe Smith and they have X, Y and Z roles, then I'll vouch for what you say!"
So to paraphrase:
App(s) "trust" an STS { which can in turn "trust" another STS } to provide it/them Claim(s)
** Switching Gears **
SOAP vs REST
At the end of the day SOAP and REST are both Service types, lets call them Claims consumers. They both want someone to give them a bucket full of claims so they can do their work and send back some stuff.
Additionally, both service types can be presented with claims via query string using a token (assuming the service can handle some url rewriting) or via a header (HTTP for REST and SOAP for, well, SOAP services). Either way the goal is the same: Transmit the claims or the UID to the App.
WS* vs HTTP
These (along with TCP/IP, SSL, secret decoder rings, etc) are methods of passing information back and forth, albeit with varying degrees of certainty that someone in the middle can't find a way to impersonate the user.
SAML vs SWT
These (along with base 64 encoding, xml, simple text, etc) are both methods of serializing claims. These two just happen to conform to standards that the others don't so everyone can speak the same language.
** Getting back to the point **
Each of those technology combinations are valid (depending on the application, some are less secure, others are easier to implement, others work better on lower level devices, etc) and are just one person's way of doing the job vs another's.
So if I have a .Net application that has been served a set of claims in SAML fomat over a WS* pipeline the end result is that the applciation has [claims in SAML].
With some processing these can be transformed into [claims in SWT].
The new claims can then be packaged up and sent via HTTP/SSL to a Java application.
IF the Java application "trusts" the same STS (or an STS that "trusts" the .Net apps STS) then it opens up the claims and does its work.
The expert tweaking you mention has to happen, the question is simply by whom and how transparant is it
The idea of having services on disparate platforms/devices/applications/etc is not strange at all, that's exactly the kind of scenario all this stuff is being built to address
I am in the process of trying to build something like what you are asking about so I've been working on the same kind of issues myself.
The Engage service you mentioned allows you to associate your application's users with outside sources and can be used to authenticate those users...
ala "I see you authenticated with google as [email protected], I know you as John Walker with an id of 4321, oh, look, you changed your favorite color setting in google to blue... carry on!"
What it doesn't do is provide claims to your application that are specific to your application (unless all you need to know comes from the google data in which case you're likely building a mash up and not an LOB application...
Another scenario:
Another place that I would direct you to is the AppFabric Access Control service offered by Microsoft. (http://msdn.microsoft.com/en-us/library/ee732536.aspx)
disclaimer: I haven't used it yet but, it looks like it does the kinds of translations you are looking for with a lot of the meat hidden away for you.
当 WIF 在底层讨论 WS-Trust / WS-Federation 时,您可以在服务层公开基于声明的身份验证。
本文介绍如何创建将使用这些协议与外部客户端通信的 WCF STS。
http://msdn.microsoft.com/en-us/library/ee748498.aspx
从服务层的授权角度来看,您可以使用自定义授权管理器来检查是否已提出声明。
http://msdn.microsoft.com/en-us/library/ms731774.aspx
要插入外部身份服务(例如 OpenID)并将您自己的声明添加到 WIF 生成的声明中,您可以从 ClaimsAuthenticationManager 进行子类化,如下所示:
公共类 MyClaimsAuthenticationManager :ClaimsAuthenticationManager
{
您需要通过设置claimsAuthenticationManager 配置参数来告诉WIF 在Web.config 文件中使用您自己的声明管理器。
希望这有帮助。
As WIF talks WS-Trust / WS-Federation under the hood, you can expose claims-based authentication at the services layer.
This article shows how to create a WCF STS that will talk to external clients using these protocols.
http://msdn.microsoft.com/en-us/library/ee748498.aspx
From an authorisation point of view at the services layer you can use a custom authorisation manager to check that claims have been presented.
http://msdn.microsoft.com/en-us/library/ms731774.aspx
To plug in external identity services such as OpenID and add your own claims into those generated by WIF then you can sub-class from ClaimsAuthenticationManager as follows:
public class MyClaimsAuthenticationManager : ClaimsAuthenticationManager
{
You'll need to tell WIF to use your own claims manager in the Web.config file by setting the claimsAuthenticationManager configuration parameter.
Hope this helps.
我使用 spring+java 解决了类似的问题;它需要的所有概念都在 .net 中,所以我在这里提到它。我发现 spring-security 提出的解决方案效果很好(对于我的简单授权要求)。在我的服务层中,需要特定权限的方法通过注释(在接口上或在实现上)声明这一点:
在此示例中,安全框架(spring)使用动态代理包装服务实现,该动态代理验证我的授权层是否已放置如果没有抛出安全异常,则正确的线程范围角色/权限位于评估服务方法的上下文中。
我还发现通过 URL 模式将需要权限的服务分组在一起很有帮助,以便在最高级别处理“需要经过身份验证的主体”要求:例如
myapp/services/secure/personService
--如果不存在身份验证信息,则任何需要 */secure 的 URL 模式都将重定向到身份验证页面。需要线程范围的凭据的真正好处(我认为)是,即使顶级 HTTP 拦截器设置错误(例如,无法验证/创建身份验证会话),只要动态代理正在工作,就不会出现任何问题。执行业务逻辑的方式。
此外,它对于聚合服务非常有效——如果一个服务调用另一个服务,如果未在组合服务上正确声明较低级别的授权规则,则仍然会执行较低级别的授权规则。
I have approached a similar problem using spring+java; all the concepts it requires are in .net so I mention it here. I found the solution which spring-security puts forward worked well (for my simple authorization requirements). In my services layer, methods which require specific permissions declare this via annotations (either on the interface or on the implementation):
In this example the security framework (spring) wraps the service implementations with a dynamic proxy which verifies that my authorization layer has put the proper thread scoped roles/permissions are in the context where the service method is evaluated, if not a security exception is thrown.
I also found it helpful to group together services which require permissions by URL patterns, so that the "requires an authenticated principal" requirement is handled at the highest level: e.g.
myapp/services/secure/personService
-- any URL pattern requiring */secure will redirect to the authentication page if no authentication info exists.What is really nice (I though) about requiring thread scoped credentials, is that even if the top level HTTP interceptor setup is done wrong (e.g. fails to verify/create an authentication session), as long as the dynamic proxy is working there is no way the business logic can get executed.
Also, it works really nicely for aggregate services -- if one service calls another, lower level authorization rules are still enforced if they are not properly declared on the composite service.