我正在构建一个应用程序,其中需求似乎是标准问题(至少对我而言)...我有一个基于asp .net mvc&的Web.UI。来自iphone,andriod&的客户黑莓。
因此,明智的做法是将我的所有业务逻辑移动到可以通过http访问的服务层。这个服务层必须接受具有用户上下文(身份)的请求,并且以一种不错的方式执行授权,无论哪种类型的客户端与之通信(我希望?)。
一年多的时间我做了3个月的演出,雇用了W.I.F. (Windows Identity Foundation)在混合内部部署和云架构。我喜欢它。引起共鸣的三件事是(1)外化认证而不关心如何完成,(2)从业务逻辑中删除授权逻辑,(3)基于声明的授权。
在过去的一年里,我听到并关注Rest Services的所有关于'新的酷嬉戏做事方式'。所以我虽然很棒,但试试吧。在我开始玩游戏之后得到编码,我开始变得非常困惑(并且随后在没有编写另一行c#的情况下读取了大约10个小时)。我仍然对所有SOAP vs REST,WS。* vs Http,SAML vs SWT babble感到困惑。我真的不希望这个线程是关于那个,因为有足够的说法在stackoverflow,但我觉得我有两个阵营之间的选择,当它不是真的感觉我想要一个或另一个但每个位?
对我而言,我上面提到的关于WIF的3点似乎并不像应该与WS绑定的概念。*?但是我感觉他们,或者至少是WIF如何在没有专家调整的情况下实现它们(例如我几天前才发现这篇文章 - http://zamd.net/2011/02/08/using-simple-web-token-swt-with-wif/)。
我不太了解的其他方面是我的客户端(iphone,andriod,blackberry)能够使用WIF,是不是向他们抛出SAML令牌的STS,它们的行为就像浏览器一样像任何其他客户端一样将它传回头部?是的,我将不得不寻找,但如果这是与W.I.F的交易破坏,我发布后直接发现,那么至少我可以远离它。
最后还要再加一点。我真的不想考虑这些。我想使用第三方身份验证/身份提供商 - http://www.janrain.com/products/engage - 我相信它使用OpenID。这适合W.I.F.或者我只是从OpenID创建一个新的SAML令牌,并从那时起使用WIF。
我想在这个喋喋不休的结尾,我想回到我开始的地方,因为越来越复杂,我问的问题越多,我考虑的选择就越多。
是否有一个服务层(在WCF上)与不同的非.NET客户端进行通信,这些客户端需要身份上下文和授权如此奇怪?如果你已经建立了这样的东西,你是怎么做到的?
答案 0 :(得分:2)
当你拥有许多设备时,一种方法是让所有设备都能使用相同的解决方案,就是针对最低的公分母。
假设您的所有客户都支持Cookie。这样做的一种方法是:
不像使用SAML令牌那样优雅,但它可以跨平台/设备工作。
IPhone支持Cookie http://support.apple.com/kb/HT1675
Blackberry支持Cookie http://docs.blackberry.com/en/developers/deliverables/11844/feature_cookie_storage_438273_11.jsp
答案 1 :(得分:1)
答案 2 :(得分:0)
当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中进行子类化:
public class MyClaimsAuthenticationManager : ClaimsAuthenticationManager
{
public override IClaimsPrincipal Authenticate(string resourceName, IClaimsPrincipal incomingPrincipal)
{
if (!incomingPrincipal.Identity.IsAuthenticated)
{
return incomingPrincipal;
}
//TODO: obtain user profile claims from external source, i.e. database, web service
// below code demonstrates how to custom claims to the current principal
// (which are then persisted for the lifecycle of the user's browser session)
IClaimsIdentity identity = (IClaimsIdentity)incomingPrincipal.Identity;
identity.Claims.Add(new Claim(ClaimTypes.Email, "dave@dave.com"));
return incomingPrincipal;
}
}
public override IClaimsPrincipal Authenticate(string resourceName, IClaimsPrincipal incomingPrincipal)
{
if (!incomingPrincipal.Identity.IsAuthenticated)
{
return incomingPrincipal;
}
//TODO: obtain user profile claims from external source, i.e. database, web service
// below code demonstrates how to custom claims to the current principal
// (which are then persisted for the lifecycle of the user's browser session)
IClaimsIdentity identity = (IClaimsIdentity)incomingPrincipal.Identity;
identity.Claims.Add(new Claim(ClaimTypes.Email, "dave@dave.com"));
return incomingPrincipal;
}
}
您需要通过设置claimAuthenticationManager配置参数告诉WIF在Web.config文件中使用您自己的声明管理器。
希望这有帮助。
答案 3 :(得分:0)
我使用spring + java解决了类似的问题;它需要的所有概念都在.net中,所以我在这里提到它。我发现spring-security提出的解决方案运行良好(我的简单授权要求)。在我的服务层中,需要特定权限的方法通过注释(在接口或实现上)声明这一点:
@Secured(MyPermissions.READ, MyPermissions.WRITE)
void modifyPerson(PersonChanges changes);
@Secured(MyPermissions.READ)
Person readPerson();
在此示例中,安全框架(spring)使用动态代理包装服务实现,动态代理验证我的授权层是否已将正确的线程范围角色/权限放在评估服务方法的上下文中,如果不是安全性抛出异常。
我还发现将URL模式需要权限的服务组合在一起很有帮助,因此需要在最高级别处理“需要经过身份验证的主体”要求: myapp/services/secure/personService
- 如果不存在身份验证信息,任何需要* / secure的URL模式都将重定向到身份验证页面。
关于需要线程范围凭据的真正好处(我虽然),即使顶级HTTP拦截器设置错误(例如无法验证/创建身份验证会话),只要动态代理正在工作业务逻辑无法执行。
此外,它对聚合服务非常有效 - 如果一个服务调用另一个服务,如果未在组合服务上正确声明它们,则仍会强制实施较低级别的授权规则。