Skip to content

Instantly share code, notes, and snippets.

@avar
Last active December 12, 2015 10:28
Show Gist options
  • Save avar/4758806 to your computer and use it in GitHub Desktop.
Save avar/4758806 to your computer and use it in GitHub Desktop.
An example of a C# request to a Plack app with Auth::Basic middleware

Demonstrates C# authentication against a Plack server. Example challenge-response captured with tcpflow:

005.009.157.150.41257-005.009.157.150.03000: GET / HTTP/1.1
Connection: keep-alive
Host: u.nix.is:3000

005.009.157.150.03000-005.009.157.150.41257: HTTP/1.0 401 Unauthorized
Date: Mon, 11 Feb 2013 23:58:20 GMT
Server: HTTP::Server::PSGI
Content-Type: text/plain
Content-Length: 22
WWW-Authenticate: Basic realm="XML Test"

005.009.157.150.03000-005.009.157.150.41257: Authorization required
005.009.157.150.41258-005.009.157.150.03000: GET / HTTP/1.0
Authorization: Basic dGhlIHhtbCB1c2VyOnNvbWUgcGFzcyB3b3Jk
Connection: keep-alive
Host: u.nix.is:3000

005.009.157.150.03000-005.009.157.150.41258: HTTP/1.0 200 OK
Date: Mon, 11 Feb 2013 23:58:20 GMT
Server: HTTP::Server::PSGI
Content-Type: text/xml
Content-Length: 69

005.009.157.150.03000-005.009.157.150.41258: <xml>Hello user 'the xml user', you made it past authentication</xml>

From this example request:

$ gmcs request.cs && mono request.exe
STATUS = OK
CONTENT = [[<xml>Hello user 'the xml user', you made it past authentication</xml>]]

Which yields these accesslog entries:

5.9.157.150 - - [12/Feb/2013:00:02:11 +0000] "GET / HTTP/1.1" 401 22 "-" "-"
(the xml user, some pass word)
5.9.157.150 - the xml user [12/Feb/2013:00:02:11 +0000] "GET / HTTP/1.0" 200 69 "-" "-"
using System;
using System.IO;
using System.Net;
using System.Text;
public class HelloWorld
{
static public void Main ()
{
// Create a new webrequest to the mentioned URL.
var uri = new Uri("http://u.nix.is:3000/");
var myWebRequest = (HttpWebRequest)WebRequest.Create(uri);
myWebRequest.PreAuthenticate=false;
var networkCredential=new NetworkCredential("the xml user", "some pass word");
myWebRequest.Credentials=networkCredential;
var myWebResponse = (HttpWebResponse)myWebRequest.GetResponse();
Console.Out.WriteLine("STATUS = " + myWebResponse.StatusCode);
var stream = myWebResponse.GetResponseStream();
var reader = new StreamReader(stream);
string text_read = reader.ReadToEnd();
Console.Out.WriteLine("CONTENT = [[" + text_read + "]]");
reader.Close();
stream.Close();
myWebResponse.Close();
}
}
#!/usr/bin/env perl
use strict;
use warnings;
use Plack;
use MIME::Base64;
my $app = sub {
my $env = shift;
my $auth = $env->{HTTP_AUTHORIZATION}
or return unauthorized();
# note the 'i' on the regex, as, accoring to RFC2617 this is a
# "case-insensitive token to identify the authentication scheme"
if ($auth =~ /^Basic (.*)$/i) {
my($user, $pass) = split /:/, (MIME::Base64::decode($1) || ":"), 2;
$pass = '' unless defined $pass;
if (authenticator($user, $pass, $env)) {
$env->{REMOTE_USER} = $user;
return [
200,
[ 'Content-Type' => 'text/xml' ],
[ "<xml>Hello user '$env->{REMOTE_USER}', you made it past authentication</xml>" ]
];
}
}
return unauthorized();
};
sub unauthorized {
my $body = 'Authorization required';
return [
401,
[ 'Content-Type' => 'text/plain',
'Content-Length' => length $body,
'WWW-Authenticate' => 'Basic realm="XML Test"' ],
[ $body ],
];
}
sub authenticator {
my ($username, $password) = @_;
print STDERR "Authenticating With: ($username, $password)\n";
return unless defined $username && defined $password;
return $username =~ /xml/ && $password =~ /pass/;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment