Der vorerst letzte Eintrag in der bliebten Reihe “wir sichern alles mögliche mit MultiOTP” 😀

RDWeb landet nach der Installation in C:\Windows\Web\RDWeb. Die Datei die uns interessiert befindet sich im Unterverzeichnis Pages und da im Verzeichnis der gewĂŒnschten Sprache: login.aspx.

Oben bei den @Import Zeilen fĂŒgen wir ein

<% @Import Namespace="System.Diagnostics" %>
<% @Import Namespace="System.Text.RegularExpressions" %>
<% @Import Namespace="System.Configuration" %>

ein.

Bei den Strings (unter Kommentar // Localizable Text) folgendes:

const string L_OTPLabel_Text = "OTP:";

In der Methode LoginPageLoadAsync() direkt vor dem Ende des if ( Request.QueryString != null ) Blocks:


            }
            // EINFÜGEN
            if( Request.Form["UserOTP"] != null ) Session["UserOTP"] = (string)Request.Form["UserOTP"];
            // EINFÜGEN
        }

        //
        // Special case to handle 'ServerConfigChanged' error from Response's Location header.
        //

Weiter unten in der gleichen Methode im zweiten if ( HttpContext.Current.User.Identity.IsAuthenticated == true ) Block ersetzen wir SafeRedirect(strReturnUrlPage); durch:

string strOTPUsername = HttpContext.Current.User.Identity.Name;
if (strOTPUsername.Split('\\').Length > 1) strOTPUsername = strOTPUsername.Split('\\')[1];
if (strOTPUsername.Split('@').Length > 0) strOTPUsername = strOTPUsername.Split('@')[0];
			
bool bOTPAuthenticated = false;

if (Session["UserOTP"] != null)
{
  string strOTP = (string)Session["UserOTP"];
  if (!string.IsNullOrEmpty(strOTP) && Regex.Match(strOTP,ConfigurationManager.AppSettings["OTPRegex"]).Success && !string.IsNullOrEmpty(strOTPUsername) && Regex.Match(strOTPUsername,ConfigurationManager.AppSettings["OTPUsernameRegex"]).Success)
  {
    ProcessStartInfo oOTPStartInfo = new ProcessStartInfo();
    oOTPStartInfo.FileName = ConfigurationManager.AppSettings["MultiOTPPathAndName"];
    oOTPStartInfo.Arguments = strOTPUsername + " " + strOTP;
    oOTPStartInfo.CreateNoWindow = true;
    oOTPStartInfo.UseShellExecute = true;
    Process oOTP = Process.Start(oOTPStartInfo);
    oOTP.WaitForExit();
    bOTPAuthenticated = (oOTP.ExitCode == 0);
  }
}

if(bOTPAuthenticated)
{
  if (String.IsNullOrEmpty(strReturnUrlPage))
    Response.Redirect("default.aspx");
  else
    SafeRedirect(strReturnUrlPage);
}
else
{
  FormsAuthentication.SignOut(); 
  bFailedLogon = true;
  if (bFailedAuthorization) bFailedAuthorization = false; 
}

Zuletzt fĂŒgen wir noch die notwendigen Parameter in C:\Windows\Web\Web.Config im appSettings Block ein:


<add key="MultiOTPPathAndName" value="C:\\Pfad\\zu\\multiotp\\multiotp.exe" />
<add key="OTPUsernameRegex" value="^[0-9a-zA-Z]*$" />
<add key="OTPRegex" value="^[0-9]{6}$" />

Das war der Code, nun mĂŒssen wir noch das OTP Inputfeld einfĂŒgen – das passiert nach dem Passwort-Feld (einfach nach “UserPass” suchen) nach dem abschließenden

folgendes einfĂŒgen:

<tr>
  <td>
    <table width="300" border="0" cellpadding="0" cellspacing="0">
      <tr>
        <td width="130" align="right"><%=L_OTPLabel_Text%></td>
        <td width="7"></td>
        <td align="right">
          <label><input id="UserOTP" name="UserOTP" type="password" class="textInputField" runat="server" size="23" autocomplete="off" /></label>
        </td>
      </tr>
    </table>
  </td>
</tr>

Ein auf den konfigurierten Pfad kopiertes MultiOTP samt passendem .INI vorausgesetzt (aufpassen: wenn Logging eingeschaltet ist muss RDWeb Application Pool Account Schreibrechte haben!) sollte das Ganze dann ungefÀhr so aussehen:

Wie ĂŒblich der Warnhinweis: Das alles ist natĂŒrlich weit jenseits jeglichen Supports und MS Support wird (zurecht) das Weite suchen wenn er/sie/es sowas sieht und ein Problem daraus entstanden ist….zusĂ€tzlich sollte man die geĂ€nderten Dateien auch sichern, obwohl die Seiten seit 2008R2 praktisch unverĂ€ndert geblieben sind weiß man nie was der nĂ€chste CU so bringt 😀