【问题标题】:UI to Web Services communication with custom authorization using .NET technologiesUI 与使用 .NET 技术的自定义授权进行 Web 服务通信
【发布时间】:2013-01-27 12:18:41
【问题描述】:

我正在尝试设计一个 Web 应用程序,该应用程序将使用 WCF 服务来访问数据并提供业务逻辑。所以总的来说,整个系统看起来像这样:

UI (ASP.NET MVC)
BusinessLayer (WCF Services)
DataLayer (Entity Framework)
Date (SQL Server Database)

系统的所有部分都将抵抗同一个封闭环境,因此我将使用证书来保护ASP.NET <-> WCF 连接。数据库连接将使用标准 EF 证券、连接字符串和 Windows 身份验证。

应用程序必须提供身份验证和授权功能。我将把大部分内容移到 ASP.NET 中,所以会有 ValidateUserAuth() 服务方法,用于验证凭据,但结果(用户所属的 UserRole)随后将由ASP 创建用户会话。

之后,每个服务方法调用都需要知道当前用户的 UserRole,才能返回正确的结果(或在必要时说“拒绝访问”)。 问题是我不想将 UserRole 作为每个服务方法的参数传递!我想让它自动发生。 WCF 甚至可以吗?

我只需要:

  • 从 ASP.NET 应用程序发出的每个服务调用都将使用从当前 ASP 会话中获取的用户数据进行扩展。
  • 该调用调用的服务方法将能够接收该用户数据并根据用户权限使用它来提供结果。
  • 所有这一切都会以某种方式在后台发生,因此不会向从 Service 公开的每个 Service Method 添加额外的 UserDetails 方法参数。

我阅读了很多关于 WCF 本身的内容,但发现了可以满足我要求的任何内容。我希望我只是错过了它,它仍然是可能的。

【问题讨论】:

    标签: asp.net wcf authorization soa


    【解决方案1】:

    以纯格式将用户角色从客户端传递到服务器将是一个设计错误。客户端可以通过在应用程序范围之外随意调用它们来轻松滥用您的服务。

    您为什么不依赖角色提供者?这样,您从客户端传递的只是身份(甚至可以是表单 cookie),然后在服务器端读取所有角色。您甚至可以使用内置机制在角色 cookie 中缓存角色。

    前段时间,我写了两篇关于使用表单身份验证保护 wcf 的教程,以便轻松集成网页和活动客户端

    http://netpl.blogspot.com/2008/02/clickonce-webservice-and-shared-forms.html

    http://netpl.blogspot.com/2010/04/aspnet-forms-authentication-sharing-for.html

    【讨论】:

    • WCF 服务将关闭,因此无法直接从 Internet 调用它。它不会使以普通形式传递 userId 或 userRole 有效吗?
    • 我认为是请求伪造威胁,您的 api 可能会导致滥用它。我认为从 Internet 还是从 Intranet 调用 api 都无关紧要 - 您仍然不希望用户能够假装他们是管理员,就像调用具有特定组合的 web 方法一样简单论据。
    【解决方案2】:

    我决定为此使用 MessageInspector:

    在客户端:

    Public Function BeforeSendRequest(ByRef request As System.ServiceModel.Channels.Message, channel As System.ServiceModel.IClientChannel) As Object Implements System.ServiceModel.Dispatcher.IClientMessageInspector.BeforeSendRequest
        Dim requestMessageProperty = New HttpRequestMessageProperty()
    
        Dim currentUser = Authentication.AuthenticatedStaffcareUser
    
        If currentUser Is Nothing Then Throw New ApplicationException()
    
        requestMessageProperty.Headers("UserName") = currentUser.UserName
        requestMessageProperty.Headers("UserId") = currentUser.UserID
        requestMessageProperty.Headers("UserRole") = currentUser.UserRole
        requestMessageProperty.Headers("EffectiveDate") = currentUser.EffectiveDate
        request.Properties(HttpRequestMessageProperty.Name) = requestMessageProperty
    
        Return Nothing
    End Function
    

    和服务器端:

    Public Function AfterReceiveRequest(ByRef request As Message, channel As IClientChannel, instanceContext As InstanceContext) As Object Implements IDispatchMessageInspector.AfterReceiveRequest
        Dim messageProperty = CType(OperationContext.Current.IncomingMessageProperties(HttpRequestMessageProperty.Name), HttpRequestMessageProperty)
    
        Dim userName = messageProperty.Headers("UserName")
        Dim userId = Integer.Parse(messageProperty.Headers("UserId"))
        Dim userRole = messageProperty.Headers("UserRole")
        Dim effectiveDate = DateTime.Parse(messageProperty.Headers("EffectiveDate"))
    
        Dim identity = New AppServerUserIdentity(userName, userId, userRole, effectiveDate)
        Dim principal = New AppServerUserPrincipal(identity)
    
        Threading.Thread.CurrentPrincipal = principal
    
        Return Nothing
    End Function
    

    我还必须设置自定义 AuthorizationPolicy 以防止标准的 AuthorizationPolicy 覆盖 Thread.CurrentPrincipal:

    Public Function Evaluate(evaluationContext As EvaluationContext, ByRef state As Object) As Boolean Implements IAuthorizationPolicy.Evaluate
    
        Dim principal = TryCast(Threading.Thread.CurrentPrincipal, AppServerUserPrincipal)
    
        If principal Is Nothing Then
            Return False
        Else
            evaluationContext.Properties("Principal") = principal
            Return True
        End If
    End Function
    

    【讨论】:

      猜你喜欢
      • 2013-03-17
      • 1970-01-01
      • 1970-01-01
      • 2012-10-13
      • 2018-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多