Issue with Azure AD B2C oauth/OpenIdConnect - azure

I have an odd issue with azure authentication. It works in one scenario (logging in with an angular app using adal) but not in an other (loading the asp.net web api up and logging in via the swagger ui authorise mechanism). I have narrowed it down to a post to the:
https://login.microsoftonline.com/te/{tenantid}/oauth2/authresp
endpoint which rather unhelpfully returns:
302
<html>
<head>
<title>Object moved</title></head>
<body>
<h2>Object moved to here.</h2>
</body>
</html>
Basically telling me an exception has occurred.
error_description = AADB2C An exception has occured.
CorrelationID = 1816d2f8-aa74-4433-a7c0-d9c8fabebdb0
Timestamp = 2017-10-27 13:46:08
The angular app, does exactly the same post but that however returns a link with the token id:
302
<html>
<head>
<title>Object moved</title>
</head>
<body>
<h2>Object moved to <a href="http://localhost:4200/#state={state -
ommitted}&id_token={id token - omitted}">here</a>.
</h2>
</body>
</html>
I can't see any differences in the posts. This one does not work (initiated from swagger ui on web api project)
POST https://login.microsoftonline.com/te/{tenant - omitted}/oauth2/authresp HTTP/1.1
Host: login.microsoftonline.com
Connection: keep-alive
Content-Length: 1595
Cache-Control: max-age=0
Origin: https://login.microsoftonline.com
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
DNT: 1
Referer: https://login.microsoftonline.com/{tenant - omitted}/oauth2/authorize?client_id={clientid - omitted}&redirect_uri=https:%2f%2flogin.microsoftonline.com%2fte%2f{tenant - omitted}%2foauth2%2fauthresp&response_type=id_token&response_mode=form_post&nonce={nonce}&state=StateProperties
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,de-CH;q=0.8,de;q=0.7,fr-CH;q=0.6,fr;q=0.5,it-CH;q=0.4,it;q=0.3
Cookie: {cookie - omitted}=; x-ms-gateway-slice=005; stsservicecookie=cpim_te
id_token={omitted}
But this post does:
POST https://login.microsoftonline.com/te/{tenant - omitted}/oauth2/authresp HTTP/1.1
Host: login.microsoftonline.com
Connection: keep-alive
Content-Length: 1590
Cache-Control: max-age=0
Origin: https://login.microsoftonline.com
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
DNT: 1
Referer: https://login.microsoftonline.com/{tenant - omitted}/oauth2/authorize?client_id={clientid - omitted}&redirect_uri=https:%2f%2flogin.microsoftonline.com%2fte%2f{tenant - omitted}%2foauth2%2fauthresp&response_type=id_token&response_mode=form_post&nonce={nonce}&state=StateProperties
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,de-CH;q=0.8,de;q=0.7,fr-CH;q=0.6,fr;q=0.5,it-CH;q=0.4,it;q=0.3
Cookie: {cookie - omitted}; x-ms-gateway-slice=003; stsservicecookie=cpim_te
id_token={omitted}
As the posts are pretty much identical the issue must lie somewhere in either the cookie or the id token (which I cannot supply for security reasons). Pasting the ID tokens from both requests into http://www.jwt.io gives me same information with the correct claims present in both. So I am a little stuck and hoping someone from the azure team can step in and help?
Many thanks

Based on the referrer in your request samples, it looks like you're not calling /v2.0/ B2C endpoint. For example, in the following request, the path should be /{tenant}/oauth2/v2.0/authorize...
https://login.microsoftonline.com/{tenant}/oauth2/authorize?client_id={clientid}&redirect_uri=https:%2f%2flogin.microsoftonline.com%2fte%2f{tenant}%2foauth2%2fauthresp&response_type=id_token&response_mode=form_post&nonce={nonce}&state=StateProperties
Due to this, you're getting unexpected behavior across both your apps. This also means that the applications you are using were not created using B2C portal (we verified this via our offline chat as well).
As of now, B2C ONLY supports applications created through the B2C portal. So, if you can kindly create an application through the B2C portal, and try again, you should have this issue resolved.

Related

gitHubAutoDeployer for Google Cloud Functions auth redirects

