Skip to content

Commit

Permalink
Merge pull request #324 from gregcorbett/X.509
Browse files Browse the repository at this point in the history
Refer to X.509, not (x|X)509
  • Loading branch information
gregcorbett authored Aug 9, 2022
2 parents 843d2b0 + a3f02d7 commit f6d4a1b
Show file tree
Hide file tree
Showing 26 changed files with 160 additions and 285 deletions.
6 changes: 3 additions & 3 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This file is best viewed using a browser-plugin for markdown `.md` files.

* [Apache Http](#apache-and-x509-host-cert)
* Version 2.2 or higher with `mod_ssl` module
* X509 host certificate.
* X.509 host certificate.

* [Database server](#database-server)
* Oracle 11g+ or MariaDB/MySQL
Expand Down Expand Up @@ -108,7 +108,7 @@ update your php.ini by adding `extension=[php_]timezonedb.so|dll` (note, Win pre
* All dates are stored as UTC in the DB and converted from local timezones.
* Do not forget to configure your timezone settings correctly.

### Apache and x509 Host cert <a id="apache"></a>
### Apache and X.509 Host cert <a id="apache"></a>

A sample Apache config file is provided `config/gocdbssl.conf`. This file
defines a sample apache virtual host for serving your GocDB portal, including URL mappings/aliases and SSL settings.
Expand Down Expand Up @@ -557,7 +557,7 @@ and editing which URL page mappings use the `rejectIfNotAuthenticated()` invocat
### Authentication
Authentication is handled by the `lib/Authentication` package, and is configured
for x509 client certificate authentication by default. Different authentication
for X.509 client certificate authentication by default. Different authentication
schemes can be configured using the abstractions in this package such as SAML2
for integration with Federated Identity Management.
See `lib/Authentication/README.md` for details.
Expand Down
2 changes: 1 addition & 1 deletion config/gocdb_schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@
<field>
<fname>TYPE</fname>
<length>255</length>
<regex>/^(X509|OIDC Subject)$/</regex>
<regex>/^(X\.509|OIDC Subject)$/</regex>
</field>
<field>
<fname>ALLOW_WRITE</fname>
Expand Down
2 changes: 1 addition & 1 deletion htdocs/PI/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ function authByCert() {
// Check if it is registered API Authentication credential.

$authEntServ = \Factory::getAPIAuthenticationService();
$authEnt = $authEntServ->getAPIAuthentication($this->dn, "X509");
$authEnt = $authEntServ->getAPIAuthentication($this->dn, "X.509");

if (!is_null($authEnt)) {
$authEntServ->updateLastUseTime($authEnt);
Expand Down
8 changes: 4 additions & 4 deletions htdocs/PI/write/PIWriteRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public function __construct() {
* @param string $requestUrl url used to access API, only the last section
* @param string|null $requestContents contents of the request (JSON String or null)
* @param Site $siteService Site Service
* @param array ('userIdentifier'=><Identifier of user>,'userIdentifierType'=><Type of identifier e.g. X509>)
* @param array ('userIdentifier'=><Identifier of user>,'userIdentifierType'=><Type of identifier e.g. X.509>)
* @return array ('httpResponseCode'=><code>,'returnObject'=><object to return to user>)
*/
public function processRequest($method, $requestUrl, $requestContents, Site $siteService, $authArray) {
Expand Down Expand Up @@ -620,10 +620,10 @@ private function setAuthInfo($authArray) {
*/
private function checkUserAuthenticated () {
if (empty($this->userIdentifier)) {
#yes 403 - 401 is not appropriate for X509 authentication
#yes 403 - 401 is not appropriate for X.509 authentication
$this->exceptionWithResponseCode(403,
"You need to be authenticated to access this resource. " .
"Please provide a valid IGTF X509 Certificate"
"Please provide a valid IGTF X.509 Certificate"
);
}
}
Expand All @@ -632,7 +632,7 @@ private function checkAuthorisation (Site $siteService, \Site $site, $identifier
try {
$siteService->checkAuthorisedAPIIdentifier($site, $identifier, $indentifierType);
} catch (\Exception $e) {
#yes 403 - 401 is not appropriate for X509 authentication
#yes 403 - 401 is not appropriate for X.509 authentication
$this->httpResponseCode = 403;
throw $e;
}
Expand Down
2 changes: 1 addition & 1 deletion htdocs/PI/write/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function returnJsonWriteAPIResult ($httpResponseCode, $object) {
function getAuthenticationInfo () {
require_once __DIR__ . '/../../web_portal/components/Get_User_Principle.php';
#Check if associated cert/token is set to define identifier type
if(isset($_SERVER['SSL_CLIENT_CERT'])){$identifierType = 'X509';}
if(isset($_SERVER['SSL_CLIENT_CERT'])){$identifierType = 'X.509';}
if(isset($_SERVER['OIDC_access_token'])){$identifierType = 'OIDC Subject';}

#This will return null if no cert is presented
Expand Down
33 changes: 0 additions & 33 deletions htdocs/landing/authenticationError.html

This file was deleted.

79 changes: 3 additions & 76 deletions htdocs/web_portal/components/Get_User_Principle.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* File: Get_User_Principle.php
* Author: David Meredith
* Description: Returns the user's principle ID string or AuthToken for the user that's currently
* connected (for x509 this is a DN).
* connected (for X.509 this is a DN).
*
* License information
*
Expand Down Expand Up @@ -137,7 +137,7 @@ function Get_User_AuthType() {
}

/**
* Get the user's principle string (x509 DN from certificate or from SAML attribute).
* Get the user's principle string (X.509 DN from certificate or from SAML attribute).
* <p>
* Called from the portal to allow authentication.
* This method serves as the global integration point for all authentication requests.
Expand Down Expand Up @@ -204,7 +204,7 @@ function Get_User_Principle(){
}

/**
* Get the DN from an x509 cert, Principle from oidc token, or null if neither can be loaded.
* Get the DN from an X.509 cert, Principle from oidc token, or null if neither can be loaded.
* Called from the PI to authenticate requests using certificates or oidc.
* @return string or null if can't authenticate request
*/
Expand Down Expand Up @@ -243,77 +243,4 @@ function redirectUserToDiscoveryPage()
die();
}



/*function Get_User_Principle_back()
{
// Return hard wired user's principle string (DN) e.g. for testing
// =======================================================
//return '/C=UK/O=eScience/OU=CLRC/L=DL/CN=david meredith';
// Check if an authentication token has been set in the SecurityContext class
// by higher level code, eg Symfony Security which provides a Firewall component
// may have been used to intercept the HTTP request and authenticate the
// user (using whatever auth scheme was configured in the Firewall). A
// Symfony controller can then subsequently set the token in the SecurityContext
// before invoking the GOCDB code.
// =======================================================
require_once __DIR__.'/../../../lib/Gocdb_Services/SecurityContextSource.php';
if(\SecurityContextSource::getContext() != null){
$token = \SecurityContextSource::getContext()->getToken();
return str_replace("emailAddress=", "Email=", $token->getUser()->getUserName());
}
// ================Use x509 Authentication=======================
//if(!isset($_SERVER['SSL_CLIENT_CERT']))
// return "";
//$Raw_Client_Certificate = $_SERVER['SSL_CLIENT_CERT'];
//$Plain_Client_Cerfificate = openssl_x509_parse($Raw_Client_Certificate);
//$User_DN = $Plain_Client_Cerfificate['name'];
// harmonise display of the "email" field that can be different depending on
// used version of SSL
//$User_DN = str_replace("emailAddress=", "Email=", $User_DN);
//return $User_DN;
if (isset($_SERVER['SSL_CLIENT_CERT'])) {
$Raw_Client_Certificate = $_SERVER['SSL_CLIENT_CERT'];
if (isset($Raw_Client_Certificate)) {
$Plain_Client_Cerfificate = openssl_x509_parse($Raw_Client_Certificate);
$User_DN = $Plain_Client_Cerfificate['name'];
if (isset($User_DN)) {
// harmonise "email" field that can be different depending on version of SSL
$dn = str_replace("emailAddress=", "Email=", $User_DN);
if ($dn != null && $dn != '') {
return $dn;
}
}
}
}
// Fall back to try saml authentication (simplesaml)
// =======================================================
if(false){ // disable by default - to use saml requires install of simplesamlphp and config below
require_once('/var/simplesamlphp/lib/_autoload.php');
$as = new SimpleSAML_Auth_Simple('default-sp');
$as->requireAuth();
\Factory::$properties['LOGOUTURL'] = $as->getLogoutURL('https://gocdb-test.esc.rl.ac.uk');
$attributes = $as->getAttributes();
if(!empty($attributes)){
//return $attributes['eduPersonPrincipalName'][0];
$dnAttribute = $attributes['urn:oid:1.3.6.1.4.1.11433.2.2.1.9'][0];
if(!empty($dnAttribute)){
return str_replace("emailAddress=", "Email=", $dnAttribute);
} else {
die('Did not retrieve a valid certificate DN from identify provider - your SSO '
. 'account needs to be associated with a certificate to login via this route');
}
}
}
// Couldn't authetnicate the user, so finally return null
return null;
}*/



?>
2 changes: 1 addition & 1 deletion htdocs/web_portal/controllers/site/add_api_auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function draw(\User $user = null, \Site $site = null) {

$params['site'] = $site;
$params['authTypes'] = array();
$params['authTypes'][]='X509';
$params['authTypes'][]='X.509';
$params['authTypes'][]='OIDC Subject';
$params['user'] = $user;
$params['allowWrite'] = false;
Expand Down
2 changes: 1 addition & 1 deletion htdocs/web_portal/controllers/site/edit_api_auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function draw(\User $user = null, \APIAuthentication $authEnt = null, \Site $sit
$params['site'] = $site;
$params['authEnt'] = $authEnt;
$params['authTypes'] = array();
$params['authTypes'][]='X509';
$params['authTypes'][]='X.509';
$params['authTypes'][]='OIDC Subject';
$params['user'] = $user;

Expand Down
2 changes: 1 addition & 1 deletion lib/Authentication/AuthProviders/GOCDBAuthProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private function authenticateAgainstDB($auth){
// between the returned $userDetails object and the given $auth token.
// Note, getPassword() never returns null, even for auth mechanisms that
// don't use a password in which case an empty string is returned. This
// allows the same auth logic across different mechanisms (e.g. x509).
// allows the same auth logic across different mechanisms (e.g. X.509).
if($userDetails->getUsername() == $auth->getPrinciple() &&
$userDetails->getPassword() == $auth->getCredentials()){

Expand Down
13 changes: 4 additions & 9 deletions lib/Authentication/AuthTokens/X509AuthenticationToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//use Monolog\Handler\StreamHandler;

/**
* An implementation of <code>IAuthentication</code> for use with X509 certificates.
* An implementation of <code>IAuthentication</code> for use with X.509 certificates.
*
* @see IAuthentication
* @author David Meredith
Expand All @@ -21,10 +21,6 @@ class X509AuthenticationToken implements IAuthentication {
//private $logger;

public function __construct() {
// create logger
//$this->logger = new Logger('X509AuthenticationTokenLogger');
//$this->logger->pushHandler(new StreamHandler(__DIR__.'/../../../gocdb.log', Logger::DEBUG));

$this->initialDN = $this->getDN();
$this->userDetails = array('AuthenticationRealm' => array('X.509'));
}
Expand All @@ -45,18 +41,18 @@ public static function isPreAuthenticating() {

/**
* {@see IAuthentication::getCredentials()}
* @return string An empty string as passwords are not used in X509.
* @return string An empty string as passwords are not used in X.509.
*/
public function getCredentials() {
return "";
}

/**
* {@see IAuthentication::eraseCredentials()}
* Does nothing, passwords not ussed in X509.
* Does nothing, passwords not ussed in X.509.
*/
public function eraseCredentials() {
// do nothing, password not used for X509
// do nothing, password not used for X.509
}

/**
Expand Down Expand Up @@ -153,4 +149,3 @@ public function setAuthorities($authorities) {


}

8 changes: 4 additions & 4 deletions lib/Authentication/IAuthentication.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static function isStateless();
* resolution process for automatic submission to
* <code>AuthenticationManager.authenticate(Authentication)</code>.
* <p>
* X509 is an example of a pre-authentication token - the server establishes
* X.509 is an example of a pre-authentication token - the server establishes
* that the user has provided a valid and trustworthy certificate before
* reaching the underlying app (which means the token can be automatically
* created during token resolution and authenticated).
Expand All @@ -50,7 +50,7 @@ public static function isPreAuthenticating();
* The identity of the principal being authenticated.
* Note, this will vary according to differet authentication mechansisms.
* In the case of an authentication request (<code>IAuthenticationManager.authentication($authToken)</code>)
* with username and password, this would be the username. For X509
* with username and password, this would be the username. For X.509
* it would be the certificate DN. Callers are expected to populate the
* principal for an authentication request (<code>IAuthenticationManager.authentication($authToken)</code>).
* <p>
Expand All @@ -65,7 +65,7 @@ public function getPrinciple();

/**
* Get current principal's credentials (usually a password). Never null. When a password is not
* used for the chosen auth scheme (e.g. X509), return an empty string.
* used for the chosen auth scheme (e.g. X.509), return an empty string.
* @return object never null
*/
public function getCredentials();
Expand Down Expand Up @@ -113,7 +113,7 @@ public function setAuthorities($authorities);
* Implementations MUST throw an AuthenticationException if the token's internal state becomes
* invalid due to whatever change (required since instances are mutable).
* <p>
* For example, in the case of a cached x509 token, the client may freely change
* For example, in the case of a cached X.509 token, the client may freely change
* their certificate in their browser by clearing the browser ssl
* cache and refreshing the page. In this case, the DN may change from the
* initial DN used when constructing the token.
Expand Down
2 changes: 1 addition & 1 deletion lib/Authentication/IUserDetailsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface IUserDetailsService {
/**
* Locates the user based on the given username string.
* The username string must uniquely identify the user (its format can differ
* depending on the authentication mechanism e.g. could be a DN string for x509).
* depending on the authentication mechanism e.g. could be a DN string for X.509).
*
* @param string $username the user string identifying the user whose data is required.
* @return IUserDetails implementation (never <code>null</code>)
Expand Down
Loading

0 comments on commit f6d4a1b

Please sign in to comment.