2

I'm trying to get response with an access code and getting:

XMLHttpRequest cannot load "h...://login.microsoftonline.com/d331431b-899c-4666-8094-e82e6bfc3964/oaut…auth%2faad&scope=user_impersonation&state=033f4ad89a574135884fd3a03c1743ab". No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:23589' is therefore not allowed access.

Used all suggestions from the ServiceStack, CORS, and OPTIONS (No Access-Control-Allow-Origin header) discussion:

added:

Plugins.Add(new CorsFeature(new[] { "http://localhost/", "http://localhost:23589" },
            allowCredentials: true,
            allowedHeaders: "Content-Type, Allow, Authorization"));

and even:

PreRequestFilters.Add((httpReq, httpRes) =>
{
     //if (httpReq.Verb == "OPTIONS")
     //{
     //    var origin = httpReq.Headers.Get("Origin");
     string origin = httpReq.Headers.Get("Origin");
     httpRes.AddHeader(HttpHeaders.AllowOrigin,  "*");
     httpRes.EndRequest();
     // }
});

Still no luck. We are using ServiceStack version 4.0.56

Request URL:

> https://login.microsoftonline.com/d331431b-899c-4666-8094-e82e6bfc3964/oauth2/authorize?response_type=code&resource=https%3a%2f%2fanalysis.windows.net%2fpowerbi%2fapi&client_id=0d3be5ed-3361-43f5-9d25-a5ccefb11f7e&redirect_uri=http%3a%2f%2flocalhost%3a23589%2fapi%2fauth%2faad&scope=user_impersonation&state=d6ef09f8064643ed914d4995562642be

Request Method:GET
Status Code:200 OK
Remote Address:157.55.208.218:443

Response Headers:

HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Expires: -1
Vary: Accept-Encoding
Server: Microsoft-IIS/8.5
x-ms-request-id: d2531fb2-2e97-4940-a15d-f3c6f1cd5e7b
client-request-id: 376b2cb0-e1d2-4749-a8b5-adfee1b3ceba
X-Frame-Options: DENY
x-ms-gateway-service-instanceid: ESTSFE_IN_344
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
Set-Cookie: buid=AAABAAEAiL9Kn2Z27UubvWFPbm0gLfvzURnxA_SU_2fqg40MIAq5oFqJPcrl7iSuhLgh52CsEbHynIx5Krpov-SlQ7tVxK9O3EWPdKHzur0dQHXgfE4FLI6Vmv3-HwokZIpKbXA2IAA; expires=Fri, 02-Dec-2016 17:25:56 GMT; path=/; secure; HttpOnly
Set-Cookie: esctx=AAABAAAAiL9Kn2Z27UubvWFPbm0gLdbqNasFxQzD3cBv92w234pND-QPmCQNU9pfwexBLi9fullMTJbXyFHlgwaIpWQHx6OpBt9rHaIVDwlxaAh7MqFmsrHiMcoXcWy55B0veMpU10kthlQdtj37nLx1_p3ocBF3tMJ822MGbR2D-Epr8iTW2AmiL46Q2oxA9gHfuwYBIAA; domain=.login.microsoftonline.com; path=/; secure; HttpOnly
Set-Cookie: x-ms-gateway-slice=productiona; path=/; secure; HttpOnly
Set-Cookie: stsservicecookie=ests; path=/; secure; HttpOnly
X-Powered-By: ASP.NET
Date: Sun, 05 Jun 2016 17:25:55 GMT
Content-Length: 9602

Request Headers:

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8,ru;q=0.6
Cache-Control:max-age=0
Connection:keep-alive
Host:login.microsoftonline.com
Origin:http://localhost:23589
Referer:http://localhost:23589/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36