I'm attempting to use the gitHubAutoDeployer function provided by:
https://github.com/GoogleCloudPlatform/community/blob/master/tutorials/cloud-functions-github-auto-deployer/index.md
I followed the project, but upon deploying and trying to trigger it, I discovered that the response to my webhook was a Google OAuth screen (in the GitHub project, go to Settings > Webhooks > Recent Deliveries). I went ahead and made the request interactive in a browser so I could provide access. After providing my credentials, I was redirected to the following:
<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>403 Forbidden</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Forbidden</h1>
<h2>Your client does not have permission to get URL <code>/gitHubAutoDeployer</code> from this server.</h2>
<h2></h2>
</body></html>
Now, Recent Deliveries in GitHub respond with a 302:
Content-Length: 2
Content-Type: text/html
Date: Mon, 30 Mar 2020 15:02:27 GMT
Location: https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=https://appengine.google.com/_ah/conflogin%3Fcontinue%3Dhttps://us-central1-REDACTED.cloudfunctions.net/gitHubAutoDeployer
Server: Google Frontend
X-Cloud-Trace-Context: d3333e1490ee3ca522c37243673931ed
What am I doing wrong? Any thoughts?
UPDATE: I opened an issue on the project's GitHub - there's a little more information available over there:
https://github.com/GoogleCloudPlatform/community/issues/1202
I also followed the tutorial on the project you referenced and I got the same result.
However, I achieved the expected behavior using Cloud Build with Continuous deployment

Add custom headers to ViewEngine response pages in ServiceStack

I am using ServiceStack with SharpPages to render dynamic content. For "reasons", I need to set the CORS headers Access-Control-Allow-Origin and Access-Control-Allow-Credentials, supporting multiple subdomains.
My SharpPages feature is enabled with :
var pagesFeature = new SharpPagesFeature()
{
ScriptMethods = { new UrlScriptMethods(), new DbScriptsAsync() },
};
pagesFeature.Args[ServiceStack.Script.ScriptConstants.DefaultDateFormat] = "MM/dd/yyyy hh:mm";
pagesFeature.Args[ServiceStack.Script.ScriptConstants.DefaultDateTimeFormat] = "MM/dd/yyyy hh:mm";
Plugins.Add(pagesFeature);
I'm hosting on IIS, so I could use web.config like below, but I can only specify one domain this way. If I specify multiple, XMLHttpRequest calls complain there are multiple domains set for that header.
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="https://subdomain.domain.com" />
</customHeaders>
</httpProtocol>
</system.webServer>
Likewise, I could have used the ServiceStack HostConfig property GlobalResponseHeaders, but same deal.
I've even tried ServiceStack PreRequestFilters, but those aren't called unless a service method is called. Here is my filter:
this.PreRequestFilters.Add((httpReq, httpResp) =>
{
var origin = httpReq.Headers.Get(HttpHeaders.Origin);
if (!string.IsNullOrWhiteSpace(origin))
{
httpResp.AddHeader(HttpHeaders.AllowOrigin, origin);
httpResp.AddHeader(HttpHeaders.AllowCredentials, "true");
}
});
Finally, StaticFileHandler.ResponseFilter won't work, since I'm using a view engine and not static files.
So, how can I add custom response headers to View Pages (SharpPages in particular, possibly Razor pages as well) in ServiceStack?
The raw request is below. Interesting that I'm requesting https://computer.domain but FireFox translates that to localhost. Regardless, the favicon.ico request DOES get trapped by the filter. The request below DOES NOT.
GET /forms/newsletter HTTP/1.1
Host: localhost:44308
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: ss-pid=wCR4INmjLXpBnbsBoe2n
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
The raw response is :
HTTP/2.0 200 OK
cache-control: private
content-type: text/html
content-encoding: gzip
vary: Accept-Encoding
server: Microsoft-IIS/10.0
x-aspnet-version: 4.0.30319
x-sourcefiles: =?UTF-8?B?QzpcVXNlcnNcamtsZW1tYWNrXFNvdXJjZVxSZXBvc1xPQlJDX0JNU1xCTVMuV2ViLkJvdHRsZURyb3BDZW50ZXJzXEJNUy5XZWIuQm90dGxlRHJvcENlbnRlcnNcZm9ybXNcbmV3c2xldHRlcg==?=
x-powered-by: ASP.NET
access-control-allow-origin: *
date: Tue, 11 Jun 2019 16:28:34 GMT
content-length: 862
X-Firefox-Spdy: h2
The PreRequestFilters should now be fired for all Razor and Sharp Pages requests from the latest v5.5.1+ that's now available on MyGet.
In the meantime, I've created a portmanteau. For a particular sub-folder, I'm using web.config to allow all remote origins. For Service-based calls, I'm using a hand-rolled version of CorsFeature (a small amount of custom logic won't work).
<location path="views/subfolder"> <-- applies the ACAO header for specific view pages
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>

Azure CDN adding pragma:no-cache header

