.NET Forum / ASP.NET / Web Services / April 2006
WSE 3.0 + UserNameToken without X.509 Cert/Kerberos + Signing + Encryption How?
|
|
Thread rating:  |
James Hancock - 22 Mar 2006 05:32 GMT OK, thanks to Julia's help and a bunch of stuff in the newsgroups I've got some of this working but not all...
Basically I need to be able to encrypt both sides of the communication between client and server using a UserNameToken that passes the UserName but not the password but is a shared secret. I cannot use X.509 or anything like that because the number of client computers is unknown and could easily be thousands, and the server may not necessarily have an SSL key and I don't want to leave it up to my clients to optionally get an SSL key, because most of them won't because they're lazy or cheap or some other "really good reason" that will jepardize their data. <aside>Hence Shared secret, which I used in WSE 2.0 with great effect because the shared secret password was unique per client computer, and it was a 512 bit hash which is really hard to break, and after every operation the hash would change (sent in the encrypted message body by the server to the client and then stored in a different encryption in the local database). (Yes, I know, if you break one message, you break 'em all, but you can't use two messages to compare between the two... I was working on an algorhythm that the server and client would use to calculate the new hash without one sending it to the other, but since this works, and is very secure the way it is, it wasn't high on the list of priorities...</aside>
I was able to do this stuff in WSE 2.0 before using the now depreciated Context.Security... stuff. No go in WSE 3.0 because it's depreciated. If I use the depreciated functions, it works fine... I think... can't tell because it doesn't use the policy stuff of course.
I've got the signing stuff done and working by using a Custom UserNameTokenManager on the server and then creating the right entries in my web.config file. Which works and is called and validates the whole deal.. assuming the client request adds a proper UserNameToken...
It still lets clients that don't use anything query my WebMethods however.
So I looked in the newsgroups here and decided I needed a policy file because the way I was doing it before was to query the Context.Security stuff looking for the entries... which is depreciated.
So I added the following on the server:
<policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">
<extensions>
<extension name="usernameOverTransportSecurity" type="Microsoft.Web.Services3.Design.UsernameOverTransportAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<extension name="wse3Trace" type="WSETracingFilter.WSEFilterAssertion, WSETracingFilter, Version=3.0.0.0, Culture=neutral, PublicKeyToken=aa253a6b9020c4eb"/>
</extensions>
<policy name="RegistrationPolicy">
<usernameOverTransportSecurity />
<requireActionHeader />
<wse3Trace/>
</policy>
</policies>
Then on the Service itself:
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Policy("RegistrationPolicy")]
public class Registration : System.Web.Services.WebService {
...
and the following on the client:
<policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">
<extensions>
<extension name="usernameOverTransportSecurity" type="Microsoft.Web.Services3.Design.UsernameOverTransportAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<extension name="wse3Trace" type="WSETracingFilter.WSEFilterAssertion, WSETracingFilter, Version=3.0.0.0, Culture=neutral, PublicKeyToken=aa253a6b9020c4eb"/>
</extensions>
<policy name="UserNamePolicy">
<usernameOverTransportSecurity />
</policy>
</policies>
and in the client request:
Microsoft.Web.Services3.Security.Tokens.UsernameToken tok = new Microsoft.Web.Services3.Security.Tokens.UsernameToken(UserName, Password, Microsoft.Web.Services3.Security.Tokens.PasswordOption.SendNone);
r.SetPolicy("UserNamePolicy");
r.SetClientCredential(tok);
Note that I'm using Mike's tool to monitor the requests.... hence the added Extension...I tried removing it and users can still just request the WebMethod and it works.
Sorry if this is a dupe everyone. It didn't seem to go through the first time...
All is good in that Mike's tool tells me that the username tolken is added etc. However!
1. The contents of the message are not encrypted. They absolutely have to be encrypted.... But the docs say that UsernameoverTransport doesn't support it, but when I query the UserNametoken it says that it does support encryption... Help please!
2. You can still request the WebMethods without any of this stuff and it works.
Also...
I would like to make sure that the minimum amount of data is sent over the wire (there could be dialup users using this!) so any suggestions on how to get this whole system to send stuff only once on the first request etc. would be greatly appreciated. (i.e. how do I enable SecureConversation??? Is that even the right way to go about it?)
I wish MS would just accept that this is a scenario that they need to support and put it in instead of making it harder and harder every time they do this, cause people are just going to get around it (like me) and thus likely are not going to get it right and think they have encrypted secure communications when they don't... better to have MS do it and do it right instead of letting people hack something together...
Thanks for any help you might be able to provide!
James Hancock
Pablo Cibraro - 22 Mar 2006 14:26 GMT Hi James,
First of all, the UsernameOverTransport turn-key assertion does not use message security and thefore it does not encrypt the message. You need to combine this assertion with a secure transport like SSL if you want to protect your messages. WSE does not provide a turn-key assertion to encrypt messages using a username token only, so you will have to develop a custom assertion in order to do that.
Secondly, you should add an authorization assertion to restrict the access to your webmethods.
Thirdly, secure conversation does not optimize the amount of data sent over the wire. This article in my weblog gives a description of this feature
http://weblogs.asp.net/cibrax/archive/2006/02/21/438670.aspx
All the turn-key assertions that use message security add the headers required by WS-Security to the message, and it is difficult to optimize that part. You should use an assertion for transport security instead.
This security guide from the Pattern & Practices team also provides really good information about this topic
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/WSSP.asp
I hope this can help you.
Regards, Pablo Cibraro http://weblogs.asp.net/cibrax
> OK, thanks to Julia's help and a bunch of stuff in the newsgroups I've got > some of this working but not all... [quoted text clipped - 157 lines] > > James Hancock James Hancock - 22 Mar 2006 18:02 GMT OK...
So what I've done is use this CodeProject article: http://www.codeproject.com/soap/WSE30UsernameAssertion.asp
Which got me to encrypted, signed messages using UserName stuff. It didn't do response encryption, but I added that and it's working to great effect.
However, I'm at a loss on how to add an "authorization assertion" to restrict access requiring the UserNameTolken to be there. I can't find anything in the documentation on how to get my assertion that I added to the policy file to always check. It seems that the ValidationMessageSecurity function in the ReceiveSecurityFilter that I added for server side stuff only gets called if the assertion is added on the client side. Otherwise it never gets called.
What am I doing wrong?
FYI, for anyone else that needs UserName stuff, I'm adding compression, and if I can get this one issue with requiring the signing of the message at all times solved, I'll happily post the solution for others to use, because this should be part of WSE from the ground up.
Thanks in advance for the help everyone!
James Hancock
> Hi James, > [quoted text clipped - 198 lines] >> >> James Hancock James Hancock - 22 Mar 2006 20:49 GMT BTW, I still think that there is a lot of benefit for Secure Conversation for what I'm doing (hundreds of requests back and forth).
Can you give me some suggestions on how to impliment it in my custom assertion or give me a direction to look to impliment my own custom version of whatever I need to do please?
Thanks! James Hancock
> Hi James, > [quoted text clipped - 198 lines] >> >> James Hancock Pablo Cibraro - 23 Mar 2006 14:33 GMT Hi James,
1. In order to use authorization, you must add the authorizationAssertion to your policy. The sample below shows how to do that:
<policy name="usernameTokenSecurity"> <authorization> <allow role="Administrators" /> <deny role="*" /> </authorization> <usernameForCertificateSecurity establishSecurityContext="true" renewExpiredSecurityContext="true" requireSignatureConfirmation="false" messageProtectionOrder="SignBeforeEncryptAndEncryptSignature" requireDerivedKeys="true" ttlInSeconds="60"> <serviceToken> <x509 storeLocation="LocalMachine" storeName="My" findValue="CN=WSE2QuickStartServer" findType="FindBySubjectDistinguishedName" /> </serviceToken> <protection> <request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" /> <response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" /> <fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" /> </protection> </usernameForCertificateSecurity> <requireActionHeader /> </policy>
2. If you want to support Secure Conversation in your custom assertion, then the Soap filters returned by your assertion must derive from the following classes:
- ClientInputFilter : SecureConversationClientReceiveSecurityFilter - ClientOutputFilter : SecureConversationClientSendSecurityFilter - ServiceInputFilter : SecureConversationServiceReceiveSecurityFilter - ServiceOutputFilter : SecureConversationServiceSendSecurityFilter
Your assertion must derive from the class SecurityPolicyAssertion as well.
In that way, your assertion will automatically support Secure conversation. The STS quickstart from the Pattern & Practices implements a Custom Assertion for SAML tokens that uses Secure Conversation.
http://www.gotdotnet.com/codegallery/codegallery.aspx?id=8da852b9-2c0d-4eb7-a2de -77222a4075f6
3. If you want to compress the messages, you can find a nice implementation of WS-Compression here http://weblogs.shockbyte.com.ar/rodolfof/archive/2006/02/07/4585.aspx
Thanks Pablo Cibraro http://weblogs.asp.net/cibrax
> BTW, I still think that there is a lot of benefit for Secure Conversation > for what I'm doing (hundreds of requests back and forth). [quoted text clipped - 215 lines] >>> >>> James Hancock James Hancock - 27 Mar 2006 05:54 GMT OK, so still trying to get this thing locked down...
I updated my policy cache file like so: <policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">
<extensions>
<extension name="compressionAssertion" type="Evolution.Web.Services.CompressionAssertion, Evolution.Web.Services"/>
<extension name="usernameAssertion" type="Evolution.Web.Services.UsernameServiceAssertion, Evolution.Web.Services" />
<extension name="wse3Trace" type="WSETracingFilter.WSEFilterAssertion, WSETracingFilter, Version=3.0.0.0, Culture=neutral, PublicKeyToken=aa253a6b9020c4eb"/>
</extensions>
<policy name="RegistrationPolicy">
<authorization>
<allow role="Administrators"/>
<deny role="*"/>
</authorization>
<protection>
<request signatureOptions="IncludeAddressing, IncludeTimestamp,
IncludeSoapBody" encryptBody="true" />
<response signatureOptions="IncludeAddressing, IncludeTimestamp,
IncludeSoapBody" encryptBody="true" />
<fault signatureOptions="IncludeAddressing, IncludeTimestamp,
IncludeSoapBody" encryptBody="false" />
</protection>
<requireActionHeader />
<compressionAssertion compressionMode="BZip2" compressionLevel="Maximum" threshold="128"/>
<usernameAssertion />
<wse3Trace/>
</policy>
</policies>
usernameAssertion is my own, it is not based on usernameForCertificateSecurity because I'm not using it, I am not using any certificates at all, all of the encryption stuff is done in my custom assertion. Even with all of that stuff added to the policy cache file, you can still go in and it will give you results from your browser window. What am I doing wrong?
Thanks.
James Hancock
> Hi James, > [quoted text clipped - 275 lines] >>>> >>>> James Hancock Kaloyan Georgieff - 17 Apr 2006 08:23 GMT Hello James,
I'm working on the project which requires encrypting and signing response and request messages both on the client and server parts with Usernametoken. You said that you have implemented it. I'm using one article from CodeProject (which you mentioned as well) but there is no full implementation of it (only ouput on client side and input on server side). Please send me your solution for it.
Thanks in advance!
Best Regards Kaloyan
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|