问题
After following Dominick Baier's Pluralsight courses and blogs around WIF 4.5, I'm still stuck with problem that I'm unable to resolve. I am using WCF Data Services with claims based authorization using WIF 4.5.
I have my ClaimsAuthenticationManager
and ClaimsAuthorizationManager
set up in the web.config:
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
...
<system.identityModel>
<identityConfiguration>
<claimsAuthenticationManager type="Magnum.WCFDataService.ClaimsTransformer, Magnum.WCFDataService" />
<claimsAuthorizationManager type="Magnum.WCFDataService.AuthorizationManager, Magnum.WCFDataService" />
</identityConfiguration>
</system.identityModel>
Here are the contents of my AuthorizationManager:
public class AuthorizationManager : ClaimsAuthorizationManager
{
public override bool CheckAccess(AuthorizationContext context)
{
var action = context.Action.First();
if (action.Type.Equals(ClaimPermission.ActionType))
{
var resource = context.Resource.First();
return context.Principal.HasClaim(resource.Value, action.Value);
}
return base.CheckAccess(context);
}
}
The first problem I encountered was that WCF was automatically calling my AuthorizationManager
for every request and passing in the http verb for the action and the URL for the resource, this was useless as I wanted to manually determine when the claims were called using the query and change interceptors provided by data services. That's where I found Dominick's explanation of the problem suggesting to write a custom class and attribute to replace ClaimsPrincipalPermission
. That went fine, the attribute is on the change and query interceptor and calls my AuthorizationManager
a second time with my custom URI.
Now, the problem is, for GET requests, it works without a hitch. The AuthorizationManager
gets called once by WCF which I ignore and a second time using my attribute which I handle. However, for POST requests (anytime I have a change interceptor), when the AuthorizationManager
is called a second time with my URI, the principal on the context is a GenericPrincipal
rather than a ClaimsPrincipal
and doesn't contain my claims to check.
How can I ensure that I always get my ClaimsPrincipal
which is generated from my ClaimsTransformer (ClaimsAuthenticationManager) everytime the AuthorizationManager
is called?
Further information After some intensive Googling, I've narrowed the problem down. I'm only seeing the GenericPrincipal if I use the SaveChangesOptions.Batch when calling the SaveChanges method from my client. If I do not send a batch update, I get a ClaimsPrincipal back as normal. So, new question; How do I retain the ClaimsPrincipal for batch updates?
I found some information on an MSDN thread (http://social.msdn.microsoft.com/Forums/en-US/35eb817d-363c-4a94-b9eb-351cd0d8567f/batch-update-and-impersonation-current-user) stating that I need to use the following in my web.config:
<serviceAuthorization principalPermissionMode="Always" impersonateCallerForAllOperations="true" impersonateOnSerializingReply="true" />
but now I am getting the following error:
The service operation 'ProcessRequestForMessage' that belongs to the contract with the 'IRequestHandler' name and the 'http://tempuri.org/' namespace does not allow impersonation.
回答1:
Problem solved, this is the correct configuration to ensure batch requests work correctly with WIF 4.5 using a WCF Data Service
<behavior>
<serviceCredentials useIdentityConfiguration="true" />
<serviceAuthorization principalPermissionMode="Always" impersonateOnSerializingReply="true" />
</behavior>
来源:https://stackoverflow.com/questions/17384002/wcf-data-service-with-wif-4-5-principal-not-set-for-post-requests