我使用以下方法关闭WCF 4通道.这是正确的方法吗?
using (IService channel
= CustomChannelFactory<IService>.CreateConfigurationChannel())
{
channel.Open();
//do stuff
}// channels disposes off??
Run Code Online (Sandbox Code Playgroud) 要求:
WCF 4.0 IIS主机使用自定义源RESTful进行基本身份验证
通过使用UserNamePasswordValidator,通过ServiceAuthorizationManager和IDispatchMessageInspector等,有很多示例和方法来实现基本身份验证.
我面临的问题是,验证实际上将从身份验证后端获取更多信息,而不是是/否答案.我想以某种方式将这些信息传递给调用的服务方法(即它将是完全成熟的User对象,具有许多属性来控制服务行为).我想避免第二次调用用户存储来检索基于用户名的数据,我可以从安全上下文访问该用户名.
到目前为止,我发现最接近的是这个解决方案,它使用WCF REST入门工具包的RequestInterceptor,我可以在其中注入ServiceSecurityContext的子类来继承我的数据,并在服务方法中强制转换ServiceSecurityContext.Current.
上面的问题是,它是为WCF 3.5编写的,我想避免使用入门套件.
问题是:任何想法最适合链接的地方,所以我可以将数据从验证逻辑传递给服务.或者用另一种方式,我可以用自定义的安全上下文替换安全上下文来进行加载?或任何其他承运人机制?
我追求的是那种行为:
客户端(可能是浏览器)尝试使用该服务:GET https:// myservcer/service/data 服务器响应"需要基本身份验证"客户端提供基本身份验证标头并再次发送请求服务器,基于用户/传入标题,从数据库中提取出一个User对象.如果找不到用户,请再次请求身份验证如果找到用户,则以某种方式传递用户对象的服务方法所有这一切都应该发生而不进行第二次往返数据库
到目前为止,我理解的是,UserNamePasswordValidator不会这样做 - 如果我在那里检索它,就无法传递User对象.
我可以创建一个自定义IAuthorizationPolicy或SecurityToken(哪一个),并将User对象放入.但是......这应该发生的地方.我可以使用UserNameSecurityTokenAuthenticator吗?是否会返回正确的HTTP错误代码以请求凭据?我如何/在哪里修改web.config以使用我的自定义内容?到目前为止,我看到如何设置仅使用自定义UserNamePasswordAuthenticator.
使用WCF 3.5和Christian Weyer的FlatWsdl EndpointBehavior,我能够在没有任何<import>指令的情况下为我的WCF服务获取单个平面WSDL文件.
现在使用WCF 4,由于某种原因,这不再起作用了.
我已经尝试了许多博客条目中描述的所有内容,包括使用WcfExtras行为扩展.
他们都指的是Chr.Weyers解决方案或推荐WcfExtras.我还确保为绑定,ServiceContract和ServiceBehavior指定了相同的命名空间.
在自定义服务主机中,当要注入FlatWsdlExtension时,Description.Endpoints集合始终为空.我尝试使用或不使用地址配置我的服务端点,到目前为止没有运气.
为了获得WCF 4服务的单一平面WSDL,我需要做什么?
谢谢你的回答.
我只使用WCF进行数据服务(即应用程序内部,非常精简,没有会话状态等),以保持我们的Web应用程序的可扩展性.
我们需要为我们当前正在传递的每个服务调用提供一些公共属性.对于每个调用具有单个请求对象并不理想,因为超出这些常见属性,其余的是非常多样的并且在开发期间经常变化.
目前我正在考虑使用自定义标头和clientmessageinspector来设置值.对于这种情况,这是最简单的推荐方法还是有更好的方法?
更多详情..
下面的红点是我不确定正确的方法(或如何去做).

发送了什么
发送的数据是一组简单的id(3或4用于userid,clientid等) - 所有这些ID都会对安全性和性能产生影响(在某些情况下,它决定了要访问的数据库).
我们还将扩展它以获得更复杂的权限 - 不需要Windows工作者.
调用者将是一个Web应用程序,它们来自会话对象,或者是一个手动填充这些应用程序的Windows服务工作者.
当前的思考
理想情况下,调用者工作流的getinstance会自动使用会话对象填充这些属性,还是使用windows服务调用(不同的构造函数?)手动填充.
然后,我们将确保这些参数始终可用,无需任何考虑或在整个代码中没有常量引用,以便在调用它的每个函数上构造契约.我们目前有很多服务调用(由于应用程序的规模/复杂性,而不是由于糟糕的工程:)),因此这扩展到复杂的权限,以自我文档的方式强制执行规则变得有点困难.
从概念上讲,会话是你在应用程序中处理这个问题的地方,但服务实际上只是一个数据访问层(具有视图映射,页面调度和来自存储库调用的最后调用安全性)所以我们不需要那种重复或复杂性,只包括要包含在查询中的关键标识和权限字段.
问题
这感觉非常像我们应该对调用的标题做的事情,因为我们总是需要这些字段,但我不确定set和get应该位于端点和客户端接口的生命周期中的哪个位置.我也很高兴错了.
我已经使用wsHTTPBinding配置了WCF服务,但即使这样我也得到了错误
Run Code Online (Sandbox Code Playgroud)Contract requires Session, but Binding 'BasicHttpBinding' doesn't support it or isn't configured properly to support it.
这是服务合同定义
<ServiceContract(SessionMode:=SessionMode.Required)>
Public Interface IPrivateService
Run Code Online (Sandbox Code Playgroud)
这是服务实现定义
<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession)>
Public Class PrivateService
Implements IPrivateService
Run Code Online (Sandbox Code Playgroud)
这是配置设置
<services>
<service behaviorConfiguration="behaviorAction" name="Viking.Service.PrivateService">
<endpoint address="RequiredService" binding="wsHttpBinding" bindingConfiguration="bindingAction" contract="Viking.Service.IPrivateService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="bindingAction" transactionFlow="false" sendTimeout="00:30:00" receiveTimeout="00:30:00">
<reliableSession enabled="true"/>
</binding>
</wsHttpBinding>
</bindings>
Run Code Online (Sandbox Code Playgroud)
真正感谢任何关于这个问题的建议.
我已将" WCF服务应用程序 "项目类型添加到我的VS解决方案(4.0)中.现在,出现的默认命名空间是" Service ",如果我运行应用程序(将WCF服务应用程序指向启动项目),它可以正常工作.
现在我已将命名空间更改为XXX.YYY.Service.PartnerPortal,如下所示
namespace XXX.YYY.Service.PartnerPortal
{
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
}
Run Code Online (Sandbox Code Playgroud)
以及IService1接口也是如此
namespace XXX.YYY.Service.PartnerPortal
{
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
}
Run Code Online (Sandbox Code Playgroud)
我还更改了项目属性中的默认命名空间
app.config文件如下
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0">
</compilation>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/></system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above …Run Code Online (Sandbox Code Playgroud) 如果同时IParameterInspector和IErrorHandler连接到一个服务,我可以肯定IErrorHandler.HandleError()将在同一个线程在那里叫上IParameterInspector.BeforeCall()叫?
我需要这个,因为在抛出错误的情况下IParameterInspector.AfterCall()永远不会被调用,并且没有办法(据我所知)我可以获得创建的关联状态对象BeforeCall().所以我希望通过ThreadStatic在我的接口实现中有一个字段来克服这个问题:(