I've set up an Azure CDN using the Standard Akamai tier. My origin is a Web App. I've set up the cache-control header in my web.config as follows:
<clientCache cacheControlMode="UseMaxAge" cacheControlCustom="public" cacheControlMaxAge="30.00:00:00" />
In my markup, I'm hitting my image file with the following code:
<img src="https://xxxx.azureedge.net/Content/Images/Turtle.jpg?v=1.0.0.27987">
When I do so, I get the following response headers:
cache-control:public, max-age=2591903
content-length:2321435
content-type:image/jpeg
date:Mon, 03 Apr 2017 19:34:23 GMT
etag:"2e7a1f1690a9d21:0"
last-modified:Thu, 30 Mar 2017 19:59:05 GMT
pragma:no-cache
server:Microsoft-IIS/8.0 status:200 vary:Accept-Encoding x-powered-by:ASP.NET
Notice the pragma:no-cache. I have NO IDEA where that is coming from. This is definitely NOT in my origin's response to load the cache. If I hit the origin, I see the following headers sent for the same image:
Accept-Ranges:bytes
Cache-Control:public,max-age=2592000
Content-Length:2321435
Content-Type:image/jpeg
Date:Mon, 03 Apr 2017 19:41:50 GMT
ETag:"2e7a1f1690a9d21:0"
Last-Modified:Thu, 30 Mar 2017 19:59:05 GMT
Server:Microsoft-IIS/8.0
X-Powered-By:ASP.NET
This means that when hitting the CDN, instead of serving this image from http cache, it's sending the ETag and I'm wasting a HTTP roundtrip. I'm assuming that the culprit is the pragma:no-cache header that is sent, which is overriding the cache-control header. My questions are:
Why is the Azure CDN adding this pragma:no-cache header when serving my image?
Is the pragma:no-cache the reason we're seeing the 304/ETag validation instead of serving from http cache?
Thanks!
Edit: I've also tried removing the tag from the web.config. I'm still seeing an ETag transmitted for the image instead of serving it from the browser http cache.

WebViewProgressProxy violates Content Security Policy (CSP) rules

We started using Content Security Policy (CSP) on our website and I noticed that many users violates CSP rules through webviewprogressproxy URLs. In such cases I receive the following report from CSP:
{"csp-report":{
"document-uri":"http://example.com/en/booking/b2",
"referrer":"http://example.com/en/booking/b1/nnn",
"violated-directive":"default-src 'self'",
"original-policy":"default-src 'self'; font-src data: 'self'; img-src 'self' www.google-analytics.com data: s3.amazonaws.com; script-src 'self' www.google-analytics.com; report-uri /cspreport",
"blocked-uri":"webviewprogressproxy://",
"source-file":"http://example.com/en/booking/b2",
"line-number":1
}}
User-Agent:
Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B440 [FBAN/MessengerForiOS;FBAV/28.1.0.50.260;FBBV/10708012;FBDV/iPhone7,2;FBMD/iPhone;FBSN/iPhone OS;FBSV/8.1.2;FBSS/2; FBCR/giffgaff;FBID/phone;FBLC/en_US;FBOP/5]
As you can see, there is some URL with webviewprogressproxy protocol. However, we don't use this protocol and when we look at the User-Agent, it seems that some Facebook application on iOS causes this error, but I'm not sure about this.
Do anyone know what causes this kind of error and how we can avoid this?

Varnish 4 Cache does not cache dynamic page

It is possible cache of dynamic pages, especially the home page?
For plan to reduce access to the database .
I can do static file cache. perfect.
Response headers
Accept-Ranges:bytes
Age:0
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:keep-alive
Content-Type:text/html; charset=utf-8
Date:Tue, 09 Dec 2014 17:07:13 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Pragma:no-cache
Transfer-Encoding:chunked
Via:1.1 varnish-v4
x-Cache:uncached
X-Varnish:295421
File default vcl: http://notepad.cc/vaokodde9
Your backend is screamming it doesn't want anyone to cache the page:
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Pragma:no-cache
It's setting all the Cache-Control headers to disallow cache, it's setting an Expires header in the past (way back), and a Pragma: no-cache. You either have to fix the backend to send headers that allow caching, or if you are sure that you won't break anything start to workaround this headers in vcl.
I would choose the first option, and work the Cookies issue later.
I think Varnish by default does not cache pages with Cookies. Maybe that is your problem (it looks like you have a PHPSESSID and some other stuff)?
See the Varnish documentation: https://www.varnish-cache.org/trac/wiki/VCLExampleCacheCookies
Try configuring your webserver to not set any cookies, or configure Varnish to ignore them (note that that may not make sense, and break your website!)
Thank you all . I managed to solve the problem by studying a little about the functioning of the cookie in the varnish .

Resources