Click or drag to resize

IOBERONCashRegisterServiceLoginUserEx Method

EXALOGIC
Prihlási používateľa do webovej služby (záleží však na nastavení spôsobu autentifikácie služby). Je potrebné volať na začiatku komunikácie s webovou službou, nakoľko sa generuje tzv. GUID pre ďalšiu komunikáciu (ten musí byť súčasťou hlavičky danej požiadavky).

Namespace: Exa.OBERON.Services
Assembly: Exa.OBERON.Services (in Exa.OBERON.Services.dll) Version: 5.0.24.0 (5.0.24.0)
Syntax
ResultValue<string> LoginUserEx(
	LoginDataParameters loginData
)

Parameters

loginData  LoginDataParameters
Prihlasovacie údaje (meno, heslo) a ďalšie doplnkové prihlasovacie údaje.

Return Value

ResultValueString
V ResultValue.Data vracia v prípade úspešného prihlásenia tzv. GUID daného používateľa (session používateľa), ktorý je nevyhnutný pre ďalšiu komunikáciu (musí byť súčasťou hlavičky danej požiadavky).
Remarks
Pri prihlásení používateľa nezabezpečenou komunikáciou (HTTP - nezabezpečená, HTTPS -> zabezpečená) môže pri odpočúvaní komunikácie útočník pomerne ľahko zistiť prihlasovacie údaje (hlavne heslo). Čiastočne to rieši systém zasielania hesla len vo forme HASH (OBERON používa SHA-1), avšak pri slabých (krátkych) heslách je veľmi jednoduché pomocou hashovacích tabuliek (databáz) získať aj takého heslo. Z tohto dôvodu je možné pri prihlásení zasielaný HASH hesla "obohatiť" o SALT a tým znemožniť využitie hashovacích tabuliek. Po úspešnom prihlásení sa v ďalších požiadavkách na webovú službu musí v hlavičke dopytu uvádzať daný GUID, podľa ktorého sa overuje daná požiadavka.
Príklad pridania GUID do hlavičky komunikácie v prostredí win32 aplikácie napísanej vo VB.NET
Public Class ServiceClient

    '...
    'Pred zaslaním požiadavky na webovú službu je potrebné pridať do HEADER-a GUID prihláseného užívateľa
    '(samozrejme GUID musí byť známe (teda užívateľ musí byť prihlásený))
    ServiceAddCustomHeaders(txt_OBERONServiceURL_UserGUID.Text, New System.ServiceModel.OperationContextScope(tmp_OBERONService.InnerChannel))
    '...
    '...

    Private Sub ServiceAddCustomHeaders(ByVal UserGUID As String, scope As System.ServiceModel.OperationContextScope)

        'Pridanie GUID do HEADER-a'
        Dim m_HeaderItem As New System.ServiceModel.MessageHeader(Of String)(UserGUID)
        Dim m_UntypedHeader As System.ServiceModel.Channels.MessageHeader = m_HeaderItem.GetUntypedHeader("userData", "")
        System.ServiceModel.OperationContext.Current.OutgoingMessageHeaders.Add(m_UntypedHeader)

    End Sub

End Class
Príklad hash-ovania hesla s použitím SALT vo VB.NET
Public Class ServiceClient

    Private Function GetPasswordHashSHA1(ByVal u_Password As String, ByVal u_Salt As String) As String

        On Error Resume Next

        Dim tmp_Password As String

        If u_Salt = String.Empty Then
            '--- Heslo bez SALT
            tmp_Password = u_Password
        Else
            '--- Je zadaný SALT - Heslo "zväčšiť" o SALT - k saltu pripojiť heslo ----
            tmp_Password = u_Salt & u_Password
        End If

        Dim m_SHA1 As New System.Security.Cryptography.SHA1Managed
        Dim m_bInput() As Byte = System.Text.Encoding.Default.GetBytes(tmp_Password)
        Dim m_bOutput() As Byte

        Dim tmp_PasswordHashSHA1_Local As String
        m_bOutput = m_SHA1.ComputeHash(m_bInput)
        tmp_PasswordHashSHA1_Local = System.BitConverter.ToString(m_bOutput)
        tmp_PasswordHashSHA1_Local = tmp_PasswordHashSHA1_Local.Replace("-", "")
        tmp_PasswordHashSHA1_Local = tmp_PasswordHashSHA1_Local.ToLower

        Return tmp_PasswordHashSHA1_Local

    End Function

