In order to create a dynamic or customized code for authorization, WCF provides a serviceauthorization, here is the way to implement it.
For example if i have a service which updates Employee information and need validation that only employees that have group ID as “12345” could be updated, in order to do this follow the below steps
- Add a new class (Validation) to your project and have this class inherit from the ServiceAuthorizationManager class in the System.ServiceModel namespace. (The ServiceAuthorizationManager class provides an Overridable method called CheckAccess(). This passes information about the current request in the OperationContext, and also passes in the messgae data itself by reference.
- Override the CheckAccess() method and the class should look like below
public class Validation : ServiceAuthorizationManager
{
public override bool CheckAccess(OperationContext operationContext, ref System.ServiceModel.Channels.Message message)
{}
- In the body of the function, remove any existing code. Since this validation is applied on all OperationContracts or Methods, you can add filters for specific actions, in my example i want this validation to apply only on OperationContract UpdateEmployee then following is the way to apply the filter
string action = operationContext.RequestContext.RequestMessage.Headers.Action;
if (action.EndsWith(“UpdateEmployee")){}
- So once we have the filter then that is where we need to create a buffered copy of the message by calling the CreateBufferedCopy() of the message argument
var copy = message.CreateBufferedCopy(100000);
- Using the copy variable, we can clone the message by calling the CreateMessage(), and then get access to the body contents by calling GetReaderAtBodyContents(). Store this into an XmlReader object, and also put this into using block to ensure cleanup. (Trick here is that we are only allowed to read the message once. So what we are doing is creating an in-memory buffer from the message, then using that to inspect the data.)
using (XmlReader reader = copy.CreateMessage().GetReaderAtBodyContents())
{
while (reader.Read())
{}}
- From here, we’re using regular .NET XML code. Inside the loop check to see if the current node Name contains GroupID. (GroupID is the name of the element that holds the GroupID of the employee, its a part of DataMember). If it does, then read the contents of the element as a string, and check if the string contains the text “12345”. If it does, then access will be allowed, otherwise denied. Here is the complete code of the Validation class looks like.
public override bool CheckAccess(OperationContext operationContext, ref System.ServiceModel.Channels.Message message)
{
string action = operationContext.RequestContext.RequestMessage.Headers.Action;
bool allowedAccess = false;if (action.EndsWith("UpdateEmployee"))
{
var copy = message.CreateBufferedCopy(100000);
using (XmlReader reader = copy.CreateMessage().GetReaderAtBodyContents())
{
while (reader.Read())
{
if (reader.Name.Contains("GroupID"))
{
string role = reader.ReadElementContentAsString();
allowedAccess = role.Contains("12345");
}
}
}
message = copy.CreateMessage(); //Generate a fresh copy of the message so that it can be processed by WCF.
}
else
{
allowedAccess = true;
}
return allowedAccess;
}
}
- The final step is to plug this authorization class into your service using configuration as follows
<serviceBehaviors>
<behavior name="Service1Behavior">
<serviceAuthorization serviceAuthorizationManagerType="Validation, Service1"/>
</behavior>
</serviceBehaviors>
Hello Kanithi,
I have done nested grid on base of your article(http://www.codeproject.com/KB/webforms/EditNestedDataGrid.aspx) in codeproject, The article was nice and hats off to you.
I would like to request your help in deep level of nested grid.I have done a three level gridview(I added one more grid further to your article., so i have GridView1,GridView2 and GridView3) as per your article and is working fine.
Addition Deletion and Modification can be done easily.But, The gridview3 is not staying in the same state after each action.The grid is getting collapsed.
The following code under GridView2_RowDataBound is not functioning…where as the same code is working fine with gridview1 and gridview2.
ClientScript.RegisterStartupScript(GetType(), “Expand”, “expandcollapse(‘div” + ((DataRowView)e.Row.DataItem)["ProjectSubPhaseId"].ToString() + “PSI’,'two’);”);
Please help me to fix this bug.
Looking forward to hear from you
Thanks and regards,
Vinod chattergee.S
Comment by Vinod — June 16, 2010 @ 7:34 am
Hi Vinod, So you are going deeper into the levels of GridView. From an UI stand point 3 levels of grids may not look good, unless there is no other way.
You can always use different controls like panels in the 3rd child level.
I haven’t got a chance to play with the 3rd child grid yet, once i do it i surely respond.
Comment by kanithis — March 2, 2011 @ 3:00 pm