diff --git a/1.cfm b/1.cfm
index a4b273e..0e63b05 100644
--- a/1.cfm
+++ b/1.cfm
@@ -1,7 +1,9 @@
+
t test
+
-
+
diff --git a/Application.cfc b/Application.cfc
index 7ad7753..a2f43e9 100644
--- a/Application.cfc
+++ b/Application.cfc
@@ -22,20 +22,18 @@
+
-
-
+
+
+
-
-
-
-
@@ -77,7 +74,7 @@
-
+
@@ -168,128 +165,156 @@
(для начала делаем без рефреша, только проверяем протухание)
А рефреш можно сделать на серверной стороне?
Кладем данные из токена в реквест и наслаждаемся --->
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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);
+ } else {
+ //точно мы так не словим дедлок ВПР
- /*
- часто появляется ошибка: после неудачного запроса к 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 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
+ }
+
@@ -418,39 +443,49 @@
-
-//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/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-----";
+ //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#");
}
- throw(message="RSA cetificate not found");
- } else {
- throw (message="Cannot obtain IDP certificate, request failed", detail="Status_Code #status_code#");
}
-}
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index.cfm b/index.cfm
index 774a235..39178ff 100644
--- a/index.cfm
+++ b/index.cfm
@@ -70,6 +70,7 @@ VCD Computing: #dateFormat(report.qComputingAge.dt_load,'YYYY-MM-DD')# #timeF
VCD Storage: #dateFormat(report.qStorageAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qStorageAge.dt_load,'HH:MM:SS')#
S3 хранение: #dateFormat(report.qS3VolAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qS3VolAge.dt_load,'HH:MM:SS')#
S3 операции и трафик: #dateFormat(report.qS3OpsTrfAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qS3OpsTrfAge.dt_load,'HH:MM:SS')#
+Цены GPL
@@ -83,7 +84,7 @@ S3 операции и трафик: #dateFormat(report.qS3OpsTrfAge.dt_load,
Артикул |
Кол-во (метрика) |
Ед.изм. |
- Цена ₽ со скид., с НДС |
+ Цена ₽ GPL, с НДС |
Стоимость ₽ с НДС |
|
@@ -92,8 +93,8 @@ S3 операции и трафик: #dateFormat(report.qS3OpsTrfAge.dt_load,
Компонент |
- GPL с НДС |
- Скидка% |
+
- #price# |
- #discount# |
+
#metric# |
diff --git a/json.cfm b/json.cfm
index db0af4e..1a1df0b 100644
--- a/json.cfm
+++ b/json.cfm
@@ -61,13 +61,14 @@
-
-
+}/>