By process of (hours of) elimination I have solved a problem that was driving
me batty today!
I have a WSE 3.0 enabled client app that calls a WSE enabled web service.
After creating a UsernameToken, the client application was setting the
credentials on the web service proxy using the generic overload:
proxy.SetClientCredential(Of UsernameToken)
(myUT)
As I built the tests up one by one everything was working swimmingly... until
I added in the SecureConversation into the client and service policies.
(establishSecurityContext="true").
Then I was getting a 401 Access denied whenever I tried to hit the web
service. I could see through the status of the tracing that I was not even
touching the web server on these calls.
Setting the SecureConversation to false let everything work again.
I spent quite a lot of time experimenting and scrutinizing my settings,
configs, etc.
I even loaded up the sample application for Secure Conversation which worked
perfectly fine.
Both web services were in IIS and I compared everything. config files, policy
files, IIS properties and security, folder security.
Combing through these, I tested every little thing that was different -
folder access permissions and more. I explored differences in code such as
setting the soapversion explicitly on the proxy. Nothing made a difference.
But finally, I came upon the nominal difference that was causing the problem
(though I have no explanation for it).
It was the use of generics in setting the ClientCredential on the proxy.
When I used the non-generic method, as the sample uses:
proxy.SetClientCredential(myUT)
instead of
proxy.SetClientCredential(Of UsernameToken)
(myUT)
suddenly I was getting a response from the server. It was still an error, but
I knew I was finally getting through to the server.
The new error was my method of doing authorization on the token. This new
token was "just a securityContextToken" and not a UsernameToken.
In my web service, I had cobbled together some old WSE 2.0 authorization code
with some WSE 3.0 code which looked like this
dim tok as
UsernameToken=RequestSoapContext.Current.IdentityToken
if tok.Principal.IsInRole(....blah blah
blah
When attaching the credentials using the generic method, IdentityToken was
returned as a UsernameToken, but now it is not. It has a base of UsernameToken,
but it doesn't cast (I tried) to UsernameToken.
I can get the principal directly from IdentityToken anyway, so I just
modified that code
dim tok as SecurityToken =
RequestSoapContext.Current.IdentityToken
if tok.Principal.IsInRole(....blah blah blah
This cost me many many hours. At least now there will be something for Google
to find!!
Don't Forget: www.acehaid.org