我正在尝试基于他们从服务调用的方法为WCF服务的内部/外部用户实现基于令牌的身份验证。我试图拦截传入的soap信封,并使用global.asax文件中的令牌成功提取信封中的操作调用,并对其进行身份验证,但是当调用完成时,它不会传递到服务中请求的操作。有没有办法捕获传入的请求并在它到达请求的呼叫之前进行一些身份验证?这是我目前的代码。
Global.asax
protected void Application_AuthorizeRequest(object sender, EventArgs e)
{
bool authorized = false;
bool soapRequestReceived = false;
try
{
XmlDocument soapDocument = new XmlDocument();
Stream receiveStream = HttpContext.Current.Request.InputStream;
receiveStream.Position = 0;
if (receiveStream.Length > 0)
{
soapRequestReceived = true;
using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
{
// Load into XML document
soapDocument.Load(readStream);
logger.Info("output of XML document received is " + readStream);
}
authorized = XMLSoapParser.ParseMethodNameAndToken(soapDocument);
if (!authorized)
{
throw new Exception("User not authorized!");
}
}
return;
}
catch (Exception EX_NAME)
{
if (soapRequestReceived && !authorized)
{
throw new Exception("User not authorized!");
}
// eat it;
}
}
这是xml解析器的代码
public static class XMLSoapParser
{
public static bool ParseMethodNameAndToken(XmlDocument doc)
{
try
{
XmlElement rootElement = doc.DocumentElement;
XmlNodeList nodes = rootElement.ChildNodes;
string methodName = "";
string token = "";
for (int i = 0; i < nodes.Count; i++)
{
if (nodes.Item(i).Name.ToLower().Contains("body"))
{
XmlNodeList bodyList = nodes.Item(i).ChildNodes;
for (int j = 0; j < bodyList.Count; j++)
{
if (bodyList.Item(j).Name.ToLower().Contains("tem:"))
{
methodName = bodyList.Item(j).Name.Substring(4);
Logger.Info("Method Name received! : " + methodName );
XmlNodeList methodNodeList = bodyList.Item(j).ChildNodes;
for (int k = 0; k < methodNodeList.Count; k++)
{
if (methodNodeList.Item(j).Name.ToLower().Contains("token"))
{
token = methodNodeList.Item(j).InnerText;
Logger.Info("Token received ! : " + token);
}
}
}
}
}
}
var client = new AuthAdminClient("BasicHttpBinding_IAuthAdmin");
var authorized = client.IsAuthorized(token, "Partners", methodName);
return authorized;
}
catch (Exception exception)
{
Logger.Warn(
string.Format(
"Execption encountered at XML Soap Parser with parameter {0} /r/n Exeception caught : {1} /r/n {2}",
doc.ToString(), exception.Message, exception.StackTrace));
return false;
}
}
}
答案 0 :(得分:2)
即使你的解决方案可行,我也不建议自己解析SOAP信封。
通常,您会从ClaimsAuthorizationManager
派生并覆盖CheckAccess
。第一个参数是AuthorizationContext
类型,它具有Action
属性,您可以从中获取调用的方法。
从ApplyConfiguration
返回false会阻止将调用分派给该方法。
编辑:要将其连接起来,您需要创建一个ServiceHost
派生类并覆盖var credentials = this.Description.Behaviors.Find<ServiceCredentials>();
var identityConfiguration = new IdentityConfiguration();
// configure IdentityConfiguration properties here
credentials.IdentityConfiguration = identityConfiguration;
credentials.UseIdentityConfiguration = true;
identityConfiguration.ClaimsAuthorizationManager = new MyClaimsAuthorizationManager();
方法。在此方法中,您创建配置身份模型,如下所示:
grunt.initConfig({
exec:{
mocha: {
cmd:function(version){
if(semver.gt(version, '0.10')){
return 'mocha test/index.js';
} else return 'mocha --harmony test/harmony/index.js';
}
}
}
});
这不是完整的代码,但应该给你足够的方向来找到一些完整的例子。有关如何激活servicehost的信息,请参阅here。