質問

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.

  1. Invoke the Logon Web Method and capture the Auth Cookie from the Http Response
  2. Set the Auth Cookie on the second Http Request to the DoSomething Method

Or Set the Auhentication Mode="Windows" if you are on a local intranet!

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top