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 😀