AuthorizationManager на основе параметров вызова службы
В настоящее время я разрабатываю свой собственный AuthorizationManager, он выглядит примерно так:
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);
}
}
Я хотел бы выполнить проверку авторизации на основе параметра контракта на обслуживание, например, если контракт выглядит следующим образом:
[ServiceContract]
public interface IServerContract
{
[OperationContract]
[ServiceKnownType(typeof(ChildTypeOne))]
[ServiceKnownType(typeof(ChildTypeTwo))]
string SecuredMessage(ParentType incoming);
}
Моя цель - авторизация в зависимости от типа, например авторизация, если входящей датой является ChildTypeOne, и отказ в случае, если это было ChildTypeTwo.
Я проверил "Сообщение", и это выглядит так:
- Должно быть расшифровано
- Кажется, сильно зависит от привязки
Есть ли простой способ получить тип параметра?
1 ответ
Хорошо, я понял, как это сделать. В любом случае, если вы знаете лучший способ сделать это, дайте мне знать:
Вот AuthorizationManager, который я использую:
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");
}
}
}
Предыдущий AuthorizationManager будет работать, отклоняя "ChildTypeTwo". Вы можете использовать RoleProvider, чтобы получить роль, основанную на типе.