.net n-tier identity&服务架构授权

时间:2011-02-18 17:34:23

标签: .net wcf architecture soa wif

我正在构建一个应用程序,其中需求似乎是标准问题(至少对我而言)...我有一个基于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客户端进行通信,这些客户端需要身份上下文和授权如此奇怪?如果你已经建立了这样的东西,你是怎么做到的?

4 个答案:

答案 0 :(得分:2)

当你拥有许多设备时,一种方法是让所有设备都能使用相同的解决方案,就是针对最低的公分母。

假设您的所有客户都支持Cookie。这样做的一种方法是:

  • 拥有基于cookie的身份验证系统。
  • 在服务器端缓存所有授权信息,链接到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拦截器设置错误(例如无法验证/创建身份验证会话),只要动态代理正在工作业务逻辑无法执行。

此外,它对聚合服务非常有效 - 如果一个服务调用另一个服务,如果未在组合服务上正确声明它们,则仍会强制实施较低级别的授权规则。