 Rank: Newbie Medals:  Joined: 3/21/2013(UTC) Posts: 8
Was thanked: 1 time(s) in 1 post(s)
|
We are looking at integrating ScreenConnect with Phonefactor. We have need to require 2 factor auth when techs are offsite. We don't want to turn ScreenConnect into a remote access solution without 2 factor auth. We already integrate PhoneFactor with Citrix for remote access so by extending to SC we are being consistent. The sample below supports the PhoneFactor Whitelist. So the setup is this. 1. Create a PhoneFactor Web Service Proxy using .NET 3.5 SDK to ScreenConnect bin directory 2. PhoneFactor Web Service must be installed somewhere so the ScreenConnect Web server can access it. 3. Add the following appSettings to the web.config file of ScreenConnect <add key="PfAuth" value="true" /> <add key="PfAuthWsUrl" value="https://<host>/PhoneFactorWebServiceSdk/PfWsSdk.asmx" /> <add key="PfAuthWsID" value="pf_admin" /> <add key="PfAuthWsPwd" value="pf_admin_password" /> 4. Modify Login.aspx..see snippets below. New function in login.aspx Code:
// Scott Wilson -- Start PhoneFactor Auth Function
protected Boolean PfAuth(string UserID, string IpAddress)
{
//Create Web Service Proxy
PfWsSdk pf = new PfWsSdk();
//Create Error Handler for Proxy
Error pfError = new Error();
//Create Result for Proxy
CallResult pfResult = new CallResult();
//Whitelist for bypass
UserPortalWhitelistIp[] pfWhiteList = new UserPortalWhitelistIp[0];
//Need credentials for PF Web Service proxy. Uses Basic Auth. Credentials need to be member of PhoneFactor Admin Group
System.Net.NetworkCredential pfCredentials = new System.Net.NetworkCredential();
//ID, Password, Whitelist,
string pfUser;
string pfPwd;
bool pfEnabled;
pfEnabled = false;
//Get the settings, these could be passed but what the hey
System.Collections.Specialized.NameValueCollection configuration = System.Web.Configuration.WebConfigurationManager.AppSettings;
if (configuration.Count > 0)
{
//Get AppSettings
pfEnabled = System.Convert.ToBoolean(configuration["PfAuth"]);
pfUser = configuration["PfAuthWsID"];
pfPwd = configuration["PfAuthWsPwd"];
pfCredentials.UserName = pfUser;
pfCredentials.Password = pfPwd;
pf.Credentials = pfCredentials;
pf.Url = configuration["PfAuthWsUrl"];
//Check the Whitelist
try
{
//Get the whitelist
pf.GetUserPortalWhitelistIps(ref pfWhiteList, ref pfError);
// Check every entry in the whitelist of UserPortal..I only use the range values..subnet, hosts, etc need to use ranage
foreach (UserPortalWhitelistIp pfWhiteListEntry in pfWhiteList)
{
try
{
System.Net.IPAddress startIP;
System.Net.IPAddress endIP;
System.Net.IPAddress testIP;
testIP = System.Net.IPAddress.Parse(Request.UserHostAddress);
startIP = System.Net.IPAddress.Parse(pfWhiteListEntry.FromIp);
endIP = System.Net.IPAddress.Parse(pfWhiteListEntry.ToIp);
byte[] testIPbytes = testIP.GetAddressBytes();
byte[] startIPbytes = startIP.GetAddressBytes();
byte[] endIPbytes = endIP.GetAddressBytes();
if (testIPbytes[0] >= startIPbytes[0] && testIPbytes[0] <= endIPbytes[0])
{
if (testIPbytes[1] >= startIPbytes[1] && testIPbytes[1] <= endIPbytes[1])
{
if (testIPbytes[2] >= startIPbytes[2] && testIPbytes[2] <= endIPbytes[2])
{
if (testIPbytes[3] >= startIPbytes[3] && testIPbytes[3] <= endIPbytes[3])
{
//If all my tests succeed..then set PF to false and bypass below.
pfEnabled = false;
}
}
}
}
}
catch
{
}
}
if (pfEnabled == true)
{
pf.PfAuthUser_3(UserID, AuthenticationType.unspecified, Request.UserHostAddress, "ScreenConnect", true, ref pfResult, ref pfError);
// Code 21 Cache, code 8 success
if ((pfResult.Code != 21) && (pfResult.Code != 8))
{
return false;
}
else
{
return true;
}
}
}
catch
{
//something went wrong
return false;
}
}
//Bad config so we fail
return false;
}
// Scott Wilson -- End PhoneFactor Auth Function
Code:
void OnLoginPanelAuthenticate(object sender, AuthenticateEventArgs e)
{
var isUserValid = Membership.ValidateUser(this.loginPanel.UserName, this.loginPanel.Password);
var oneTimePasswordUserKey = default(string);
var oneTimePasswordAuthenticationProvider = default(OneTimePasswordAuthenticationProvider);
if (isUserValid)
{
// Scott Wilson - PF Auth Begin
System.Collections.Specialized.NameValueCollection configuration = System.Web.Configuration.WebConfigurationManager.AppSettings;
if (System.Convert.ToBoolean(configuration["PfAuth"]))
{
if (!PfAuth(this.loginPanel.UserName, Request.UserHostAddress))
{
isUserValid = false;
}
}
// Scott Wilson - PF Auth End
this.GetOneTimePasswordAuthenticationInfo(ref oneTimePasswordUserKey, ref oneTimePasswordAuthenticationProvider);
if (oneTimePasswordUserKey == null)
5. Enjoy. Please contact me if you have questions. This is a "beta" setup. It could still be prettier and integrated into the main code branch... HINT..HINT.. :-) Another idea would be to configure SC to support Radius Auth since PhoneFactor has a Radius Proxy, then the code wouldn't be required. Another idea would be to have an IIS version of SC since PhoneFactor has an IIS Plugin to do Form Authentication. Scott
|
|
|
|
 Rank: Newbie Medals:  Joined: 3/21/2013(UTC) Posts: 8
Was thanked: 1 time(s) in 1 post(s)
|
Ok.. Have an update. My original code used the Web Service of PhoneFactor to perform the Auth. You must be a paying PhoneFactor customer to use this Web Services. I created a PF Radius Agent which is available under the free version of PhoneFactor up to 25 people at your company. You might be able to use this with any radius server if you want. 1. Go to http://nradius.nw-network.com/web/index.php. Download source .zip file. Create a new library C# project and compile the class to make a .NET object. Make sure you use the 3.5 framework 2. Copy the resulting .DLL to your BIN directory on ScreenConnect. 3. ScreenConnect Server must have network access to RADIUS server to so make sure all firewall settings are correct. 4. Add the following AppSettings to web.config Quote: <add key="PfAuth" value="true" /> <add key="PfRadiusSvr" value="<radius server>" /> <add key="PfRadiusPwd" value="<radius shared secret>" />
5. Add the following code to near top of Login.aspx Code:
// Scott Wilson -- Start PhoneFactor Radius Auth Function
protected Boolean PfRadiusAuth(string UserID, string Password)
{
int result;
int wait;
string pfRadiusSvr;
string pfRadiusPwd;
bool pfEnabled;
//Get Settings
System.Collections.Specialized.NameValueCollection configuration = System.Web.Configuration.WebConfigurationManager.AppSettings;
if (configuration.Count > 0)
{
//Get AppSettings
pfEnabled = System.Convert.ToBoolean(configuration["PfAuth"]);
pfRadiusSvr = configuration["PfRadiusSvr"];
pfRadiusPwd = configuration["PfRadiusPwd"];
}
else
{
return false;
}
//Radius Timeout to 2 minutes..could be configured with AppSetting
wait = 120000;
if (UserID != "" && Password != "" && pfEnabled == true)
{
System.Net.nRadius.nRadius_Client pfRadius = new System.Net.nRadius.nRadius_Client(pfRadiusSvr, pfRadiusPwd, UserID, Password);
pfRadius.UDPTimeout = wait;
//Attribute 66 needed to do a whitelist lookup on PF Agent
pfRadius.SetAttribute(66, Request.UserHostAddress);
result = pfRadius.Authenticate();
switch (result)
{
//Deny
case -4:
return false;
break;
//Timeout
case -2:
return false;
break;
//Access Granted
case 0:
return true;
break;
default:
return false;
break;
}
}
else
return false;
}
//SW End PF Radius
6. Add the following code further down in login.aspx OnLoginPanelAuthenticate function. Quote: if (isUserValid) {
// Scott Wilson - PF Auth Begin System.Collections.Specialized.NameValueCollection configuration = System.Web.Configuration.WebConfigurationManager.AppSettings; if (System.Convert.ToBoolean(configuration["PfAuth"])) { if (!PfRadiusAuth(this.loginPanel.UserName, this.loginPanel.Password)) { isUserValid = false; this.Response.Redirect("deny.html"); } } // Scott Wilson - PF Auth End
Thanks, Scott
|
|
|
|
Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.