WCF 服务:使用 AD 对 WebGet 和 WebInvoke 的限制 - 匿名访问网站的安全角色
WCF service: restrictions for WebGet and WebInvoke with AD - security roles for a website with anonymous access
我用 WebGet 和 WebInvoke 方法编写了一个 WCF 服务。它到目前为止有效(经过大量试验和错误:-)
但现在我无法让使用 AD 安全角色的限制发挥作用。
我需要限制对 WebInvoke
方法 SetBoxPosition
的访问,该方法用于将数据写入我的服务。
唯一有效的限制是下面 web.config
<location>
中对 "ZES_R" 和 "ZES_RW" 的限制。但顾名思义:ZES_R 应该读取和 ZES_RW 读取和写入 (post) ...
我尝试了来自广大互联网的各种代码...
IE。来自 https://ramanisandeep.wordpress.com/2014/11/24/wcf-security-how-do-i-restrict-user-access-to-methods-in-wcf/
[PrincipalPermission(SecurityAction.Demand, Role = "ZES_rw")]
public String SetBoxPosition(PostBoxData postBoxData)
{ .....
或制作自定义 ServiceAuthorizationManager。
public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
try
{
ServiceSecurityContext securityContext = operationContext.ServiceSecurityContext;
WindowsIdentity callingIdentity = securityContext.WindowsIdentity;
WindowsPrincipal principal = new WindowsPrincipal(callingIdentity);
return principal.IsInRole("rdm-WEB-Reas_rw");
}
catch (Exception)
{
return false;
}
}
}
调试函数 CheckAccessCore
时创建的 WindowsPrincipal principal
似乎是空的/匿名的,至少 Name = "" 和 Type = Anonymous,虽然我必须输入我的 Windows 运行 服务的凭据。
出于各种(部分是历史原因)原因,页面本身的配置允许匿名访问。
在 web.config
中,我通过不同的“位置”部分限制访问,如下所示。
我曾尝试关闭匿名访问,但随后出现错误:
System.ServiceModel.ServiceActivationException
因为我不想失去匿名访问权限,所以我没有进一步挖掘......
有人知道如何让它工作吗?
并且:如果我的代码中的其他内容是伪造的(除了我的拼写),请告诉我:-)
接口:
namespace ZES
{
[ServiceContract(Namespace = "ZESDataService")]
public interface IZESData
{
[OperationContract]
[WebGet]
string Hallo();
[OperationContract]
[WebInvoke(Method = "POST",RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle= WebMessageBodyStyle.WrappedRequest)]
String SetBoxPosition(PostBoxData postBoxData);
}
[DataContract]
public class PostBoxData
{
[DataMember] public int BoxID { get; set; }
[DataMember] public char Bundesland { get; set; }
[DataMember] public Decimal Latitude { get; set; }
[DataMember] public Decimal Longtitude { get; set; }
}
}
ZESData.svc:
<%@ ServiceHost Language="C#" Debug="true" Service="ZES.ZESData" CodeBehind="ZESData.svc.cs" %>
ZESData.svc.cs
namespace ZES
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public partial class ZESData : IZESData
{
public string Hallo()
{
//Simple func 4 testing
return "Hallo Welt";
}
public String SetBoxPosition(PostBoxData postBoxData)
{
//function used 4 writing Data to Database
return SetBoxPos(postBoxData.BoxID, postBoxData.Bundesland, postBoxData.Latitude, postBoxData.Longtitude);
}
}
}
web.config
<configuration>
<appSettings/>
<system.web>
<compilation debug="true" targetFramework="4.0">
</compilation>
<authentication mode="Windows"/>
<customErrors mode="Off"/>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
</system.webServer>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="httpsWebBinding">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" />
</security>
</binding>
<binding name="httpWebBinding">
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<diagnostics performanceCounters="Default" />
<behaviors>
<serviceBehaviors>
<behavior name="ZESDataServiceTypeBehaviors" >
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" />
<!--<serviceAuthorization principalPermissionMode="UseWindowsGroups" />-->
<!--<serviceAuthorization serviceAuthorizationManagerType=" ZES.MyServiceAuthorizationManager, ZES" />-->
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="ZESDataAspNetAjaxBehavior">
<webHttp />
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="ZESDataServiceTypeBehaviors"
name="ZES.ZESData">
<endpoint address=""
behaviorConfiguration="ZESDataAspNetAjaxBehavior"
binding="webHttpBinding"
bindingConfiguration="httpsWebBinding"
name="ZESData"
contract=" ZES.IZESData" />
<endpoint address=""
behaviorConfiguration="ZESDataAspNetAjaxBehavior"
binding="webHttpBinding"
bindingConfiguration="httpWebBinding"
name="ZESData"
contract="ZES.IZESData" />
<endpoint address="mex"
binding="mexHttpsBinding" name="mex" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
<location>
<system.web>
<authorization>
<allow roles="ZES_r"/>
<allow roles="ZES_rw"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<location path="Error">
<system.web>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
</location>
<location path="Default.aspx">
<system.web>
<authorization>
<allow roles="ZES_r"/>
<allow roles="ZES_rw"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<location path="Images">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
</configuration>
我又一次找到了答案......
在这里询问有助于找到解决方案,在其他人的帮助下并且没有 :-)
但也许它可以帮助别人......
如问题中所述,我没有尝试禁用匿名访问,因为我遇到了其他错误。
试图解决这个错误找到了答案。
我的绑定错误:
(留下旧的作为评论)
<bindings>
<webHttpBinding>
<binding name="httpsWebBinding">
<security mode="Transport">
<!-- <transport clientCredentialType="None" proxyCredentialType="None" /> -->
<transport clientCredentialType="Windows" proxyCredentialType="Windows" />
</security>
</binding>
<binding name="httpWebBinding">
<security mode="None">
<!-- <transport clientCredentialType="None" proxyCredentialType="None" /> -->
<transport clientCredentialType="Windows" proxyCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
现在
[PrincipalPermission(SecurityAction.Demand, Role = "rdm-WEB-Reas_rw")]
public String SetBoxPosition(PostBoxData postBoxData)
几乎按预期工作,只是我得到 "accepted" 而不是 "Not Allowed" 或类似的,当使用没有权限写入的用户时。
我从一个示例中复制了绑定以在您的网站上启用 https,这就是从网上复制和粘贴代码的结果,您不完全理解:-)
感谢阅读,如果您喜欢我的回答,请给我投票。我真的很想发表评论:-)
我用 WebGet 和 WebInvoke 方法编写了一个 WCF 服务。它到目前为止有效(经过大量试验和错误:-)
但现在我无法让使用 AD 安全角色的限制发挥作用。
我需要限制对 WebInvoke
方法 SetBoxPosition
的访问,该方法用于将数据写入我的服务。
唯一有效的限制是下面 web.config
<location>
中对 "ZES_R" 和 "ZES_RW" 的限制。但顾名思义:ZES_R 应该读取和 ZES_RW 读取和写入 (post) ...
我尝试了来自广大互联网的各种代码... IE。来自 https://ramanisandeep.wordpress.com/2014/11/24/wcf-security-how-do-i-restrict-user-access-to-methods-in-wcf/
[PrincipalPermission(SecurityAction.Demand, Role = "ZES_rw")]
public String SetBoxPosition(PostBoxData postBoxData)
{ .....
或制作自定义 ServiceAuthorizationManager。
public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
try
{
ServiceSecurityContext securityContext = operationContext.ServiceSecurityContext;
WindowsIdentity callingIdentity = securityContext.WindowsIdentity;
WindowsPrincipal principal = new WindowsPrincipal(callingIdentity);
return principal.IsInRole("rdm-WEB-Reas_rw");
}
catch (Exception)
{
return false;
}
}
}
调试函数 CheckAccessCore
时创建的 WindowsPrincipal principal
似乎是空的/匿名的,至少 Name = "" 和 Type = Anonymous,虽然我必须输入我的 Windows 运行 服务的凭据。
出于各种(部分是历史原因)原因,页面本身的配置允许匿名访问。
在 web.config
中,我通过不同的“位置”部分限制访问,如下所示。
我曾尝试关闭匿名访问,但随后出现错误:
System.ServiceModel.ServiceActivationException
因为我不想失去匿名访问权限,所以我没有进一步挖掘......
有人知道如何让它工作吗?
并且:如果我的代码中的其他内容是伪造的(除了我的拼写),请告诉我:-)
接口:
namespace ZES
{
[ServiceContract(Namespace = "ZESDataService")]
public interface IZESData
{
[OperationContract]
[WebGet]
string Hallo();
[OperationContract]
[WebInvoke(Method = "POST",RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle= WebMessageBodyStyle.WrappedRequest)]
String SetBoxPosition(PostBoxData postBoxData);
}
[DataContract]
public class PostBoxData
{
[DataMember] public int BoxID { get; set; }
[DataMember] public char Bundesland { get; set; }
[DataMember] public Decimal Latitude { get; set; }
[DataMember] public Decimal Longtitude { get; set; }
}
}
ZESData.svc:
<%@ ServiceHost Language="C#" Debug="true" Service="ZES.ZESData" CodeBehind="ZESData.svc.cs" %>
ZESData.svc.cs
namespace ZES
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public partial class ZESData : IZESData
{
public string Hallo()
{
//Simple func 4 testing
return "Hallo Welt";
}
public String SetBoxPosition(PostBoxData postBoxData)
{
//function used 4 writing Data to Database
return SetBoxPos(postBoxData.BoxID, postBoxData.Bundesland, postBoxData.Latitude, postBoxData.Longtitude);
}
}
}
web.config
<configuration>
<appSettings/>
<system.web>
<compilation debug="true" targetFramework="4.0">
</compilation>
<authentication mode="Windows"/>
<customErrors mode="Off"/>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
</system.webServer>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="httpsWebBinding">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" />
</security>
</binding>
<binding name="httpWebBinding">
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<diagnostics performanceCounters="Default" />
<behaviors>
<serviceBehaviors>
<behavior name="ZESDataServiceTypeBehaviors" >
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" />
<!--<serviceAuthorization principalPermissionMode="UseWindowsGroups" />-->
<!--<serviceAuthorization serviceAuthorizationManagerType=" ZES.MyServiceAuthorizationManager, ZES" />-->
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="ZESDataAspNetAjaxBehavior">
<webHttp />
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="ZESDataServiceTypeBehaviors"
name="ZES.ZESData">
<endpoint address=""
behaviorConfiguration="ZESDataAspNetAjaxBehavior"
binding="webHttpBinding"
bindingConfiguration="httpsWebBinding"
name="ZESData"
contract=" ZES.IZESData" />
<endpoint address=""
behaviorConfiguration="ZESDataAspNetAjaxBehavior"
binding="webHttpBinding"
bindingConfiguration="httpWebBinding"
name="ZESData"
contract="ZES.IZESData" />
<endpoint address="mex"
binding="mexHttpsBinding" name="mex" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
<location>
<system.web>
<authorization>
<allow roles="ZES_r"/>
<allow roles="ZES_rw"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<location path="Error">
<system.web>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
</location>
<location path="Default.aspx">
<system.web>
<authorization>
<allow roles="ZES_r"/>
<allow roles="ZES_rw"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<location path="Images">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
</configuration>
我又一次找到了答案...... 在这里询问有助于找到解决方案,在其他人的帮助下并且没有 :-) 但也许它可以帮助别人......
如问题中所述,我没有尝试禁用匿名访问,因为我遇到了其他错误。
试图解决这个错误找到了答案。
我的绑定错误: (留下旧的作为评论)
<bindings>
<webHttpBinding>
<binding name="httpsWebBinding">
<security mode="Transport">
<!-- <transport clientCredentialType="None" proxyCredentialType="None" /> -->
<transport clientCredentialType="Windows" proxyCredentialType="Windows" />
</security>
</binding>
<binding name="httpWebBinding">
<security mode="None">
<!-- <transport clientCredentialType="None" proxyCredentialType="None" /> -->
<transport clientCredentialType="Windows" proxyCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
现在
[PrincipalPermission(SecurityAction.Demand, Role = "rdm-WEB-Reas_rw")]
public String SetBoxPosition(PostBoxData postBoxData)
几乎按预期工作,只是我得到 "accepted" 而不是 "Not Allowed" 或类似的,当使用没有权限写入的用户时。
我从一个示例中复制了绑定以在您的网站上启用 https,这就是从网上复制和粘贴代码的结果,您不完全理解:-)
感谢阅读,如果您喜欢我的回答,请给我投票。我真的很想发表评论:-)