|
I’ve been writing on Credentials in context of Silverlight for some time now. I didn’t like the options that were available to secure services and allow integration with Silverlight. For some history search for “credentials” on my blog.
July 2008 – Silverlight 2 – A series of articles on possible (failed) work-arounds for getting Credentials in Silverlight.
March 2009 – Silverlight 3 – WebClient, WebRequest and WCF calls using Credentials?
July 2009 – Silverlight 3 – Did we get support for Credentials?
In Silverlight 3 we already got the property Credentials on both WebClient and WebRequest. But sadly there still was no implementation available. After the launch of Silverlight 3 Tim Heuer already commented that the feature for credentials was being considered for future versions. Very nice, specially because we finally got it in Silverlight 4 (beta).
Support for Credentials has come to the ClientHttp stack, so you must make sure you register the http prefix to be using ClientHttp stack.
WebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.ClientHttp);
Besides that we also need to make sure that we set the property UseDefaultCredentials to false. Depending on whether you make use of a WebRequest or use a WebClient it will look like this.
request.UseDefaultCredentials = false;
WebRequest with Credentials
When you want do a simple webrequest to a url that’s secured using credentials this can look like this.
private void DoWebRequestWithCredentials()
{
WebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.ClientHttp);
var request = WebRequest.Create(new Uri("http://mark.mymonster.nl")) as HttpWebRequest;
request.Credentials = new NetworkCredential("username", "password");
request.UseDefaultCredentials = false;
request.BeginGetResponse(ResponseCallBack, request);
}
private void ResponseCallBack(IAsyncResult ar)
{
var request = ar.AsyncState as HttpWebRequest;
var response = request.EndGetResponse(ar) as HttpWebResponse;
using(var reader = new StreamReader(response.GetResponseStream()))
{
string result = reader.ReadToEnd();
}
}
WebClient with Credentials
The WebClient has the same properties. Works same as providing credentials to a WebRequest, that’s really nice.
private void DoWebClientDownloadWithCredentials()
{
WebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.ClientHttp);
var client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.UseDefaultCredentials = false;
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(new Uri("http://mark.mymonster.nl"));
}
private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
string result = e.Result;
}
WCF?
Sadly during tryout I didn’t find the credentials property to be part of ClientBase<T>. So for WCF we still have to wait some time to get credentials, or will it be part of final Silverlight 4?
What happens when you provide the wrong credentials?
I tried to make a webrequest with the wrong credentials. I expected an exception similar to “Unauthorized”, but instead I received a WebException with the message “The remote server returned an error: NotFound.”. I hope the team changes this to a more meaning full exception, because this makes debugging very hard.
|
December 3rd, 2009 at 01:05
[...] Silverlight 4 – Credentials, we’ve got it! « Mark Monster mark.mymonster.nl/2009/12/02/silverlight-4-credentials-weve-got-it – view page – cached I’m a Software Engineer specialized in Microsoft technology with a special interest for Silverlight. Since 2007 I work for Rubicon as a Software [...]
December 3rd, 2009 at 16:30
Excelent article. I copy/pasted your code, zipped the project and put it here: http://niklas.saers.com/files/sl4auth1.zip It gives me the following error:
{System.Security.SecurityException: Security error.
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.ClientHttpWebRequest.c__DisplayClass5.b__4(Object sendState)
at System.Net.Browser.AsyncHelper.c__DisplayClass2.b__0(Object sendState)}
Then I copied the second example, put it at http://niklas.saers.com/files/sl4auth2.zip, it gives this exception:
{System.Security.SecurityException: Security error.
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.ClientHttpWebRequest.c__DisplayClass5.b__4(Object sendState)
at System.Net.Browser.AsyncHelper.c__DisplayClass2.b__0(Object sendState)}
Any idea what I’m doing very different from what you’re doing?
Cheers
Nik
December 3rd, 2009 at 16:49
To follow up with a quick PS, I thought perhaps it could be because http://mark.mymonster.nl/clientaccesspolicy.xml was missing, but I’ve tried using my own server, and here it first gets clientaccesspolicy.xml, and then it fails with the TargetInvocationException that has the inner-exception:
{System.Security.SecurityException —> System.Security.SecurityException: Security error.
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.ClientHttpWebRequest.c__DisplayClass5.b__4(Object sendState)
at System.Net.Browser.AsyncHelper.c__DisplayClass2.b__0(Object sendState)
— End of inner exception stack trace —
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
at System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult result)}
Cheers
Nik
December 3rd, 2009 at 21:30
[...] more: Silverlight 4 – Credentials, we've got it! « Mark Monster By admin | category: Silverlight, silverlight 2 | tags: articles-on-possible, [...]
December 4th, 2009 at 04:15
[...] the original: Silverlight 4 – Credentials, we've got it! « Mark Monster By admin | category: silverlight | tags: been-writing, credentials, like-the-options, [...]
December 7th, 2009 at 17:29
Why would we want this? I assume just when not using an Intranet? Does the username and password go across the network in plain text?
December 7th, 2009 at 21:20
Hi Mark,
There can be a lot of different reasons why you would want to use this.
For example:
- Some web API’s make use of Basic Authentication for the authentication part.
- Your webservices are built on a completely different platform, and authentication is done using Basic Authentication.
Yes it is send as plain text when you’re connecting to a HTTP address. But remember this is exactly the same as logging in to a normal webapplication that’s running on HTTP. If you want it secure you can make use of HTTPS.
One of the examples I’m thinking of is like this: an Silverlight application that can run out of browser but communicates with a Sharepoint List over the Internet. In that case I would use Basic Authentication over an HTTPS connection to authenticate the user in Sharepoint.
Does this explain it a little bit more Mark?