),
DE( "https://" ),
DE( "http://" )
) &
cgi.http_host &
reReplace(
getDirectoryFromPath( arguments.template ), "([^\\/]+[\\/]){#local.requestDepth#}$",
"",
"one"
)
) />
var requestData = GetHttpRequestData();
var headers = requestData.headers;
//writedump(headers);
if (structKeyExists(headers,"authorization")) {
var authorizationHeader = headers.authorization;
if (authorizationHeader.startsWith("Bearer ")) {
var bearerToken = Mid(authorizationHeader, 8);
writeDump(bearerToken);
//var token=toString(binaryDecode(bearerToken, "base64"));
//writeDump(token);
//jwt = new lib.jwt(this.client_secret);
//lock scope="application" type="readonly" timeout="1" {
// var token_data = (jwt.decode(token, application.idpCertificate,"RS256"));
//}
var result="";
//try {
var iamService = new http(method = "GET", charset = "utf-8", url = #this.iam_url#, timeout="5");
iamService.addParam(type = "HEADER", name = "Accept", value = "application/json");
iamService.addParam(type = "HEADER", name = "Authorization", value = "#authorizationHeader#"); //passthrough
//writedump(this.iamServiceUrl);abort;
var resp = iamService.send();
//if (resp.status_code NEQ 200) throw("IDP response not OK");
//writedump(resp);abort;
var prefix = resp.getPrefix();
if (prefix.status_code NEQ 200) {
//writedump(this.iamServiceUrl);
//writedump(resp);
var iamStatusCode = (isValid("integer", prefix.status_code)) ? val(prefix.status_code) : 500;
throw(message="IAM error", detail="URL: #this.iam_url# Status Code: #prefix.status_code#");
//abort;
//throw("IDP response not OK");
}
result = prefix.filecontent;
var idpUserData=deserializeJson(result);
request.auth.wz=idpUserData.userInfo.ClientId;//GUID!
request.auth.login = idpUserData.userInfo.login;
//request.usrUid=idpUserData.userInfo.contactId;//userId; //GUID!
//writedump(idpUserData);abort;
//} catch (e) {
/*if (fileExists("#GetDirectoryFromPath(GetCurrentTemplatePath())#/etc/local-debug")) { //true for local debug without IDP, etc/* does not go to repository
var result='{"accounts":[{"login":"","type":"telegram"}],"avatar":["d2d2b7ac-50af-432b-b7c4-f7d6561e288a"],"company":"ООО «НУБЕС»","companyId":"8ec70ac0-546d-42a7-8cff-339c8fb51a23","contactId":"983967a3-58c2-4cdd-84a5-8b427ccfac82","email":"smishchuk@nubes.ru","externalUser":false,"fio":{"fullName":"Мищук Сергей ","name":"Сергей","secondName":"","surname":"Мищук"},"groupIds":["94bf5be7-52f4-5c13-87c3-513786934685","ab12b6b8-0265-4683-a5c2-5e1a74a55216","aff008c3-7443-50f6-86e1-ecff3cd3b04d","d6000da0-c9aa-55eb-9882-f118b432730b","d89a33dc-3177-5854-9580-f7f860a5ab7c","ddfe2555-9ef4-42cb-9a2b-7f24e61e7747","df12926f-ecb8-5479-857f-6d291464baad","fda5c295-230a-5025-9797-b8b4e99e08aa","2be9b4b6-94d1-59f9-a649-cab228d82169","64fe6f5c-a91b-5fea-a7ca-d9823701ebd4"],"integration":{"serviceId":""},"login":"smishchuk@nubes.ru","mobilePhone":[],"position":"","userId":"d72530e1-66a4-412f-a046-38153c4e5405"}';}
*/
//writedump(resp);
//return representationOf( {"exception"=e} );
//rethrow(e);
//}
}
} else {
//точно мы так не словим дедлок ВПР
lock scope="session" type="exclusive" timeout="3" {
//writedump(session);
//writeoutput(getTickCount()-request.startTickCount);
//Это первая проба, с сессией
//Когда протухнет сессия, мы можем пойти к IDP и повторно аутентифицироваться. Поскольку у нас сохраняются куки IDP, его сессия, возможно, будет жива. Если мы обновляли сессию IDP в другом приложении SSO, по всей видимости, она будет продолжаться. Если мы видим, что сессия IDP состарилась и хочет протухнуть, мы можем ее освежить и получить новый access token (который мы пока не используем - мы пользуемся ответом IDP) Наверное, правильно обходиться для этих целей вообще без сессии *** --->
//проверить sso
//? сделать рефреш
//? сделать логаут
//? сделать отображение ошибки IDP
//+ сделать получение сертификата
if (structKeyExists(session, "auth")) {
request.auth = structCopy(session.auth);
} else {
//
session.auth_state=createGUID().toString()
jwt = new lib.jwt(this.client_secret);
idp = new lib.oauth2(this.client_id, this.client_secret, this.auth_endpoint, this.access_token_endpoint, this.redirect_uri);
/*
часто появляется ошибка: после неудачного запроса к IDP
в адресной строке браузера остается все, с чем его редиректил IDP,
а повторный запрос с этим контентом уже не работает. Получаем 400 Bad Request -
может быть, KeyCloak так защищается от циклических редиректов
Не очень понятно, как предотвратить повторный запрос (можно, конечно, использовать сессию, но странно)
*/
//writeOutput(getTickCount()-request.startTickCount);
if(structKeyExists(url, "code")) { //обрабатываем редирект от IDP *** наличие поля code в URL введет нас в заблуждение,
//но эvar = data, label =то только без валидной сессии
//dump(var = url.code, label = "URL.code");
// Request access token from idp with the
// authorization code that we got via the URL
//aFormFields = [];
//data = idp.makeAccessTokenRequest((url.code).content, aFormFields);
try {
writeOutput("idp.makeAccessTokenRequest");
writeOutput(getTickCount()-request.startTickCount);
resp = idp.makeAccessTokenRequest(url.code/*, aFormFields*/);
writeOutput("idp.makeAccessTokenRequest Done");
writeOutput(getTickCount()-request.startTickCount);
//dump(resp);
data = deserializeJson(resp.content);
//writedump(data);
// Print full response from idp
//dump(var = data, label = "makeAccessTokenRequest - Response from idp");
//echo('Refresh token #data.refresh_token#');
session.auth.expires_in = data.expires_in;
session.auth.refresh_expires_in = data.refresh_expires_in;
session.auth.access_token = data.access_token;
session.auth.refresh_token = data.refresh_token;
session.auth.id_token = data.id_token;
session.auth.token_type = data.token_type;
session.idp_response_content = structCopy(data);
//flush()
lock scope="application" type="readonly" timeout="1" {
token_data = (jwt.decode(data.access_token, application.idpCertificate,"RS256"));
}
writeOutput("jwt.decode Done");
writeOutput(getTickCount()-request.startTickCount);
writedump(token_data);
session.auth.login = token_data.preferred_username;
session.auth.wz = token_data.ClientID;
session.auth.fullname = token_data.name;
session.auth.groups = token_data.groups;
session.auth.session_state = token_data.session_state;
session.auth.sid = token_data.sid;
session.auth.auth_time = token_data.auth_time;
session.auth.exp = token_data.exp;
session.auth.iat = token_data.iat;
//session.sid = token_data.sid;
session.token_data = structCopy(token_data);
location(this.redirect_uri,false);
} catch (e) {echo('
****************** #e.message# : #e.detail# **********');}
} else {
strURL = idp.buildRedirectToAuthURL({"scope":'openid profile email',"state":session.auth_state,"allow_signup":false});
echo('self-made Auth link (idp) #strURL#
');
location(strUrl,false);
}
}
} // lock session exclusive
}
--->
select value as stand from config
where name='STAND'
select 1;
select 2;
//https://keycloak.nubes.ru/admin
//https://keycloak.nubes.ru/realms/SSH_CA/account //smishchuk@mgmt.nubes.ru
//https://stackoverflow.com/questions/28658735/what-are-keycloaks-oauth2-openid-connect-endpoints
//http://https://keycloak.nubes.ru/realms/SSH_CA/.well-known/openid-configuration
//https://keycloak.nubes.ru/realms/cloud/.well-known/openid-configuration тут ссылка
//https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/certs тут серт
//только надо его обрамить -----BEGIN CERTIFICATE-----
function getIdpCertificate(certUrl) {
var httpService = new http();
httpService.setMethod( "get" );
httpService.setCharset( "utf-8" );
httpService.setUrl(arguments.certUrl);
var result = httpService.send().getPrefix();
var status_code = result.ResponseHeader['Status_Code'];
if ('200' == status_code) {
var content = deserializeJson(result.FileContent);
//мы подразумеваем структуру конкретно KeyCloak
var key = "";
for (key in content.keys) {
if ("RSA" == key.kty AND "sig" == key.use) {
return "-----BEGIN CERTIFICATE-----" & key.x5c[1] & "-----END CERTIFICATE-----";
}
}
throw(message="RSA cetificate not found");
} else {
throw (message="Cannot obtain IDP certificate, request failed", detail="Status_Code #status_code#");
}
}