FSN#41669 Basic Auth en FSN#41668 aanzet

svn path=/Website/trunk/; revision=35003
This commit is contained in:
Jos Groot Lipman
2017-08-17 21:03:42 +00:00
parent 774d14879b
commit 5fcdd475e6
8 changed files with 344 additions and 297 deletions

View File

@@ -18,37 +18,15 @@ var DEZE = this;
api2_rest = {
authenticate: function _authenticate()
{
var APIKEY;
if (S("fac_api_key_in_url"))
APIKEY = getQParam("APIKEY", "");
if (!APIKEY && Request.ServerVariables("HTTP_X_FACILITOR_API_KEY").Count)
APIKEY = String(Request.ServerVariables("HTTP_X_FACILITOR_API_KEY")); // Meegegeven als X-FACILITOR-API-Key
if (!APIKEY && Session("user_key") > 0)
{
user_key = Session("user_key"); // Hierdoor is de API intern te gebruiken zonder authenticatie
var method = String(Request.ServerVariables("REQUEST_METHOD"));
if (method != "GET") // Vereis dan wel het CSRF token
if (method != "GET" && Session("stateless") != 1) // Vereis dan wel het CSRF token
{
var token = Request.ServerVariables("HTTP_X_CSRF_TOKEN").Count // Meegegeven als X-CSRF-TOKEN
? String(Request.ServerVariables("HTTP_X_CSRF_TOKEN"))
: "";
protectRequest.validateToken(token);
}
}
else
{
if (Session("user_key") > 0)
{} // Tijdens ontwikkeling heb je soms in tweede tab de GUI open. Laat dat ongemoeid.
else
Session.Abandon(); // Altijd, voor de zekerheid
var sql = "SELECT prs_perslid_key, prs_perslid_naam, prs_perslid_oslogin"
+ " FROM prs_perslid"
+ " WHERE prs_perslid_verwijder IS NULL"
+ " AND prs_perslid_apikey = " + safe.quoted_sql(APIKEY);
var oRs = Oracle.Execute(sql);
if (oRs.Eof || !APIKEY)
if (user_key < 0)
{
Response.Status = "401 Unauthorized";
// Sommige applicaties kunnen in reactie hierop een b64 encoded username:password sturen
@@ -56,9 +34,6 @@ api2_rest = {
if (S("basic_auth_realm"))
Response.AddHeader("WWW-Authenticate", "Basic realm=\"" + S("basic_auth_realm") + "\"");
Response.End;
};
__Log("API2 User is: {0} ({1})".format(oRs("prs_perslid_naam").Value, oRs("prs_perslid_oslogin").Value));
/* global */ user_key = oRs("prs_perslid_key").Value;
if (typeof NO_ADDHEADER == "undefined" && Request.Servervariables("HTTP_FCLT_VERSION").Count > 0)
{ // wordt opgepikt door FCLTAPI.DLL voor in de logging en daarna gestript. Niet in Fiddler dus
@@ -93,7 +68,6 @@ api2_rest = {
oRs.Close()
}
/* global */ user = new Perslid(user_key); // wordt mogelijk nog overruled door imporsonate
CheckForLogging(Request.QueryString("logging")); // Nu pas kan autorisatie via user gecontroleerd worden
},

View File

@@ -53,6 +53,7 @@ function model_aut_idp_map(params)
+ ";9;" + L("lcl_prs_person_email")
+ ";10;" + L("lcl_prs_person_phone")
+ ";11;" + L("lcl_prs_person_mobile")
+ ";12;" + L("prs_perslid_externid")
// De foreign's
+ ";20;" + L("lcl_prs_person_function")

View File

@@ -92,7 +92,7 @@ function model_prs_perslid(params)
"label": L("lcl_prs_person_initials"),
"typ": "varchar"
},
"prefix": {
"middlename": {
"dbs": "prs_perslid_tussenvoegsel",
"label": L("lcl_prs_person_tussen"),
"typ": "varchar"
@@ -169,6 +169,11 @@ function model_prs_perslid(params)
"typ": "key",
"foreign": "prs_afdeling"
},
"externalid": {
"dbs": "prs_perslid_externid",
"label": L("prs_perslid_externid"),
"typ": "varchar"
},
"company": {
"dbs": "pa.prs_bedrijf_key",
"label": L("lcl_prs_company"),

View File

@@ -18,6 +18,7 @@
<!-- #include file="../api2/model_prs_perslid.inc" -->
<%
// Elders is prs_key geauthenticeerd. Registreer die hier als de actieve gebruiker.
// stateless komen we hier al niet
function doLogin(prs_key, params)
{
__Log("==== doLogin " + prs_key);
@@ -67,12 +68,6 @@ function doLogin(prs_key, params)
}
}
// Alvast nieuwe user_key loggen zodat je ziet wie er inlogt.
if (typeof NO_ADDHEADER == "undefined" && user_key != prs_key && Request.Servervariables("HTTP_FCLT_VERSION").Count > 0)
{ // wordt opgepikt door FCLTAPI.DLL voor in de logging en daarna gestript. Niet in Fiddler te zien dus
Response.AddHeader ("FCLT_USERID", customerId + "\\" + String(prs_key));
}
/* global */ user_key = prs_key;
//user_lang = oRs(1).Value; // globale moet er nog uit!
if (typeof LCL_Disable == "undefined")
@@ -99,7 +94,7 @@ function doLogin(prs_key, params)
var agent = String(Request.ServerVariables("HTTP_USER_AGENT"));
// Welbeschouwd gebruiken we het volgende FAC_SESSION record nooit, we werken
// altijd met ASPSESSION==>IIS SESSION==>user_key
// altijd met ASPSESSION cookie==>IIS SESSION==>user_key
var sql = "INSERT INTO fac_session"
+ " (fac_session_sessionid_hash,"
+ " prs_perslid_key,"
@@ -180,16 +175,6 @@ function doLogin(prs_key, params)
+ " )";
Oracle.Execute(sql, true);
}
else
{
__Log("Welcome.asp expired?");
var sql = "DELETE FROM fac_menu"
+ " WHERE fac_menu_altgroep = 5"
+ " AND fac_menu_alturl = " + safe.quoted_sql(S("fac_firstlogin_url"))
+ " AND prs_perslid_key = " + user_key
+ " AND fac_menu_aanmaak < SYSDATE - " + S("fac_firstlogin_expire");
Oracle.Execute(sql, true);
}
var fac_lang = getQParamSafe("fac_lang", "").toUpperCase(); // overrule via param
// Liever geen session maar m_connections heeft dit al nodig voor zijn fac.initsession
@@ -200,6 +185,14 @@ function doLogin(prs_key, params)
return true;
}
function doLoginStateless(prs_key, params)
{
/* global */ user_key = prs_key;
Session("user_key") = user_key; // Nu ben je pas *echt* ingelogd
/* global */ user = new Perslid(user_key); // wordt mogelijk nog overruled door imporsonate
Session("stateless") = 1;
Session.Abandon(); // Altijd, voor de zekerheid
}
// Session.Abondon is gevaarlijk: dan verlies je ook CustomerID etc.
// Bovendien krijg je met IIS dan nog steeds geen nieuwe ASPSESSIONID
@@ -258,7 +251,7 @@ function makeSessionCookie (sessionData)
+ "fac.makehash(" + safe.quoted_sql(sessionId) + "), "
+ user_key + ", "
+ safe.quoted_sql(sessionData) + ", "
+ " sysdate + " + S("login_remember_days") + ", " // sessie timeout op een half jaar.
+ " sysdate + " + S("login_remember_days") + ", " // sessie timeout op 30 dagen.
+ safe.quoted_sql(agent, 256) + ","
+ safe.quoted_sql(ip, 64) + " )"
Oracle.Execute(sql);
@@ -440,7 +433,7 @@ function testpassword(prs_key, wachtwoord, pmobile)
oRs.Close();
if (!found)
return false;
// else TODO upgraden!
// else iets verderop upgraden!
var workfactor = 0;
}
else // new style
@@ -487,11 +480,11 @@ function setpassword(prs_key, wachtwoord, expired)
{
var passsalt = shared.random(32);
var workfactor = S("prs_password_hash_factor");
var is_hash = pbkdf2(wachtwoord, passsalt, workfactor);
var new_hash = pbkdf2(wachtwoord, passsalt, workfactor);
var sql = "UPDATE prs_perslid" // Ooit expire op SYSDATE + fac.getsetting ('prs_password_expiration') als die is gevuld
+ " SET prs_perslid_wachtwoord_exp = " + (expired?"SYSDATE":"NULL")
+ " , prs_perslid_salt = " + safe.quoted_sql(passsalt)
+ " , prs_perslid_wachtwoord_hash = " + safe.quoted_sql('1${0}${1}'.format(workfactor, is_hash))
+ " , prs_perslid_wachtwoord_hash = " + safe.quoted_sql('1${0}${1}'.format(workfactor, new_hash))
+ " WHERE prs_perslid_key = " + prs_key;
Oracle.Execute(sql);
}
@@ -505,7 +498,6 @@ function testotp (prs_key, otprequest)
+ " WHERE prs_perslid_key = " + prs_key;
var oRs = Oracle.Execute(sql);
var otpsecret = oRs("prs_perslid_otpsecret").Value;
var otpcounter = oRs("prs_perslid_otpcounter").Value || -1;
oRs.Close();
@@ -549,6 +541,7 @@ function verify_otp (prs_key, otprequest, otpsecret, otpcounter)
return otp_oke;
}
// Op basis van usernaam/wachtwoord gaan we iemand authenticeren
function getIdentity(username, wachtwoord, params)
{
var result = { success: false, fail_reason: L("lcl_login_wrong") };
@@ -622,9 +615,9 @@ function getIdentity(username, wachtwoord, params)
{
logins.push(" upper(prs_perslid_email) = " + safe.quoted_sql_upper(username));
}
else if (getQParam("API", ""))
else if (getQParam("API", "") || getQParam("API2", ""))
{
logins.push(" prs_perslid_apikey = " + safe.quoted_sql_upper(username, 128));
logins.push(" prs_perslid_apikey = " + safe.quoted_sql(username, 128)); // TODO zorgen dat result.stateless gezet raakt
wachtwoord = null;
}
else
@@ -653,6 +646,7 @@ function getIdentity(username, wachtwoord, params)
var oSLNKDWF = new ActiveXObject("SLNKDWF.About");
var sleepmsec = Math.min(80000, tmicro / 1000 * 32);
oSLNKDWF.Sleep(sleepmsec);
oRs.Close();
return result;
}
@@ -660,7 +654,7 @@ function getIdentity(username, wachtwoord, params)
var otpcounter = oRs("prs_perslid_otpcounter").Value || -1;
var found = false;
if (/* nog niet vanuit SAML/default.asp params.noPassword && */ wachtwoord == null) // SSO
if (/* nog niet vanuit SAML/default.asp params.noPassword && */ wachtwoord === null) // SSO
found = true; // En zijn we verder wel klaar
else
found = testpassword(oRs("prs_perslid_key").Value, wachtwoord, params.mobile);
@@ -735,7 +729,12 @@ function tryLogin(username, wachtwoord, params)
return false;
if (ident.user_key > 0)
{
if (ident.stateless || params.stateless)
doLoginStateless(ident.user_key, params);
else
doLogin(ident.user_key, params);
}
return true;
}
@@ -1015,11 +1014,6 @@ function SimpleSSO()
__Log('User#2a = '+username);
}
if (username !='' && username!='undefined') {
// Strip domain name
while( (i = username.indexOf('\\')) >= 0 ) {
l = username.length;
if( i < l-1 ) username = username.substring(i+1,l);
}
tryLogin(username, null, { noPassword: true });
}
}
@@ -1047,11 +1041,6 @@ function IntegratedSSO()
}
if (username !='' && username!='UNDEFINED')
{
// Strip domain name
while( (i = username.indexOf('\\')) >= 0 ) {
l = username.length;
if( i < l-1 ) username = username.substring(i+1,l);
}
tryLogin(username, null, { noPassword: true });
}
}
@@ -1370,14 +1359,14 @@ function process_claim(claim, idp_data, params)
{
case 1: // login
settings.overrule_setting("login_use_email", 0);
tryLogin(claim[idpm.from], null, { noPassword: true, idp_code: idp_data.code, noFacSession: params.by_bearer, isFACFACinternal: isFACFACinternal });
tryLogin(claim[idpm.from], null, { noPassword: true, idp_code: idp_data.code, stateless: params.by_bearer, isFACFACinternal: isFACFACinternal });
break;
case 9: // email
settings.overrule_setting("login_use_email", 1);
tryLogin(claim[idpm.from], null, { noPassword: true, idp_code: idp_data.code, noFacSession: params.by_bearer, isFACFACinternal: isFACFACinternal });
tryLogin(claim[idpm.from], null, { noPassword: true, idp_code: idp_data.code, stateless: params.by_bearer, isFACFACinternal: isFACFACinternal });
break;
case 99: // internal, prs_perslid_key
doLogin(parseInt(claim[idpm.from], 10), { noFacSession: params.by_bearer, idp_code: idp_data.code, isFACFACinternal: isFACFACinternal });
doLogin(parseInt(claim[idpm.from], 10), { stateless: params.by_bearer, idp_code: idp_data.code, isFACFACinternal: isFACFACinternal });
break;
default:
if (idpm.name.id > 1000) // Flexkenmerk
@@ -1394,7 +1383,7 @@ function process_claim(claim, idp_data, params)
var oRs = Oracle.Execute(sql);
if (!oRs.Eof)
{
doLogin(oRs("prs_perslid_key").Value, { noFacSession: params.by_bearer, idp_code: idp_data.code, isFACFACinternal: isFACFACinternal });
doLogin(oRs("prs_perslid_key").Value, { stateless: params.by_bearer, idp_code: idp_data.code, isFACFACinternal: isFACFACinternal });
}
oRs.Close();
}
@@ -1414,6 +1403,13 @@ function process_claim(claim, idp_data, params)
|| user_key > 0 && idp_data.autocreate.id & 2 // en/ of bijwerken
)
{
process_claim_update(claim, idp_data, params)
}
}
function process_claim_update(claim, idp_data, params)
{
var isFACFACinternal = idp_data.internal != 0;
var persdata = { };
for (var i =0; i < idp_data.idpmappings.length; i++)
{
@@ -1427,7 +1423,7 @@ function process_claim(claim, idp_data, params)
case 1: persdata["login"] = val; break;
case 2: persdata["lastname"] = val; break;
case 3: persdata["firstname"] = val; break;
case 4: persdata["prefix"] = val; break;
case 4: persdata["middlename"] = val; break;
case 5: persdata["initials"] = val; break;
case 6: persdata["gender"] = val; break;
case 7: persdata["phone"] = val; break;
@@ -1435,6 +1431,7 @@ function process_claim(claim, idp_data, params)
case 9: persdata["email"] = val; break;
case 10: persdata["phone"] = val; break;
case 11: persdata["mobile"] = val; break;
case 12: persdata["externalid"] = val; break;
// de foreigns
case 20: if (val)
persdata["function"] = { name: val }; break; // Kan omdat fields.function.desc_is_unique is gezet
@@ -1628,7 +1625,6 @@ function process_claim(claim, idp_data, params)
}
}
}
}
%>
<script language="VBScript" runat="Server">

