I have a console application that sends a XML to a MVC application and receive another XML as a response. It works perfectly, but I want to add authorization (for obvious reasons).
Here is the code from the console application:
using (var wc = new WebClient())
{
return GetXmlFromBytes(
wc.UploadData("URL", GetBytesFromXml(xmlToSend))
);
}
And here is the code from the MVC application:
public ActionResult DoSomething()
{
XElement xml = XElement.Load(new System.IO.StreamReader(Request.InputStream));
var response = InsertDataFromXml(xml);
return File(GenerateFileFromResponse, "text/xml", "result.xml");
}
And it works. So, to implement the authorization, I added the following code:
Console (added the wc.Credentials
):
using (var wc = new WebClient())
{
wc.Credentials = new NetworkCredential("user", "password");
return GetXmlFromBytes(
wc.UploadData("URL", GetBytesFromXml(xmlToSend))
);
}
MVC application (added the [Authorize]
):
[Authorize]
public ActionResult DoSomething()
{
XElement xml = XElement.Load(new System.IO.StreamReader(Request.InputStream));
var response = InsertDataFromXml(xml);
return File(GenerateFileFromResponse, "text/xml", "result.xml");
}
And it doesn't work. I don't know if this information is needed to solve this, but my web.config
has the following item:
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
In fact, the file that the MVC application sends back is the HTML of the LogOn page!
What do I have to do to solve this? Is any parameter missing in the NetworkCredentials
? I know it can be instantiated with a domain
, but I don't know what is the domain of the users in the MVC application.
And, just to make sure: I assured "user" and "password" are valid.
You're mixing credential types;
wc.Credentials = new NetworkCredential("user", "password");
is for HTTP authentication.
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
is forms authentication.
These are entirely different, and not compatible. Using forms authentication from a command line app is challenging, you'd need to go to the login page with a request, POST the username and password, then take the authentication cookie that is return and attach it to subsequent requests.
You need to Authenticate first of all as you are using Forms Authentication.
Or Set the Auhentication Mode="Windows" if you are on a local intranet!
wc.Headers.Add(HttpRequestHeader.Cookie, "somecookie");
, right? ), but I still don't know how to do numer 1. Any ideas - Lucas Reis 2012-04-05 22:07
Create an AuthenticationService which can be used to do forms authentication. With the ClientBaseExtensions class you can get the cookie out of your WCF service client. Inject this cookie into the other call...
String cookies = null;
var auth = new AuthenticationServiceClient();
using (new OperationContextScope(auth.InnerChannel))
{
auth.Login("user", "password", null, true);
cookies = auth.GetIncomingCookies();
}
Now inject the cookie data into your data service or your HTTP call.
See http://mytoolkit.codeplex.com/wikipage?title=ClientBaseExtensions