我正在尝试使用REST和SOAP端点编写WCF服务。我最初使用" TransportCredentialOnly"用于SOAP端点。当我开始添加REST端点时...我正在使用第三方OAUTH 1.0类来为REST服务提供安全性。
使用" TransportCredentialOnly"身份验证,我必须启用" Windows身份验证"在IIS网站应用程序上。
我遇到的问题是REST调用回来了"身份验证失败"因为IIS希望在命中REST端点之前使用Windows凭据进行初始身份验证。
我启用了#34;匿名身份验证"在IIS应用程序上,但在继续之前仍会提示您输入Windows凭据。
无论如何都要保持" Windows身份验证" SOAP调用的方案,并在REST端点上进行匿名身份验证(将继续使用OAuth 1.0)?我并不是真的想将它分成两个项目/服务,因为一些函数/方法/类在SOAP和REST调用之间是通用的。
到目前为止,这是我的网络配置尝试:
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
<authentication mode="Windows"/>
<authorization>
<allow roles="DOMAIN\Security_Group"/>
<deny users="*"/>
</authorization>
<customErrors mode="Off"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP" />
</webHttpBinding>
</bindings>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="Anonymous">
<security mode="None"/>
</standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
<services>
<service name="service name">
<endpoint address="SOAP"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpEndpointBinding"
contract="contract name">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="REST"
kind="webHttpEndpoint"
binding ="webHttpBinding"
bindingConfiguration="webHttpBindingWithJsonP"
endpointConfiguration="Anonymous"
behaviorConfiguration="restBehavior"
contract ="contract name">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="service url"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="restBehavior">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<useRequestHeadersForMetadataAddress/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="http" />
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="false" />
</system.serviceModel>
<system.webServer>
<httpProtocol>
<customHeaders>
<!--<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Methods" value="POST,GET"/>
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept"/>-->
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
10-20-2015更新:我在web.config文件中应用了一个新的配置来使用serviceAuthorization
<service name="service name" behaviorConfiguration="Oauth">
<endpoint address="service address"
binding ="webHttpBinding"
behaviorConfiguration="restBehavior"
contract ="service contract">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="base address"/>
</baseAddresses>
</host>
</service>
<behavior name="Oauth">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceAuthorization serviceAuthorizationManagerType="Assembly.OAuthAuthorizationManager,Assembly" />
</behavior>
这是OAuthorizationManager类:
public class OAuthAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
bool Authenticated = false;
string normalizedUrl;
string normalizedRequestParameters;
base.CheckAccessCore(operationContext);
// to get the httpmethod
HttpRequestMessageProperty requestProperty = (HttpRequestMessageProperty)(operationContext.RequestContext.RequestMessage).Properties[HttpRequestMessageProperty.Name];
string httpmethod = requestProperty.Method;
// HttpContext.Current is null, so forget about it
// HttpContext context = HttpContext.Current;
NameValueCollection pa = HttpUtility.ParseQueryString(operationContext.IncomingMessageProperties.Via.Query);
if (pa != null && pa["oauth_consumer_key"] != null)
{
// to get uri without oauth parameters
string uri = operationContext.IncomingMessageProperties
.Via.OriginalString.Replace
(operationContext.IncomingMessageProperties
.Via.Query, "");
string consumersecret = "secret";
OAuthBase oauth = new OAuthBase();
string hash = oauth.GenerateSignature(
new Uri(uri),
pa["oauth_consumer_key"],
consumersecret,
null, // totken
null, //token secret
httpmethod,
pa["oauth_timestamp"],
pa["oauth_nonce"],
out normalizedUrl,
out normalizedRequestParameters
);
Authenticated = pa["oauth_signature"] == hash;
}
return Authenticated;
}
}
答案 0 :(得分:0)
在IIS中托管基于REST的WCF服务有一个可行的解决方案可以使用自己的自定义基本身份验证。您可以轻松地发回一个响应标头来挑战基本身份验证凭据,并且只需将IIS连接到ServiceAuthorizationManager
。在这种情况下,IIS将只负责托管和它。
创建一个继承自public class RestAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
//Extract the Authorization header, and parse out the credentials converting the Base64 string:
var authHeader = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];
if ((authHeader != null) && (authHeader != string.Empty))
{
var svcCredentials = System.Text.ASCIIEncoding.ASCII
.GetString(Convert.FromBase64String(authHeader.Substring(6)))
.Split(':');
var user = new { Name = svcCredentials[0], Password = svcCredentials[1] };
if ((user.Name == "user1" && user.Password == "test"))
{
//User is authrized and originating call will proceed
return true;
}
else
{
//not authorized
return false;
}
}
else
{
//No authorization header was provided, so challenge the client to provide before proceeding:
WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate: Basic realm=\"MyWCFService\"");
//Throw an exception with the associated HTTP status code equivalent to HTTP status 401
throw new WebFaultException(HttpStatusCode.Unauthorized);
}
}
}
的自定义授权管理器类,并将其配置为您的服务。
<serviceBehaviors>
<behavior name="SecureRESTSvcTestBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<serviceAuthorization serviceAuthorizationManagerType="WcfRestAuthentication.Services.Api.RestAuthorizationManager, WcfRestAuthentication"/>
</behavior>
</serviceBehaviors>
将以上自定义授权管理器添加到配置:
Error: spawn C: \Users\ myusername\ Documents\ GitHub\ angular - testing - tutorial\ node_m
odules\ gulp - protractor\ node_modules\.bin\ protractor.cmd ENOENT
at exports._errnoException(util.js: 746: 11)
at Process.ChildProcess._handle.onexit(child_process.js: 1053: 32)
at child_process.js: 1144: 20
at process._tickCallback(node.js: 355: 11)
将以上行为仅应用于REST端点。现在IIS再也无法控制任何授权。确保使用SSL证书确保以明文形式发送信用证。