A digression

44
A digression • The next feature of programming HTTP clients that we will consider is user authentication • Before considering that, however, we will digress to consider a commonly-used user authentication technique

description

A digression. The next feature of programming HTTP clients that we will consider is user authentication Before considering that, however, we will digress to consider a commonly-used user authentication technique. Basic HTTP Authentication. Before giving a document to a client, - PowerPoint PPT Presentation

Transcript of A digression

Page 1: A digression

A digression

• The next feature of programming HTTP clients that we will consider is user authentication

• Before considering that, however, we will digress to consider a commonly-used user authentication technique

Page 2: A digression

Basic HTTP Authentication • Before giving a document to a client,

– a HTTP server looks for access-control files in every directory of the path to the document

– if it finds one, it only serves the document to the client if the client can prove entitlement

• By default, the access-control files are called .htaccess

• But, in Apache-style servers at least, a list of names for such files can be specified using the AccessFileName directive when configuring the server

(See http://httpd.apache.org/docs/1.3/mod/core.html#accessfilename )

Page 3: A digression

Basic HTTP Authentication (contd.) • To use Basic HTTP Authentication to control access to a directory

and its sub-directories,– create, in the directory, a file with one of the names specified in

the AccessFileName directive• normally, this means a file called .htaccess

– At its simplest, the contents of the file will look like this:AuthName "Some string to name this restricted area"

AuthType Basic

AuthUserFile path/to/some/password/file

require user valid-user

• This specifies • that only a client which can identify itself according to the password

file should be given access to this directory and its contents

• a name for the restricted area of the disk -- this name will be given to the client trying to access any file in this part of the disk, to help remind it of the right name+password to use

Page 4: A digression

Basic HTTP Authentication (contd.) • Suppose I want to protect all contents of the directory

http://www.cs.ucc.ie/j.bowen/cs4408/resources/demosecure/

• I could place in that directory a .htaccess file containing:AuthName "This info is restricted to CS 4408 students"

AuthType Basic

AuthUserFile /www/docs/j.bowen/cs4408/resources/.htpasswd

require user valid-user

• Then I would use the htpasswd utility provided by Apache to insert names+passwords for all eligible people into a file called .htpasswd in the parent resources directory

• Any person trying to use a browser to access this directory would receive this challenge window:

Page 5: A digression

Basic HTTP Authentication (contd.)

• If the user fails to provide acceptable authentication,

he/she would receive the screen shown on the bottom right

Page 6: A digression

Using MSIE to try to get a document from this directory

• Suppose we put a copy of showRequest2.php in this directory

• Suppose we try to use Microsoft Internet Explorer to try to read the output from showRequest2.php

• Suppose we fail to provide the correct password• We get the page shown below

Page 7: A digression

A "home-made browser" which attempts to get the same output

• Now suppose this "home-made" browser tries to read the same file

http://cosmos.ucc.ie/~jabowen/cs4408/myBrowser6.php <?php

require_once "HTTP/Request.php";

$req = &new HTTP_Request("http://www.cs.ucc.ie/j.bowen/cs4408/resources/demosecure/showRequest2.php");

if (!PEAR::isError($req->sendRequest()))

{ echo "<br><strong style='color:red'>Headers</strong>";

$headers = $req->getResponseHeader();

foreach ($headers as $name => $value) { echo "<br> $name = $value"; }

echo "<br><strong style='color:red'>Cookies</strong><br>";

$cookies = $req->getResponseCookies();

foreach ($cookies as $fields)

{ foreach ($fields as $name => $value) { echo "$name = $value; "; }echo "<br>"; }

$contents= $req->getResponseBody();

echo "<br><strong style='color:red'>Body</strong><br>";

echo $contents;

}?>

Page 8: A digression

Results of running this "browser"

• The response contains a WWW-Authenticate header, which specifies that Basic authentication is in force for this disk area, a "realm" called "This info is restricted to CS 4408 students"

• The message body contains the HTML page that we got when we tried to use Microsoft Internet Explorer

Page 9: A digression

A "browser" which provides authentication for this realm

• At http://cosmos.ucc.ie/~jabowen/cs4408/myBrowser7.php<?php

require_once "HTTP/Request.php";

$req = &new HTTP_Request("http://www.cs.ucc.ie/j.bowen/cs4408/resources/demosecure/showRequest2.php");

$req->setBasicAuth("peadar", "foo");if (!PEAR::isError($req->sendRequest()))

{ echo "<br><strong style='color:red'>Headers</strong>";

$headers = $req->getResponseHeader();

foreach ($headers as $name => $value) { echo "<br> $name = $value"; }

echo "<br><strong style='color:red'>Cookies</strong><br>";

$cookies = $req->getResponseCookies();

foreach ($cookies as $fields)

{ foreach ($fields as $name => $value) { echo "$name = $value; "; }echo "<br>"; }

$contents= $req->getResponseBody();

echo "<br><strong style='color:red'>Body</strong><br>";

echo $contents;

}?>

Page 10: A digression

Results of running this "browser"

• Request is accepted -- user+password are in SERVER vars

$PHP_AUTH_USER, $PHP_AUTH_PW which we saw, last year, when we did server-side user-authentication in a PHP program

Page 11: A digression

Another Approach to authentication

• Instead of depending on the server demon to defend directories, we can– make our own programs defend themselves

on a program-by-program basis

Page 12: A digression

PHP-based handling of passwords on both client-side and server-side

• We have just seen how to program a client to send a user+password

• Last year, we saw how to write a server-side PHP program which demanded that the client authenticate itself

• Let's revise that and see how we can use PHP for both sides of the authentication process

Page 13: A digression

Server-side User-authentication in PHP

• A server-side program can use the header() function to send headers requiring authentication

– This will cause a browser to pop up a username/password/realm dialog window and

– When the values have been provided by the user, the browser will send a new request back to the same page containing the appropriate information

– When ther, some special PHP variables will be set:

$PHP_AUTH_USER or $_SERVER["PHP_AUTH_USER"]

$PHP_AUTH_PW or $_SERVER["PHP_AUTH_PW"]

Page 14: A digression

User-authentication in PHP (contd.)

• Consider the following program which is here:

http://www.cs.ucc.ie/j.bowen/cs4408/resources/securePage.php

<?php

if ( ($_SERVER["PHP_AUTH_USER"]=='pedro') &&

($_SERVER["PHP_AUTH_PW"]=='qwerty') )

{ echo "<h1>Welcome</h1>"; }

else

{header("HTTP/1.0 401 Unauthorized");

header("WWW-Authenticate: Basic realm=BankAccounts");

echo "<h1>You must identify yourself</h1>";

echo "<p>Please provide a correct user+password</p>";

}

?>

Page 15: A digression

cs 4408 got here on 14 nov 2005

Page 16: A digression

Accessing this program through a normal browser

• When first called by the browser, no user name or password is provided

• When the WWW-Authenticate header is received by the browser, it asks the user for a username+password

• If he gets it right, he is welcomed

• Otherwise, he is told to that he must identify himself as a user who is entitled to visit the page

Page 17: A digression

A "browser" which provides wrong details for this realm

• At http://cosmos.ucc.ie/~jabowen/cs4408/myBrowser8.php<?php

require_once "HTTP/Request.php";$req = &new HTTP_Request("http://www.cs.ucc.ie/j.bowen/cs4408/resources/securePage.php");

$req->setBasicAuth("peader", "foo");

if (!PEAR::isError($req->sendRequest()))

{echo "<br><strong style='color:red'>Headers</strong>";

$headers = $req->getResponseHeader();

foreach ($headers as $name => $value)

{ echo "<br> $name = $value"; }

echo "<br><strong style='color:red'>Cookies</strong><br>";

$cookies = $req->getResponseCookies();

foreach ($cookies as $fields)

{ foreach ($fields as $name => $value) { echo "$name = $value; "; } echo "<br>"; }

$contents= $req->getResponseBody();

echo "<br><strong style='color:red'>Body</strong><br>";

echo $contents;

}?>

Page 18: A digression

Results of running this "browser"

• Request is rejected because of wrong username and password

Page 19: A digression

A "browser" which provides correct details for this realm

• At http://cosmos.ucc.ie/~jabowen/cs4408/myBrowser9.php<?php

require_once "HTTP/Request.php";$req = &new HTTP_Request("http://www.cs.ucc.ie/j.bowen/cs4408/resources/securePage.php");

$req->setBasicAuth("pedro", "qwerty");

if (!PEAR::isError($req->sendRequest()))

{echo "<br><strong style='color:red'>Headers</strong>";

$headers = $req->getResponseHeader();

foreach ($headers as $name => $value)

{ echo "<br> $name = $value"; }

echo "<br><strong style='color:red'>Cookies</strong><br>";

$cookies = $req->getResponseCookies();

foreach ($cookies as $fields)

{ foreach ($fields as $name => $value) { echo "$name = $value; "; } echo "<br>"; }

$contents= $req->getResponseBody();

echo "<br><strong style='color:red'>Body</strong><br>";

echo $contents;

}?>

Page 20: A digression

Results of running this "browser"

• Request is accepted

Page 21: A digression

User-authentication in PHP (contd.)

• Remember that you cannot mix self-provision of user authentication with external user authentication

• The PHP_AUTH variables will not be set if external authentication is also enabled for a directory which contains a PHP program that is trying to do self-provision of user authentication

– This is to avoid trhe possibility that a script might reveals the password for a page that was protected through a traditional external mechanism, such as the .htaccess mechanism

Page 22: A digression

Using proxies

• HTTP supports both direct and indirect connections between servers and clients

• Indirect connections transmit the request/response messages through one or more proxies

Page 23: A digression

Using proxies (contd.)

• This program, at http://cosmos.ucc.ie/~jabowen/cs4408/myBrowser201.php

uses a direct connection to the RTE server:<?php

require_once "HTTP/Request.php";

$req = & new HTTP_Request('http://www.rte.ie/');

if (!PEAR::isError($req->sendRequest()))

{ $contents= $req->getResponseBody();

echo $contents;}

?>

Page 24: A digression

Output from running this program

Page 25: A digression

Using proxies (contd.)

• This program, at http://cosmos.ucc.ie/~jabowen/cs4408/myBrowser202.php

asks a proxy server to pass its request to the RTE server:

<?php

require_once "HTTP/Request.php";

$req = & new HTTP_Request('http://www.rte.ie/');

$req->setProxy("csproxy.ucc.ie", 80);

if (!PEAR::isError($req->sendRequest()))

{ $contents= $req->getResponseBody();

echo $contents;}

?>

Page 26: A digression

Output from running this program

Page 27: A digression

Uploading files

• Last year, we saw how to write PHP programs which would accept files being uploaded from a browser

• We will review that material before going on to see how we can write our own clients to upload files to servers

Page 28: A digression

File upload form<html><head><title>Upload a File</title></head><body><h1>Upload a File</h1>

<form enctype="multipart/form-data" method="post" action="uploadFile.php">

<p>File to Upload:<input type="file" name=“file1" size="30"></p>

<p><button input type="submit“> "Upload File“</button></p>

</form></body></html>

Page 29: A digression

File upload script<html><head><title>File Upload Report</title></head><body><h1>File Upload Report</h1><p><?phpif ( $file1_name != ‘’ ) { copy("$file1 ", "/full/path/to/your/target/directory/$file1_name") or die(“Could not copy the file! Are directory permissions correct? </p></body></html>");

echo “The following file has been received: “; echo “$file1_name containing $file1_size bytes and of MIME type $file1_type"; } else { die(“You did not specify an input file </p></body></html> "); } ?></p></body></html>

Page 30: A digression
Page 31: A digression
Page 32: A digression
Page 33: A digression

Newer convention

• Newer versions of PHP store all the uploaded file information in the $_FILES autoglobal array.

• $_FILES['userfile']['name'] – The original name of the file on the client machine.

• $_FILES['userfile']['type'] – The mime type of the file, if the browser provided this

information. An example would be `"image/gif"`. • $_FILES['userfile']['size']

– The size, in bytes, of the uploaded file. • $_FILES['userfile']['tmp_name']

– The temporary filename of the file in which the uploaded file was stored on the server.

Page 34: A digression

Part 1 of newer version of program• Program available at:

http://www.cs.ucc.ie/j.bowen/cs4408/resources/fileUploader.php

• It will only work if it has write permission for directory /www/docs/j.bowen/cs4408/resources/upload/

<html>

<head><title>File uploader</title></head>

<body>

<?php

if (!$_POST["uploadingFile"])

{ ?><h1>Upload a File</h1>

<form enctype="multipart/form-data" method="post" action="fileUploader.php">

<p>File to Upload:

<input type="file" name="file1" size="30"></p>

<input type="hidden" name="uploadingFile" value="1">

<p><button input type="submit">Upload File</button></p>

</form>

<?php

}

Page 35: A digression

Part 2 of newer version of program

else {?> <h1>File Upload Report</h1><p>

<?php $file1_name=$_FILES["file1"]["name"];

$file1_type=$_FILES["file1"]["type"];

$file1_size=$_FILES["file1"]["size"];

$file1=$_FILES["file1"]["tmp_name"];

if ( $file1_name != "" ) { $uploadDirectory = '/www/docs/j.bowen/cs4408/resources/upload/';

$destinationFile= $uploadDirectory.$file1_name;

move_uploaded_file($file1, $destinationFile) or die("Could not copy the file! Are directory permissions correct?");

?>The following file has been received: <?php echo $file1_name; ?> containing <?php echo $file1_size; ?>

bytes and of MIME type <?php echo $file1_type; ?><?php

}

else { die("You did not specify an input file </p>"); } ?>

<?php } ?>

</p></body></html>

Page 36: A digression

Program in use with a MSIE browser

Page 37: A digression

Program in use with a MSIE browser

Page 38: A digression

Program in use with a MSIE browser

Page 39: A digression

Program in use with a MSIE browser

Page 40: A digression

Program in use with a MSIE browser

Page 41: A digression

Program in use with a MSIE browser

Page 42: A digression

A client which uploads a file to the same program • Suppose we want to write our own client which will upload a file to

this program:

http://www.cs.ucc.ie/j.bowen/cs4408/resources/fileUploader.php

• Remember that the program fileUploader.php expects to receive data from a form on which there are the following input boxes:

<input type="file" name="file1" size="30">

<input type="hidden" name="uploadingFile" value="1">

• Our client must send a request which contains data that looks as if it comes from these two inputs

• That it, it must send, as POST data, the equationuploadingFile=1

• and it must send a file as it it were sent from a file input called file1

Page 43: A digression

A client which uploads a file to the same program • This client is available here

http://cosmos.ucc.ie/~jabowen/cs4408/myBrowser10.php

• It uploads a file called courses.txt from a sub-directory, called demoDir, of the directory which contains the client program itself

<?php

require_once "HTTP/Request.php";

$req =& new HTTP_Request("http://www.cs.ucc.ie/j.bowen/cs4408/resources/fileUploader.php");

$req->setMethod(HTTP_REQUEST_METHOD_POST);

$req->addPostData("uploadingFile", "1");

$result = $req->addFile("file1", "demoDir/courses.txt");

if (!PEAR::isError($result))

{ $response = $req->sendRequest();

if (!PEAR::isError($response)) { echo $req->getResponseBody(); }

} ?>

Page 44: A digression

Result of running this client