View File

@@ -6,11 +6,24 @@
Met vernieuwde kennis zou ik dit bestand authenticate.asp noemen
We weten niet wie de gebruiker is.
Probeer op allerlei manieren SSO
Probeer op allerlei manieren te authentiseren
Als het lukt geven we een user_key terug in Session("user_key");
Als het niet lukt zal doorgaans door common.inc verder gegaan worden in de interactieve Logon.asp
LET OP: Dit bestand wordt via Server.Transfer vanuit Common.inc aangeroepen
We onderscheiden twee soorten authenticatie
Statefull
Dit is voor een interactieve gebruiker met een browser. Initieel wordt op
allerlei manieren authenticatie geprobeerd maar daarna wordt de user_key
in een Session opgeslagen en de volgende keer wordt via een Session-coolie
vanuit die session de authenticatie gedaan
In prs_perslid_login wordt het laatste moment van inloggen bijgewrkt
Er wordt een fac_session record aangemaakt (waar we verder weinig mee doen)
Stateless
Dit is voor API aanroepen. ELKE aanroep komt de authenticatie opnieuw
mee. Dit wordt niet geregistreerd in prs_perslid_login
Er wordt een Session.abandon gedaan om niet te veel IIS sessies te houden
*/
DOCTYPE_Disable = 1;
ANONYMOUS_Allowed = 1;
@@ -46,19 +59,28 @@ if (typeof Session("sso_sgf") == "string") // Vanuit FACWS001-portal/ sso_sgf.as
Session.Contents.Remove("sso_sgf_realuser");
}
// De stateless varianten proberen we eerst, die worden tenslotte potentieel vaak uitgevoerd
if (user_key < 0)
SimpleSSO(); // de base64 simple sso
// Ingescande QR-code bookmark gaat naar \appl\prs\prs_perslid_qr_confirm.asp
if (user_key < 0) // Probeer de user_key uit een cookie te halen
{
var FcltId = "" + Request.Cookies("fcltid");
if (FcltId != null && FcltId != "")
var APIKEY;
if (S("fac_api_key_in_url"))
APIKEY = getQParam("APIKEY", "");
if (!APIKEY && Request.ServerVariables("HTTP_X_FACILITOR_API_KEY").Count)
APIKEY = String(Request.ServerVariables("HTTP_X_FACILITOR_API_KEY")); // Meegegeven als X-FACILITOR-API-Key
if (APIKEY)
{
setUserFromSession (FcltId);
if (user_key > 0)
makeSessionCookie("Remember Login"); // Atijd nieuwe
var sql = "SELECT prs_perslid_key, prs_perslid_naam, prs_perslid_oslogin"
+ " FROM prs_perslid"
+ " WHERE prs_perslid_verwijder IS NULL"
+ " AND prs_perslid_apikey = " + safe.quoted_sql(APIKEY);
var oRs = Oracle.Execute(sql);
if (!oRs.Eof)
{
__Log("API2 User is: {0} ({1})".format(oRs("prs_perslid_naam").Value, oRs("prs_perslid_oslogin").Value));
doLoginStateless(oRs("prs_perslid_key").Value);
}
// else negeren
oRs.Close()
}
}
@@ -74,11 +96,27 @@ if (user_key < 0)
{
var ww = plain.split(":");
ww.shift();
tryLogin(plain.split(":")[0], ww.join(":")); // Behoudt eventuele ':' in wachtwoord
tryLogin(plain.split(":")[0], ww.join(":"), { stateless: true }); // Behoudt eventuele ':' in wachtwoord
}
}
}
if (user_key < 0)
SimpleSSO(); // de base64 simple sso
// Ingescande QR-code bookmark gaat naar \appl\prs\prs_perslid_qr_confirm.asp
if (user_key < 0) // Probeer de user_key uit een cookie te halen
{
var FcltId = "" + Request.Cookies("fcltid");
if (FcltId != null && FcltId != "")
{
setUserFromSession (FcltId);
if (user_key > 0)
makeSessionCookie("Remember Login"); // Atijd nieuwe
}
}
if (user_key < 0)
{
var auth = String(Request.ServerVariables("HTTP_X_FACILITOR_ACCESS_TOKEN"));
@@ -269,7 +307,7 @@ if (user_key < 0 && APIname)
var API = new API_func(); // controleert vanzelf
if (API.apidata.prs_perslid_key)
doLogin(API.apidata.prs_perslid_key, { noFacSession: true });
doLogin(API.apidata.prs_perslid_key, { stateless: true });
}
// LogOff.asp kan Session("no_sso") gezet hebben
@@ -297,6 +335,15 @@ if (user_key < 0 && S("os_logon")
//if (user_key < 0)
// trySSO("DEFAULT"); // zal je standaard naar het loginscherm sturen
if (user_key > 0) // dan hebben we (nu) een nieuwe user
{
// Alvast nieuwe user_key loggen zodat je ziet wie er inlogt.
if (typeof NO_ADDHEADER == "undefined" && Request.Servervariables("HTTP_FCLT_VERSION").Count > 0)
{ // wordt opgepikt door FCLTAPI.DLL voor in de logging en daarna gestript. Niet in Fiddler dus
Response.AddHeader ("FCLT_USERID", customerId + "\\" + String(user_key));
}
}
__Log("== Leaving loginTry.asp ==");
%>

View File

@@ -74,6 +74,14 @@
}
// einde conversie user_options naar fac_menu
__Log("Welcome.asp expired?");
var sql = "DELETE FROM fac_menu"
+ " WHERE fac_menu_altgroep = 5"
+ " AND fac_menu_alturl = " + safe.quoted_sql(S("fac_firstlogin_url"))
+ " AND prs_perslid_key = " + user_key
+ " AND fac_menu_aanmaak < SYSDATE - " + S("fac_firstlogin_expire");
Oracle.Execute(sql, true);
// autoopen ophalen uit database
var autoopen = [];
var sql = "SELECT fac_menu_altlabel"

View File

@@ -22,6 +22,8 @@
<!--#include file="../Shared/iface.inc" -->
<%
debugger;
FCLTHeader.Requires({plugins:["suggest","jQuery"], js: ["jquery-ui.js"]})
var submitting = getQParamInt("submit", 0) == 1;

View File

@@ -42,4 +42,18 @@
<match url="^melding/(\d+)" />
<action type="Rewrite" url="default.asp?u=melding&amp;k={R:1}" appendQueryString="true" />
</rule>
<rule name="SCIMUsers" stopProcessing="true">
<match url="^SCIM/Users" />
<action type="Rewrite" url="default.asp?api2=persons&amp;format=json&amp;plugin=scimusers&amp;include=lastchange,authorization" appendQueryString="true" />
</rule>
<!--
<rule name="Check file exists">
<match url="^([^.]+)\.([a-zA-Z]+)" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="/appl/shared/404_error.asp?url404={R:1}.{R:2}" appendQueryString="true" />
</rule>
-->
</rules>