WebStack

docs/login-redirect.html

732:7f1f02b485f8
2007-11-12 paulb [project @ 2007-11-12 00:50:03 by paulb] Introduced base classes for common authentication activities. Made cookie usage "safe" for usernames containing ":" characters. Added support for OpenID signatures.
     1 <?xml version="1.0" encoding="iso-8859-1"?>     2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">     3 <html xmlns="http://www.w3.org/1999/xhtml"><head>     4   <title>LoginRedirect and Login Modules</title>     5   <link href="styles.css" rel="stylesheet" type="text/css" /></head>     6 <body>     7 <h1>LoginRedirect and Login Modules</h1>     8 <p>The <code>LoginRedirect</code> and <code>Login</code> modules     9 provide a    10 "single sign-on" environment for WebStack applications. Unlike the    11 authenticator-only approach, each application or part of an application    12 utilising this mechanism must be wrapped inside a    13 <code>LoginRedirectResource</code> object which determines whether a    14 given    15 transaction contains information identifying the application's user.</p>    16 <h2>How the Modules Work</h2>    17 <p>When a request arrives in the application, the following things    18 happen:</p>    19 <ol>    20   <li>The <code>LoginRedirectResource</code> examines the transaction    21 and attempts to find out whether it identifies a user.</li>    22   <li>Should sufficient information be present in the transaction, the    23 user is allowed to access the application and is identified in the    24 normal way (ie. the <code>get_user</code> method on the transaction    25 object).</li>    26   <li>Otherwise, a redirect occurs to a login screen provided by a <code>LoginResource</code>    27 object which then presents a login form to be completed by the user.</li>    28   <li>The <code>LoginResource</code> object then receives the    29 completed form information and verifies the identity of the user,    30 testing the supplied credentials against the credentials database    31 specified in the deployment of the resource.</li>    32   <li>Upon successful authentication, the user is redirected back to    33 the application, guarded by <code>LoginRedirectResource</code> which    34 should let the user gain access.</li>    35 </ol>    36 <h2>Introducing LoginRedirectResource</h2>    37 <p>The easiest way of introducing <code>LoginRedirectResource</code>    38 objects    39 is to do so in the adapter code, as described in <a href="writing-adapters.html">"Writing Adapters"</a>. The most    40 significant    41 difference between deploying normal resources and    42 <code>LoginRedirectResource</code> objects is the special way in which    43 such    44 objects are initialised and that they themselves contain the actual    45 resources    46 of the application which provide the real functionality.</p>    47 <p>Here is what the deployment of <code>LoginRedirectResource</code>    48 objects    49 often looks like:</p>    50 <pre>from WebStack.Resources.LoginRedirect import LoginRedirectResource, LoginRedirectAuthenticator<br /><br />deploy(<br />    LoginRedirectResource(<br />        login_url="http://localhost:8081",<br />        app_url="http://localhost:8080",<br />        resource=[some resource object which provides the real application behaviour],<br />        authenticator=LoginRedirectAuthenticator(secret_key="horses"),<br />        anonymous_parameter_name="anonymous",<br />        logout_parameter_name="logout"<br />    )<br />)</pre>    51 <p>Certain parts of the resource are configurable, according to which    52 other    53 services may exist in or alongside the deployed application.</p>    54 <div class="WebStack">    55 <h3>WebStack API - LoginRedirectResource Initialisation</h3>    56 <p>The following parameters must be provided when initialising a    57 <code>LoginRedirectResource</code> object:</p>    58 <dl>    59   <dt><code>login_url</code></dt>    60   <dd>This specifies the location of the separate login application or    61 resource which presents a login screen to unidentified users and logs    62 them in.</dd>    63   <dt><code>app_url</code></dt>    64   <dd>This specifies the location of the application itself - it must    65 therefore be updated according to where the application is eventually    66 deployed.</dd>    67   <dt><code>resource</code></dt>    68   <dd>This provides the resource object which contains the application    69 code, or at least the entry point into various parts of the application    70 code.</dd>    71   <dt><code>authenticator</code></dt>    72   <dd>This provides the authenticator object which decides whether a    73 user is recognised or not. The special <code>LoginRedirectAuthenticator</code>    74 is recommended and must itself be configured using a <code>secret_key</code>    75 parameter which is used to protect user-related information exchanged    76 over the network - the value provided for <code>secret_key</code> must    77 be unguessable and kept secret from unauthorised individuals.</dd>    78   <dt><code>anonymous_parameter_name</code></dt>    79   <dd>An optional parameter providing the name of a request parameter    80 (see <a href="parameters.html">"Request Parameters and Uploads"</a>)    81 which, if specified, permits a user to access an application without    82 being formally identified. If omitted, all users will be required to    83 identify themselves explicitly.</dd>    84   <dt><code>anonymous_username</code></dt>    85   <dd>An optional parameter providing the name given to anonymous users    86 which is returned when a transaction's <code>get_user</code> method is    87 called. By default, <code>anonymous</code> is used for such users.</dd>    88   <dt><code>logout_parameter_name</code></dt>    89   <dd>An optional parameter providing the name of a request parameter    90 which, if specified, permits a user to log out of an application. If    91 omitted, no means of logging out will be available, although deleting    92 browser cookies will probably have the desired effect.</dd>    93   <dt><code>logout_url</code></dt>    94   <dd>An optional parameter which indicates the location of the    95 resource visited when a user logs out. By default, the location is a    96 path to the root resource in the server environment of the application.</dd>    97   <dt><code>use_logout_redirect</code></dt>    98   <dd>An optional parameter which determines whether users logging out    99 of an application will be redirected to the <code>logout_url</code> or   100 not. By default, users are redirected, but if a false value is given   101 for this parameter, a simple page is presented to the user informing   102 them of the situation - it is recommended that a subclass of <code>LoginRedirectResource</code>   103 be employed should more informative pages be required.</dd><dt><code>path_encoding</code></dt><dd>An   104 optional parameter indicating the character encoding used to generate   105 (and, in other places, to interpret) URL-encoded character values in   106 URLs and paths.</dd>   107 </dl><p>See the <a href="../apidocs/public/WebStack.Resources.LoginRedirect.LoginRedirectResource-class.html">API documentation</a> for the <code>LoginRedirectResource</code> class for more details.</p>   108 </div>   109 <h3>Redirection from/to the Application</h3>   110 <p>Some server/framework environments do not permit automatic   111 redirection   112 back to the application, notably Apache/mod_python. In such cases, a   113 success   114 screen is presented to the user with a link to the application they   115 were   116 attempting to access.</p>   117 <h3>The Role of Authenticators</h3>   118 <p>In this mechanism, authenticators are employed, but only to verify   119 the   120 credentials of users when <code>LoginResource</code> or   121 <code>LoginRedirectResource</code> objects are accessed. Although it   122 should   123 be possible to reuse <a href="authenticators.html">application-wide   124 authenticator</a> classes in conjunction with <code>LoginResource</code>,   125 such classes will not provide the additional functionality required to   126 support the "single sign-on" aspects of this mechanism - mixing in such   127 classes with <code>LoginAuthenticator</code> may provide a solution to   128 this   129 issue, however.</p><h2>Extending LoginRedirectResource</h2><p>Sometimes, using <code>LoginRedirectResource</code> directly is not appropriate in an application. For example, specifying the <code>app_url</code> and <code>login_url</code> as absolute URLs (so that <code>LoginRedirectResource</code> can   130 redirect users into the application and over to the login screen) may   131 seem like excessive detail which will need to be changed if the   132 application is deployed even in a slightly different location. We might   133 therefore wish to use a <code>PathSelector</code> resource (see <a href="attributes.html">"Transaction Attributes"</a> and <a href="selectors.html">"Selectors"</a>) to record the "root path" into an application and then to employ a login URL which is relative to the "root path".</p><p>To achieve this,  <code>LoginRedirectResource</code> provides methods which can be overridden - <code>get_app_url</code> and <code>get_login_url</code> - and we might define a subclass of  <code>LoginRedirectResource</code> as follows:</p><pre>class MyLoginRedirectResource(LoginRedirectResource):<br /><br />    "An example of customising LoginRedirectResource."<br /><br />    def get_login_url(self, trans):<br /><br />        "Use a different login URL, using 'trans' to find out what it might be."<br /><br />        # Find out what the PathSelector stored for the root of the application.<br /><br />        root_path = trans.get_attributes()["root"]<br /><br />        # Return the value of the login_url attribute appended to the root path.<br /><br />        return root_path + self.login_url</pre><p>Since <code>LoginRedirectResource</code> calls the <code>get_login_url</code> method when forming the URL to redirect to the login resource, by overriding the original method from the <code>LoginRedirectResource</code> class we can define different behaviour. Of course, to take advantage of this new behaviour, we must instantiate <code>MyLoginRedirectResource</code> instead of <code>LoginRedirectResource</code> when setting up the application.</p>   134 <h2>Deploying a Login Application</h2>   135 <p>In order for this authentication mechanism to function in its   136 entirety, a   137 login application (or resource) must be available to authenticate   138 unidentified users. It may already be the case that such an application   139 has   140 been deployed and is available at a certain URL - if so, it should be   141 sufficient for a <code>LoginRedirectResource</code> object to be   142 configured   143 as described above, making sure that the <code>login_url</code>   144 actually   145 refers to the location of the existing login application, and that the   146 <code>authenticator</code> object's <code>secret_key</code> is   147 consistent   148 with the way the existing login application has been set up.</p>   149 <p>However, if no existing login application (or resource) exists, one   150 may be   151 deployed using adapter code similar to the following:</p>   152 <pre>from WebStack.Adapters.BaseHTTPRequestHandler import deploy<br />from WebStack.Resources.Login import LoginResource, LoginAuthenticator<br /><br />deploy(<br />    LoginResource(                   # This is the login application's main resource.<br />        LoginAuthenticator(          # This provides authentication support.<br />            secret_key="horses",<br />            credentials=(<br />                ("badger", "abc"),<br />                ("vole", "xyz"),<br />            )<br />        )<br />    ),<br />    address=("", 8081)<br />)</pre>   153 <p>The above code merely starts a login application in the   154 BaseHTTPRequestHandler environment at a specific address (which   155 corresponds   156 to that specified in the <code>login_url</code> of the   157 <code>LoginRedirectResource</code> used above) and provides a   158 <code>LoginAuthenticator</code> object configured to use a   159 <code>secret_key</code> (which corresponds to the <code>secret_key</code>   160 used in the <code>authenticator</code> of the   161 <code>LoginRedirectResource</code> above) and some user credentials.   162 The user   163 credentials define which users are to be recognised for applications   164 which   165 employ this login application, along with the password details of each   166 user.</p>   167 <div class="WebStack">   168 <h3>WebStack API - LoginAuthenticator Credentials</h3>   169 <p>When initialising a <code>LoginAuthenticator</code> object with   170 credentials, the supplied credentials object must support tests on its   171 contents of the following form:</p>   172 <pre>(username, password) in credentials</pre>   173 <p>In other words, the credentials object must either be a sequence of   174 username and password tuples, or it must implement the   175 <code>__contains__</code> method and accept such tuples as arguments to   176 that   177 method.</p>   178 </div>   179 <h2>Anonymous Access</h2>   180 <p>With the <code>LoginRedirect</code> and <code>Login</code>   181 modules, it is   182 possible to declare a particular request parameter (see   183 <code>anonymous_parameter_name</code> above) which must be present in   184 the URL   185 used to access a particular application for the client to be given   186 anonymous   187 access. Consequently, anonymous users are then identified specially   188 with a   189 special username that can also be configured (see   190 <code>anonymous_username</code> above).</p>   191 <h2>Logout Functions</h2>   192 <p>With the <code>LoginRedirect</code> and <code>Login</code>   193 modules, it is   194 possible to declare a particular request parameter (see   195 <code>logout_parameter_name</code> above) which must be present in the   196 URL   197 used to access a particular application for the client to be logged   198 out. A   199 special logout confirmation URL may also be configured (see   200 <code>logout_url</code> and <code>use_logout_redirect</code> above).</p>   201 </body></html>