I also tried adding this code in AppHost Confugure method:

 base.SetConfig(new HostConfig
            {
                GlobalResponseHeaders = {
                    { "Access-Control-Allow-Origin", "*" },
                    { "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
                    { "Access-Control-Allow-Headers", "Content-Type" },
                },
            });

From Fiddler:

Request headers:

GET /d331431b-899c-4666-8094-e82e6bfc3964/oauth2/authorize?response_type=code&resource=https%3a%2f%2fanalysis.windows.net%2fpowerbi%2fapi&client_id=0d3be5ed-3361-43f5-9d25-a5ccefb11f7e&redirect_uri=http%3a%2f%2flocalhost%3a23589%2fapi%2fauth%2faad&scope=user_impersonation&state=3c41d4ea46a8408fb19fdf05ea07643a HTTP/1.1
Host: login.microsoftonline.com
Connection: keep-alive
Cache-Control: max-age=0
Accept: application/json, text/plain, */*
Origin: http://localhost:23589
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://localhost:23589/
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8,ru;q=0.6

Response Headers:

HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Expires: -1
Vary: Accept-Encoding
Server: Microsoft-IIS/8.5
x-ms-request-id: 70fcd73f-f880-4744-b896-6edc491b1d22
client-request-id: a52446b6-a7f0-4afb-ba23-8d27207ddb27
X-Frame-Options: DENY
x-ms-gateway-service-instanceid: ESTSFE_IN_19
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
Set-Cookie: buid=AAABAAEAiL9Kn2Z27UubvWFPbm0gLWnOYMRRqrZRDzgogkab1uuAetOi-f1iLnpE1G5EU3xMkzYdvTgIs2Fz79S07PNcfnEry6eWS8RX_4k8awcIgY063VQ7VvWP6SRRvXfCgpJeIAA; expires=Fri, 02-Dec-2016 22:20:48 GMT; path=/; secure; HttpOnly
Set-Cookie: esctx=AAABAAAAiL9Kn2Z27UubvWFPbm0gLZemnOQ8vijuCpi6h8NzV-CjOfr0MZwZhb4Nfczf20C1TSXORoJbIHCbVBV_MmeuXTR1mbzh9GzFIBmi__ff0M-gGh02fol-sHPyKJnU7Zfi2cEYWensHvmiEJO9Tw5KbO8tWdZxl-XDi7V5IZNNsJWp4LxTVVGkOeyOYieMfJ6mIAA; domain=.login.microsoftonline.com; path=/; secure; HttpOnly
Set-Cookie: x-ms-gateway-slice=productiona; path=/; secure; HttpOnly
Set-Cookie: stsservicecookie=ests; path=/; secure; HttpOnly
X-Powered-By: ASP.NET
Date: Sun, 05 Jun 2016 22:20:49 GMT
Content-Length: 36210
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Tatyana K
  • 21
  • 5
  • Can you post the raw HTTP Request and Response Headers, you can get them with Chrome WebInspector or Fiddler. – mythz Jun 03 '16 at 20:54
  • Thank you for the reply. There are no: "Access-Control-Allow.." in the Response Headers. Access-Control-Allow-Headers:Content-Type Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Origin:* – Tatyana K Jun 05 '16 at 17:51
  • When I call my AuthProvider directly everything is good and request/response look different: Request URL:https://login.microsoftonline.com/d331431b-899c-4666-8094-e82e6bfc3964/oauth2/authorize?response_type=code&resource=https%3a%2f%2fanalysis.windows.net%2fpowerbi%2fapi&client_id=0d3be5ed-3361-43f5-9d25-a5ccefb11f7e&redirect_uri=http%3a%2f%2flocalhost%3a23589%2fapi%2fauth%2faad&scope=user_impersonation&state=e3adb3ae0daf433c85c20b427f347739 Request Method:GET Status Code:302 Found Remote Address:157.55.208.218:443 – Tatyana K Jun 05 '16 at 18:15
  • The `Origin` and `Referer` headers seem incomplete or corrupted. The url in the Origin header is what's supposed to match exactly with what's added on `Plugins.Add(new CorsFeature(new[] { "http://localhost:23589" });` – mythz Jun 05 '16 at 19:34
  • i tried with "/" and without.The error message has: http://localhost:23589. – Tatyana K Jun 05 '16 at 21:32
  • i tried with "/" and without.The error message has: http://localhost:23589. When I call auth provider directly: http://localhost:23589/api/auth/aad Origin and Referer are not in the request headers – Tatyana K Jun 05 '16 at 21:39
  • You need to look at the Request Headers made in the Ajax request only. Maybe try capturing the HTTP Headers using Fiddler as the headers you posted seem incomplete/corrupted which doesn't help identifying the issue. Also make sure you're not trying multiple different ways to add CORS Headers as they'll be invalidated (as you're doing with the GlobalResponseHeaders, CorsFeature plugin + PreRequestFilters which are all doing the same thing). Stick with one method, ideally the CorsFeature, then capture and repost the HTTP Headers. – mythz Jun 05 '16 at 21:48
  • Only kept CorsFeature plugin, but stop seeing: "Access-Control-Allow-Origin" header, but looks like it doesn't even apply when i make requests to azure. The issue is still there. Posted fiddler headers. Thanks again for your help. – Tatyana K Jun 05 '16 at 22:32
  • The `Origin` header still seems corrupted, I'd look into why it's sending `h..p://` instead of `http://`. – mythz Jun 05 '16 at 22:37
  • sorry, i had to change http to h..p because stackoverflow would not let me add links to my questions. – Tatyana K Jun 05 '16 at 23:17
  • That's because you didn't indent it to mark up the fragment as code, have a look at the updated answer for an example. Please never rewrite important pieces of info like this, it completely throws us off. So the issue is because the HTTP Response doesn't contain the `Access-Control-Allow-Origin`. But what's not making sense is why you're requesting `login.microsoftonline.com`, it's unlikely you're in control of this domain, so you're not going to be able to configure it to accept CORS, that's only something the service implementation itself has to do. – mythz Jun 05 '16 at 23:31
  • Sounds like you have a misunderstanding how CORS works, the request is failing when you try to access `https://login.microsoftonline.com/..` from Ajax which you can't do because it doesn't have CORS enabled. But what I'm not seeing is what ServiceStack has to do with this request, and where you're expecting the CorsFeature is meant to modify the returned headers as it just looks like it's just between Ajax and `login.microsoftonline.com`? – mythz Jun 05 '16 at 23:36
  • I've added two IAuthProvider providers in AppHost.cs. One of them has to login to azure. For that it has to request the code and get it back in a query string. this provider has Provider = "aad" and AuthRealm = "auth/aad". if i call it directly in the browser it works well. I tried to create AuthenticateAttribute sending "aad" to the base constructor, but when the service decorated with this attribute is called default login popup is displayed. How to link the attribute to the authprovider? If you need to call authenticate once when app starts what is the right place? – Tatyana K Jun 06 '16 at 00:44
  • I don't know what you're asking but it doesn't have anything to do with this question, ask a new question, provide all relevant source code and explain exactly what you're trying to, what doesn't work and exactly what the issue is. – mythz Jun 06 '16 at 00:53
  • Yes, it does. The auth provider is registered in AppHost and mapped to url: /auth/add. When i call this url I get No 'Access-Control-Allow-Origin' header. I am asking this question because I'm new to ServiceStack and could not find example how to do it. – Tatyana K Jun 06 '16 at 12:51
  • Nothing in your question is about the AAD auth provider, instead you've mischaracterized the issue as a ServiceStack CORS issue which doesn't have any impact between your Ajax call and the remote `http://login.microsoftonline.com..` which it wont let you do since it doesn't allow CORS. Go back to what works by directly linking to `/api/auth/aad` because you're fundamentally prohibited from doing what you're trying to do with Ajax and no amount of local server configuration is going to have any effect. – mythz Jun 06 '16 at 13:13

3 Answers3

2

The issue is because you're trying to call the /api/auth/aad OAuth route via Ajax instead of linking to it directly in your page.

You can't call the AAD OAuth route via Ajax since the url it redirects to that's used to capture the clients authorization (https://login.microsoftonline.com/..) doesn't allow CORS as indicated in the error that you're seeing.

This isn't a ServiceStack CORS issue which you don't need in order to talk to your local API's (i.e. http://localhost:23589) since its hosted in the same domain as the HTML page. CORS (Cross-origin resource sharing) is needed when using Ajax to access a resource outside of the domain (i.e. https://login.microsoftonline.com/..) which since it doesn't allow CORS will not let you access that url via Ajax.

mythz
  • 141,670
  • 29
  • 246
  • 390
1

Remove the last slash in your url "http://localhost"

Mike
  • 1,645
  • 3
  • 13
  • 21
1

As mythz explained in his answer, CORS is not allowed from your originating domain. You are, however, allowed to register your application with Microsoft Azure(?) Active Directory so that it can display a separate login dialog that will return a callback to your application as soon as authentication succeeds.

For more information about the AAD login flow (mind you, this is a NodeJS example, not bare javascript, but the same logic applies) check out Getting started with Azure AD.

DJFliX
  • 170
  • 7
  • Thank you for your answer. I was trying to avoid javascript libraries such as (adal and adal-angular) and login to Azure using ServiceStack authentication: https://github.com/jfoshee/ServiceStack.Authentication.Aad . It works great when there is no client, but doesn't in real life when you add a client. I had to give up on the server side authentication to Azure and went back to adal.js. – Tatyana K Jun 14 '16 at 14:15
  • I know the AAD login flow, and here is the issue: 1. Client calls a service that needs access to Azure. 2. Service calls AAD AuthenticationProvider. 3. AuthenticationProvider requests a code and returns. 4.Service returns. 5. Microsoft sends the code in the query string but AuthenticationProvider can't get it and continue with the flow. – Tatyana K Jun 14 '16 at 14:17
  • Thanks for your explanation :). – DJFliX Jun 15 '16 at 07:41