ASP.NET MVC ajax to WebAPI returning WIF sts redirect response
We are using a custom WIF 3.0 STS Provider for multiple projects. I am integrating that authentication to both a new MVC 4 WebApp, and WebAPI 2 Service Layer.
If I browse directly to each (WebApp and WebAPI Service) I am able to correctly authenticate. It redirects to the WIF STS signin, I login, get a ClaimsToken, and it then redirects and displays the expected page.
However if I'm already authenticated, and my WebApp does a jQuery.get() ajax call to the WebAPI Service, it reacts like it has no ClaimsToken. It redirects (302) and my Response Header location is of the STS provider signin:
https://sts-provider.my.net/?wa=wsignin1.0&wtrealm=https%3a%2f%2fwebapi.services.my.net%2f&wctx=rm%3d0%26id%3dpassive%26ru%3d%252fapi%252fStuff&wct=2014-08-11T22%3a10%3a43Z&wreply=https%3a%2f%2fwebapi.services.my.net%2f
and the jQuery.get() callback gives me a textStatus of "error". How does the Service not see the ClaimsToken cookie? Please help.
I don't know what you try to accomplish. Probably your entire application is blocked from unauthorised access (which is the WIF default).
In that case it is normal that you get this redirect since the WIF http modules see this as an unauthorised request and redirect you to the STS to become authorised. There are several ways to solve this. The first thing to do is to make sure you tell asp.NET that you API is "open". You can open up the entire applcation in your web.config :
<system.web>
<authorization>
<allow users="*" />
</authorization>
And then close the (needed or all) MVC controllers using [Authorise] attributes. The advantage is that you web api will also be "open" and therefore not do a redirect. If you want to protect you web api using WIF tokens then you need additional work. In that case you need to make sure then sender somehow sends the security token in the header o fthe web api request. You can writer you own http filter for that. I guess the ThinkTecture nuget already contains some out of the box support for this as well.
Figured it out and hope this helps others. When making a cross-origin request with credentials and ssl secure (because of STS authentication), there's additional settings on both ends. Microsoft covers it briefly, but wasn't detailed enough for this implementation of ssl(app)-to-ssl(service) with ssl-STS-auth in between:
http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
So I changed my WebApp call to a jQuery.ajax() and set these additional options:
$.ajax({
url: "https://webapi.services.my.net/api/info/all",
type: 'GET',
//this tells my WebApp to send the ClaimsToken to the service call
xhrFields: { withCredentials: true },
//this tells the WebApp we're making a request against a different domain
crossDomain: true,
...
});
Then on my WebAPI Service controller I installed WebApi.Cors and setup as such:
[EnableCors(origins: "https://webapp.my.net",
headers: "*", methods: "*")]
public class InfoController : ApiController
{
But for some reason, I was still getting the error message:
Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials.
Well, it turns out I wasn't telling my WebAPI Service that it was receiving the credentials. The result was my WebApp call was just dying on a 302 redirect to the STS and never having a ClaimsToken to give the service call. My WebApp jQuery callback gave textStatus of "error" and jqXHR.status as 0, instead of 302. I fixed this by setting up my WebAPI Service controller with the additional SupportsCredentials setting:
[EnableCors(origins: "https://webapp.my.net",
headers: "*", methods: "*", SupportsCredentials = true)]
public class InfoController : ApiController
{
BOOM. We're in business. Hope this helps :)
链接地址: http://www.djcxy.com/p/12446.html上一篇: 什么是合适的WWW