End Class
Príklad prihlásenia a volania priamo z html stránky pomocou Java skriptov
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Test webovej služby</title>
    <!-- Tato testovacia html stranka spustena na lokalnom pocitaci pracuje korektne v Internet Exploreri, -->
    <!--  v inych prehliadacoch sa casto vyskytuje problem so zabezpecenim, tzv. Cross-site scripting. -->
    <style>
        .right { text-align: right; }
        .tb td, .tb th { padding: 4px; }
        .tb {
            border: solid 1px #808080;
            border-spacing: 0;
        }
        .tb thead tr {
                background-color: #e6e6e6;
                background-image: linear-gradient(top, #eeeeee, #dadada);
            }
    </style>

</head>
<body>

    <div>

        <form id="testWebService" action="/">
            <!-- 87.197.186.118:20057 / system / system -->
            <input type="text" id="settAddress" placeholder="adresa webovej služby" value="87.197.186.118:20057" />
            <input type="text" id="settName" placeholder="meno" value="system" />
            <input type="text" id="settPassword" placeholder="heslo" value="system" />

            <button id="runTest" type="submit" >Test</button>
        </form>


    </div>

    <div id="resultData"></div>

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.10.2.js" type="text/javascript"></script>

<script type="text/javascript" id="sha1" >
    (function (e) { var t = function (e, t) { return e << t | e >>> 32 - t }; var n = function (e) { var t = ""; var n; var r; var i; for (n = 0; n <= 6; n += 2) { r = e >>> n * 4 + 4 & 15; i = e >>> n * 4 & 15; t += r.toString(16) + i.toString(16) } return t }; var r = function (e) { var t = ""; var n; var r; for (n = 7; n >= 0; n--) { r = e >>> n * 4 & 15; t += r.toString(16) } return t }; var i = function (e) { e = e.replace(/\x0d\x0a/g, "\n"); var t = ""; for (var n = 0; n < e.length; n++) { var r = e.charCodeAt(n); if (r < 128) { t += String.fromCharCode(r) } else if (r > 127 && r < 2048) { t += String.fromCharCode(r >> 6 | 192); t += String.fromCharCode(r & 63 | 128) } else { t += String.fromCharCode(r >> 12 | 224); t += String.fromCharCode(r >> 6 & 63 | 128); t += String.fromCharCode(r & 63 | 128) } } return t }; e.extend({ sha1: function (e) { var n; var s, o; var u = new Array(80); var a = 1732584193; var f = 4023233417; var l = 2562383102; var c = 271733878; var h = 3285377520; var p, d, v, m, g; var y; e = i(e); var b = e.length; var w = new Array; for (s = 0; s < b - 3; s += 4) { o = e.charCodeAt(s) << 24 | e.charCodeAt(s + 1) << 16 | e.charCodeAt(s + 2) << 8 | e.charCodeAt(s + 3); w.push(o) } switch (b % 4) { case 0: s = 2147483648; break; case 1: s = e.charCodeAt(b - 1) << 24 | 8388608; break; case 2: s = e.charCodeAt(b - 2) << 24 | e.charCodeAt(b - 1) << 16 | 32768; break; case 3: s = e.charCodeAt(b - 3) << 24 | e.charCodeAt(b - 2) << 16 | e.charCodeAt(b - 1) << 8 | 128; break } w.push(s); while (w.length % 16 != 14) w.push(0); w.push(b >>> 29); w.push(b << 3 & 4294967295); for (n = 0; n < w.length; n += 16) { for (s = 0; s < 16; s++) u[s] = w[n + s]; for (s = 16; s <= 79; s++) u[s] = t(u[s - 3] ^ u[s - 8] ^ u[s - 14] ^ u[s - 16], 1); p = a; d = f; v = l; m = c; g = h; for (s = 0; s <= 19; s++) { y = t(p, 5) + (d & v | ~d & m) + g + u[s] + 1518500249 & 4294967295; g = m; m = v; v = t(d, 30); d = p; p = y } for (s = 20; s <= 39; s++) { y = t(p, 5) + (d ^ v ^ m) + g + u[s] + 1859775393 & 4294967295; g = m; m = v; v = t(d, 30); d = p; p = y } for (s = 40; s <= 59; s++) { y = t(p, 5) + (d & v | d & m | v & m) + g + u[s] + 2400959708 & 4294967295; g = m; m = v; v = t(d, 30); d = p; p = y } for (s = 60; s <= 79; s++) { y = t(p, 5) + (d ^ v ^ m) + g + u[s] + 3395469782 & 4294967295; g = m; m = v; v = t(d, 30); d = p; p = y } a = a + p & 4294967295; f = f + d & 4294967295; l = l + v & 4294967295; c = c + m & 4294967295; h = h + g & 4294967295 } var y = r(a) + r(f) + r(l) + r(c) + r(h); return y.toLowerCase() } }) })(jQuery)
</script>

<script type="text/javascript">

    (function ($) {

        window.userData = '';
        window.token = '';

        /* --- unit test --- */
        $("#testWebService").submit(function (evt) {
            evt.preventDefault();
            var exc = myException(''),
                data = dataResult(),
                datah = {html:''},
                ajaxUrl = '',
                post = {},
                elmResult = null;

            elmResult = $('#resultData');
            elmResult.empty();

            //ping
            ajaxUrl = getUrl('ping');
            exc = ajaxHtml(ajaxUrl, datah);
            if (exc.result == false) { //--- nejaká chyba
                elmResult.append('Ping: <p style="color: red;">' + exc.description + '</p>');
            } else {
                elmResult.html('<br/>Ping: <p style="color: blue;">' + datah.html + '</p>');
            }

            //get salt for sha1 hash
            data = dataResult();
            post = { username: $('#settName').val() };
            ajaxUrl = getUrl('GetLoginSalt');
            exc = ajaxPost(ajaxUrl, data, post);
            if (exc.result == false) { //--- nejaká chyba
                elmResult.append('Salt: <p style="color: red;">' + exc.description + '</p>');
            } else {
                window.token = data.data;
                elmResult.append('Salt: <p style="color: blue;">' + data.data + '</p>');
            }


            //login
            post = { username: $('#settName').val(), password: $.sha1(data.data + $('#settPassword').val()) };
            data = dataResult();
            ajaxUrl = getUrl('LoginUser');
            exc = ajaxPost(ajaxUrl, data, post);
            if (exc.result == false) { //--- nejaká chyba
                elmResult.append('Token: <p style="color: red;">' + exc.description + '</p>');
            } else {
                window.token = data.data;
                elmResult.append('Token: <p style="color: blue;">' + data.data + '</p>');
            }


            // is login test
            data = dataResult();
            ajaxUrl = getUrl('IsLogin?ud=' + window.token);
            exc = ajaxGet(ajaxUrl, data);
            if (exc.result == false) { //--- nejaká chyba
                elmResult.append('Is Login: <p style="color: red;">FALSE</p>');
            } else {
                elmResult.append('Is Login: <p style="color: blue;">TRUE</p>');
            }


            // method
            data = dataResult();
            post = { GetItems: true };
            ajaxUrl = getUrl('GetBillsOpen');
            exc = ajaxPost(ajaxUrl, data, post);
            if (exc.result == false) { //--- nejaká chyba
                elmResult.append('Zoznam otvorených účtov: <p style="color: red;">' + exc.description + '</p>');
            } else {
                elmResult.append('<p style="color: Purple;">Zoznam otvorených účtov: </p>');
                var str = '<table border="0" class="tb"><thead><tr><th>IDNum</th><th>Predajné miesto</th><th>Názov stola</th><th class="right">Suma [EUR]</th></tr></thead><tbody>';
                data.data.forEach(function (item, index) {
                    str += '<tr>';
                    str += '<td>' + item.IDNum + '</td>';
                    str += '<td>' + item.SalesPoint + '</td>';
                    str += '<td>' + item.Name + '</td>';
                    str += '<td class="right">' + item.TotalPrice + '</td>';
                    str += '</tr>';
                });
                str += '</tbody></table>';
                elmResult.append(str);
            }


            // logout
            ajaxUrl = getUrl('Logout?ud=' + window.token);
            exc = ajaxGet(ajaxUrl, data);
            if (exc.result == false) { //--- nejaká chyba
                elmResult.append('<br/>Logout: OK<br/>');
            } else {
                elmResult.append('<br/>Logout: OK<br/>');
            }

        });

        function getUrl(method) {
            return 'http://' + $('#settAddress').val() + '/' + method;
        }

        function ajaxGet(ajaxurl, rfResult, jdata, processdata) {
            var exc = myException('');
            if (!processdata) { processdata = false; }
            if (!jdata) { jdata = null; }
            $.ajax({ type: 'GET', cache: false, async: false,
                dataType: 'json', contentType: 'application/json; charset=utf-8',
                url: ajaxurl, processData: processdata,
                data: JSON.stringify(jdata), //--- musí byt konverzia na text,
                beforeSend: function (xhr) {
                    xhr.setRequestHeader('userData', window.userData);
                },
                success: function (data, textStatus, xhr) {
                    dataResultGet(data, rfResult);
                    if (rfResult.result == false && rfResult.errNumber === 2) {
                        // chyba užívateľ nie je prihlásený
                    }
                    window.userData = xhr.getResponseHeader('userData');
                    exc.result = true;//--- default je true
                    if (rfResult.result == false) {
                        exc.result = false;
                        exc.errNumber = rfResult.errNumber;
                        exc.description = rfResult.description;
                    }                
                },
                error: function (xhr, exception, errorThrown) {
                    exc = z_GetAjaxException(xhr, exception, errorThrown);
                }
            });
            return exc;
        }

        function ajaxPost(ajaxurl, rfResult, jdata, processdata) {
            var exc = myException('');
            if (!processdata) { processdata = false; }
            if (!jdata) { jdata = null; }
            $.ajax({
                type: 'POST', cache: false, async: false,
                dataType: 'json', contentType: 'application/json; charset=utf-8',
                url: ajaxurl, processData: processdata,
                data: JSON.stringify(jdata), //--- musí byt konverzia na text,
                beforeSend: function (xhr) {
                    xhr.setRequestHeader('userData', window.userData);
                },
                success: function (data, textStatus, xhr) {
                    dataResultGet(data, rfResult);
                    if (rfResult.result == false && rfResult.errNumber === 2) {
                        // chyba užívateľ nie je prihlásený
                    }
                    window.userData = xhr.getResponseHeader('userData');
                    exc.result = true;//--- default je true
                    if (rfResult.result == false) {
                        exc.result = false;
                        exc.errNumber = rfResult.errNumber;
                        exc.description = rfResult.description;
                    }
                },
                error: function (xhr, exception, errorThrown) {
                    exc = z_GetAjaxException(xhr, exception, errorThrown);
                }
            });
            return exc;
        }

        function ajaxHtml(ajaxurl, rfResult, callType, jdata) {
            var exc = myException('');
            if (!callType) { callType = 'GET'; }
            $.ajax({
                type: callType, url: ajaxurl, cache: false, async: false,
                dataType: 'html', contentType: 'text/html; charset=utf-8',
                processData: false, data: JSON.stringify(jdata),
                beforeSend: function (xhr) {
                    xhr.setRequestHeader('userData', window.userData);
                },
                success: function (data, textStatus, xhr) {
                    window.userData = xhr.getResponseHeader('userData');
                    rfResult.html = data;
                    exc.result = true;
                },
                error: function (xhr, exception, errorThrown) {
                    exc = z_GetAjaxException(xhr, exception, errorThrown);
                }
            });
            return exc;
        }

        /* --- Support methods --- */

        function myException(descr, msg, errNum, res) { //exception object
            return { result: !res ? false : res, errNumber: !errNum ? 0 : errNum, message: !msg ? '' : msg, description: !descr ? '' : descr };
        };

        function dataResult() { //data result object
            return { result: false, errNumber: 0, description: '', data: null };
        };
        function dataResultGet(data, rfResult) {//rfResult musí byť inicializovaný pomocou 'dataResult'
            rfResult.result = data.result;
            rfResult.errNumber = data.errNumber;
            rfResult.description = data.description;
            rfResult.data = data.data;
        }

        function z_GetAjaxException(jqXHR, exception, errorThrown) {
            var exc = myException();

            if (jqXHR.status === 0) {
                exc = myException('Server webovej služby je v tejto chvíli nedostupný.', '', 111);
            } else if (jqXHR.status == 404) {
                exc = myException('Metóda pre spracovanie požiadavky nebola nájdená.', '', 404);
            } else if (jqXHR.status == 500) {
                exc = myException('Interná chyba servera webovej služby.', '', 500);
            } else if (exception === 'parsererror') {
                exc = myException('Chyba pre spracovaní JSON dát zo servera.', '', 900);
            } else if (exception === 'timeout') {
                exc = myException('Čas pre spracovanie požiadavky vypršal.', '', 901);
            } else if (exception === 'abort') {
                exc = myException('Asynchrónne volanie bolo prerušené.', '', 902);
            } else {
                exc = myException('Neznáma chyba.<br/>' + jqXHR.statusText, '', 99);
            }
            return exc;
        }

    })(jQuery);

</script>

</body>
</html>
Example
Url: http://address:port/LoginUserEx
See Also