CORS Behind Kerberos

Recently had a frustrating issue dealing with CORS when interacting with an API behind an authenticated Kerberos setup. Attempts to contact the API presented the following error:-

XMLHttpRequest cannot load http://dev:8080/api/v1/ Invalid HTTP status code 401

According to the spec the authentication header is not issued on preflight requests. Specifically:-

Otherwise, make a preflight request. Fetch the request URL from origin source origin using referrer source as override referrer source with the manual redirect flag and the block cookies flag set, using the method OPTIONS, and with the following additional constraints:

Include an Access-Control-Request-Method header with as header field value the request method (even when that is a simple method).

If author request headers is not empty include an Access-Control-Request-Headers header with as header field value a comma-separated list of the header field names from author request headers in lexicographical order, each converted to ASCII lowercase (even when one or more are a simple header).

Exclude the author request headers.

Exclude user credentials.

Exclude the request entity body.

This has the effect of the server issuing a 401 and the browser blocking the request immediately.

The solution requires explicitly disabling authentication for the preflight OPTIONS request, in this instance Kerberos.

In the .htaccess file for the project this meant adding:-

<LimitExcept OPTIONS>
  Require valid-user
</LimitExcept>

This allowed the preflight to continue and any subsequent GET or POST to the service.

After this was sorted, the next issue was the origin headers needing changed to sort this error:-

XMLHttpRequest cannot load https://dev:8080/api/v1/. A wildcard ‘*’ cannot be used in the ‘Access-Control-Allow-Origin’ header when the credentials flag is true. Origin ‘http://localhost:8080’ is therefore not allowed access

This involved changing the Access-Control-Allow-Origin header from a wildcard to the specific origin accessing the resource:-

$response->headers->set('Access-Control-Allow-Origin', $request->headers->get('Origin'));
$response->headers->set('Access-Control-Allow-Credentials', 'true');

Any client side code needs changed to explicitly pass credentials when dealing with the protected service. E.g. jQuery:-

$.ajax({
  url: "https://dev:8080/api/v1",
  dataType: 'json',
  type: 'GET',
  xhrFields: {
    'withCredentials': true
  },
  crossDomain: true
}).success(function(data) {
  console.log(data)
}).error(function(xhr, status, error) {
  console.log(xhr);
});

Or Angular:-

app.config(function ($httpProvider) {
  $httpProvider.defaults.withCredentials = true; //Tell browser to provide credentials
  $httpProvider.defaults.useXDomain = true; //Take CORS measures
});

Other resources discussing this matter.

gulp-phpcbf

Like gulp-phpcs in your pipeline but want it to fix your errors too? Meet gulp-phpcbf!

var gulp = require('gulp');
var phpcbf = require('gulp-phpcbf');
var gutil = require('gutil');

gulp.task('phpcbf', function () {
  return gulp.src(['src/**/*.php', '!src/vendor/**/*.*'])
  .pipe(phpcbf({
    bin: 'phpcbf',
    standard: 'PSR2',
    warningSeverity: 0
  }))
  .on('error', gutil.log)
  .pipe(gulp.dest('src'));
});

Cops and Criminals

From your body wasn’t built to last: a lesson from human mortality rates

Unfortunately, the full complexity of human biology does not lend itself readily to cartoons about cops and criminals. There are a lot of difficult questions for anyone who tries to put together a serious theory of human aging. Who are the criminals and who are the cops that kill them? What is the “incubation time” for a criminal, and why does it give “him” enough strength to fight off the immune response? Why is the police force dwindling over time? For that matter, what kind of “clock” does your body have that measures time at all?

DevOps

From what is this Devops thing anyway?

On most projects I’ve worked on, the project team is split into developers, testers, release managers and sysadmins working in separate silos. From a process perspective this is dreadfully wasteful. It can also lead to a ‘lob it over the wall’ philosophy - problems are passed between business analysts, developers, QA specialists and sysadmins. Furthermore, we see a replication of this silo structure within the teams - it’s not uncommon to see dedicated database and network people in the same system team, alongside sysadmins. Often the larger silos aren’t in the same office, the same city, or in sometimes not even in the same country. The result is an ‘us and them’ mentality - groups of people who are simultaneously suspicious of and afraid of each other.