Answered by:
Metadata retrieval with custom authorization policy

Question
-
I am prototyping a WCF service with a custom authorization policy. The service ran fine until I set principalPermissionMode = "Custom" and implemented the evaluate method of my IAuthorizationPolicy. Now the client throws an exception when it tries to get the metadata.
I have seen various posts that talk about trapping these calls and I can successfully trap them by looking for
operationContext.IncomingMessageHeaders.Action == "http://schemas.xmlsoap.org/ws/2004/09/transfer/Get/"
But what do I do once I trap them? Regardless of whether I return true or false from the evaluate method I still get the exception.
Do I need to do something else before my IAuthorizationPolicy so that evaluate never gets called?
Just to be clear - I do not want to authorize these calls - I am ok with making them publicly available.- Edited by MarkWB Monday, August 17, 2009 9:20 PM
Monday, August 17, 2009 9:05 PM
Answers
-
Hi,
Exactly... you need to implement your custom AuthorizationManager.
The Authorization policies are supposed to add claims based on specific authorization rules and the authorization manager takes the decision to authorize or not clients based on these claims....
Regards,
Rodrigo.- Marked as answer by MarkWB Wednesday, August 19, 2009 3:23 AM
Tuesday, August 18, 2009 8:31 PM
All replies
-
Hi Mark.
could you post more detail does about your custom authorization policy setting. and the exception?
Then we can talk about it together.
Frank Xu Lei--谦卑若愚,好学若饥
专注于.NET平台下分布式应用系统开发和企业应用系统集成
Focus on Distributed Applications Development and EAI based on .NET
欢迎访问老徐的中文技术博客:Welcome to My Chinese Technical Blog
欢迎访问微软WCF中文技术论坛:Welcome to Microsoft Chinese WCF Forum
欢迎访问微软WCF英文技术论坛:Welcome to Microsoft English WCF ForumTuesday, August 18, 2009 9:19 AM -
Frank,
Sure thing - although there is not much to it:
Here is my service host config:<serviceAuthorization principalPermissionMode="Custom"> <authorizationPolicies> <add policyType="MyAuthorizationPolicy,MyAuthorizationPolicy"/> </authorizationPolicies> </serviceAuthorization>
And here is the Evaluate method in MyAuthorizationPolicy class:public bool Evaluate(EvaluationContext evaluationContext, ref object state) { if (evaluationContext.Properties.ContainsKey("Identities")) { //Code that does stuff and adds a claimset... return true; } else { return false; } }
As I said, the evaluate method runs fine as long as there are not calls for metadata. When there are, the else condition is run which results in returning false. However, I have also forced it to return true in the else to see if that had any effect and it does not. I still get the exception on the client.
And here is the text from the error dialog on the Visual Studio test client:
Error: Cannot obtain Metadata from http://localhost:8080/evalservice/mexIf this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.
WS-Metadata Exchange Error
URI: http://localhost:8080/evalservice/mexMetadata contains a reference that cannot be resolved: 'http://localhost:8080/evalservice/mex'.
<?xml version="1.0" encoding="utf-16"?><Fault xmlns="http://www.w3.org/2003/05/soap-envelope"><Code><Value>Receiver</Value><Subcode><Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</Value></Subcode></Code><Reason><Text xml:lang="en-US">The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.</Text></Reason></Fault>
HTTP GET Error
URI: http://localhost:8080/evalservice/mexThere was an error downloading 'http://localhost:8080/evalservice/mex'.
The request failed with HTTP status 400: Bad Request.
Tuesday, August 18, 2009 4:02 PM -
Here is the client error with details turned on:
No custom principal is specified in the authorization context.
Do I need to implement an AuthorizationManager (which I have noticed is called before the AuthorizationPolicy) ?Error: Cannot obtain Metadata from http://localhost:8080/evalservice/mex If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455. WS-Metadata Exchange Error URI: http://localhost:8080/evalservice/mex Metadata contains a reference that cannot be resolved: 'http://localhost:8080/evalservice/mex'. <?xml version="1.0" encoding="utf-16"?><Fault xmlns="http://www.w3.org/2003/05/soap-envelope"><Code><Value>Receiver</Value><Subcode><Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</Value></Subcode></Code><Reason><Text xml:lang="en-US">No custom principal is specified in the authorization context.</Text></Reason><Detail xmlns:s="http://www.w3.org/2003/05/soap-envelope"><ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><HelpLink i:nil="true"></HelpLink><InnerException i:nil="true"></InnerException><Message>No custom principal is specified in the authorization context.</Message><StackTrace> at System.ServiceModel.Dispatcher.SecurityImpersonationBehavior.GetCustomPrincipal(ServiceSecurityContext securityContext) at System.ServiceModel.Dispatcher.SecurityImpersonationBehavior.SetCurrentThreadPrincipal(ServiceSecurityContext securityContext, Boolean& isThreadPrincipalSet) at System.ServiceModel.Dispatcher.SecurityImpersonationBehavior.StartImpersonation(MessageRpc& rpc, IDisposable& impersonationContext, IPrincipal& originalPrincipal, Boolean& isThreadPrincipalSet) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace><Type>System.InvalidOperationException</Type></ExceptionDetail></Detail></Fault> HTTP GET Error URI: http://localhost:8080/evalservice/mex There was an error downloading 'http://localhost:8080/evalservice/mex'. The request failed with HTTP status 400: Bad Request.
- Proposed as answer by Rybak Piotr Friday, February 1, 2013 8:05 AM
Tuesday, August 18, 2009 4:25 PM -
Hi,
Exactly... you need to implement your custom AuthorizationManager.
The Authorization policies are supposed to add claims based on specific authorization rules and the authorization manager takes the decision to authorize or not clients based on these claims....
Regards,
Rodrigo.- Marked as answer by MarkWB Wednesday, August 19, 2009 3:23 AM
Tuesday, August 18, 2009 8:31 PM -
That workd. Thanks Rodrigo.Wednesday, August 19, 2009 3:23 AM