当前位置: 动力学知识库 > 问答 > 编程问答 >

wcf security - AuthorizationManager based on service invocation parameters

问题描述:

I'm currently developing my own AuthorizationManager, it looks something like that:

 public class MyAuthorizationManager : ServiceAuthorizationManager

{

static bool initialize = false;

public override bool CheckAccess(OperationContext operationContext)

{

ServiceSecurityContext context = ServiceSecurityContext.Current;

string[] roles = Roles.GetRolesForUser(operationContext.ServiceSecurityContext.PrimaryIdentity.Name);

return roles.Count() > 0;

}

public override bool CheckAccess(OperationContext operationContext, ref System.ServiceModel.Channels.Message message)

{

MessageBuffer buffer = operationContext.RequestContext.RequestMessage.CreateBufferedCopy(int.MaxValue);

message = buffer.CreateMessage();

Console.WriteLine(message);

return base.CheckAccess(operationContext, ref message);

}

}

I would like to perform authorization check based on a service contract parameter, in example, if contract looks like:

[ServiceContract]

public interface IServerContract

{

[OperationContract]

[ServiceKnownType(typeof(ChildTypeOne))]

[ServiceKnownType(typeof(ChildTypeTwo))]

string SecuredMessage(ParentType incoming);

}

My goal is authorizing depending on type, in example, authorizing if incoming date is ChildTypeOne and deniying in case it was ChildTypeTwo.

I've checked "Message" and it looks like:

  • It must be decrypted
  • Seems to be highly dependent on binding

Is there any easy way to simply get parameter type?

网友答案:

Ok, i've figured out how to perform that. Anyway, if you know any better way to do so, let me know:

Here is the AuthorizationManager i'm using:

 public class MyAuthorizationManager : ServiceAuthorizationManager
{
    static bool initialize = false;

    public override bool CheckAccess(OperationContext operationContext, ref System.ServiceModel.Channels.Message message)
    {
            bool returnedValue = base.CheckAccess(operationContext, ref message);
            // messags in WCF are always read-once
            // we create one copy to work with, and one copy to return back to the plumbing
            MessageBuffer buffer = operationContext.RequestContext.RequestMessage.CreateBufferedCopy(int.MaxValue);
            message = buffer.CreateMessage();

            // get the username vale using XPath
            XPathNavigator nav = buffer.CreateNavigator();
            StandardNamespaceManager nsm = new StandardNamespaceManager(nav.NameTable);
            nav = nav.SelectSingleNode("//@i:type",nsm);
            returnedValue &= (nav.ToString() == "a:"+typeof(ChildTypeOne).Name);
            return returnedValue;
    }


    public class StandardNamespaceManager : XmlNamespaceManager
    {
        public StandardNamespaceManager(XmlNameTable nameTable)
            : base(nameTable)
        {
            this.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");
            this.AddNamespace("s11", "http://schemas.xmlsoap.org/soap/envelope/");
            this.AddNamespace("s12", "http://www.w3.org/2003/05/soap-envelope");
            this.AddNamespace("wsaAugust2004", "http://schemas.xmlsoap.org/ws/2004/08/addressing");
            this.AddNamespace("wsa10", "http://www.w3.org/2005/08/addressing");
            this.AddNamespace("i", "http://www.w3.org/2001/XMLSchema-instance");
        }
    }
}

Previous AuthorizationManager will work rejecting "ChildTypeTwo". You can use a RoleProvider in order to get role based on type.

分享给朋友:
您可能感兴趣的文章:
随机阅读: