kzen.dev
  • Întrebări
  • Tag-uri
  • Utilizatori
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
 Olegas
Olegas
Question

Amazon S3 direct upload din browser-ul client - cheie privată divulgarea

Am'm de punere în aplicare un fișier direct incarca de la calculator client pentru Amazon S3, prin intermediul REST API folosind doar JavaScript, fără nici un cod server-side. Toate funcționează bine, dar un singur lucru mă îngrijorează pe mine...

Când am trimite o cerere la Amazon S3 REST API, am nevoie pentru a semna cererea și de a pune o semnătură în "Autentificare" antet. Pentru a crea o semnătură, trebuie să-mi folosesc cheia secretă. Dar toate lucrurile se întâmplă pe partea de client, deci, cheia secretă pot fi ușor de arătat la pagina sursa (chiar dacă am obfuscate/cripta sursele mele).

Cum pot rezolva asta? Și este o problemă la toate? Poate pot limita cod privat specific de utilizare numai pentru REST API apeluri de la un anumit CORS Origine și de a PUNE doar și POST metode sau poate link-ul de cheie doar S3 și specifice găleată? Poate există alte metode de autentificare?

"fără server" soluție este ideală, dar pot să ia în considerare implicarea unele serverside de prelucrare, cu excepția încărcarea unui fișier pe server și apoi trimite la S3.

145 2013-07-11T05:44:37+00:00 9
 Rory
Rory
Întrebarea editată 25 august 2014 в 9:32
Programare
authentication
javascript
amazon
amazon-web-services
amazon-s3
Solution / Answer
 secretmike
secretmike
15 iulie 2013 в 9:56
2013-07-15T21:56:40+00:00
Mai mult
Sursă
Editează
#19890913

Cred că ceea ce vrei este Bazat pe Browser de Încărcări Folosind POST.

Practic, ai nevoie de cod server-side, dar tot nu este de a genera semnat politici. Odată ce client-side cod a semnat politică, se poate incarca folosind POSTA direct la S3 fără datele trec prin server.

Aici's oficială doc link-uri:

Diagrama: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingHTTPPOST.html

Exemplu de cod: http://docs.aws.amazon.com/AmazonS3/latest/dev/HTTPPOSTExamples.html

Semnat politica ar merge în html într-o formă de genul asta:

<html>
  <head>
    ...
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    ...
  </head>
  <body>
  ...
  <form action="http://johnsmith.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
    Key to upload: <input type="input" name="key" value="user/eric/" /><br />
    <input type="hidden" name="acl" value="public-read" />
    <input type="hidden" name="success_action_redirect" value="http://johnsmith.s3.amazonaws.com/successful_upload.html" />
    Content-Type: <input type="input" name="Content-Type" value="image/jpeg" /><br />
    <input type="hidden" name="x-amz-meta-uuid" value="14365123651274" />
    Tags for File: <input type="input" name="x-amz-meta-tag" value="" /><br />
    <input type="hidden" name="AWSAccessKeyId" value="AKIAIOSFODNN7EXAMPLE" />
    <input type="hidden" name="Policy" value="POLICY" />
    <input type="hidden" name="Signature" value="SIGNATURE" />
    File: <input type="file" name="file" /> <br />
    <!-- The elements after this will be ignored -->
    <input type="submit" name="submit" value="Upload to Amazon S3" />
  </form>
  ...
</html>

Notificare FORMĂ de acțiune este de a trimite fișierul direct la S3 - nu prin server.

De fiecare dată când unul dintre utilizatori vrea să încărcați un fișier, veți crea POLITICĂ " și " SEMNĂTURA de pe server. Vă întoarceți pagina pentru utilizator's browser-ul. Utilizatorul poate apoi să încărcați un fișier direct la S3, fără a trece prin server.

Atunci când vă conectați politica, de obicei face politica expiră după câteva minute. Aceasta obligă utilizatorii să vorbesc cu server-ul dvs. înainte de a încărca. Acest lucru vă permite să monitorizeze și să limiteze încărcări, dacă doriți.

Singurele date de gând să sau de la server-ul dvs. este semnat de Url-uri. Secretul cheile rămân secrete pe server.

 secretmike
secretmike
Răspuns editat 17 iulie 2013 в 2:15
203
0
 Joomler
Joomler
25 iunie 2015 в 4:18
2015-06-25T16:18:54+00:00
Mai mult
Sursă
Editează
#19890916

Puteți face acest lucru prin AWS S3 Cognito încercați acest link aici :

http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-examples.html#Amazon_S3

Încercați, de asemenea, acest cod

Doar schimba Regiunea, IdentityPoolId și găleata numele

<!DOCTYPE html>
<html>

<head>
    <title>AWS S3 File Upload</title>
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js"></script>
</head>

<body>
    <input type="file" id="file-chooser" />
    <button id="upload-button">Upload to S3</button>
    <div id="results"></div>
    <script type="text/javascript">
    AWS.config.region = 'your-region'; // 1. Enter your region

    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: 'your-IdentityPoolId' // 2. Enter your identity pool
    });

    AWS.config.credentials.get(function(err) {
        if (err) alert(err);
        console.log(AWS.config.credentials);
    });

    var bucketName = 'your-bucket'; // Enter your bucket name
    var bucket = new AWS.S3({
        params: {
            Bucket: bucketName
        }
    });

    var fileChooser = document.getElementById('file-chooser');
    var button = document.getElementById('upload-button');
    var results = document.getElementById('results');
    button.addEventListener('click', function() {

        var file = fileChooser.files[0];

        if (file) {

            results.innerHTML = '';
            var objKey = 'testing/' + file.name;
            var params = {
                Key: objKey,
                ContentType: file.type,
                Body: file,
                ACL: 'public-read'
            };

            bucket.putObject(params, function(err, data) {
                if (err) {
                    results.innerHTML = 'ERROR: ' + err;
                } else {
                    listObjs();
                }
            });
        } else {
            results.innerHTML = 'Nothing to upload.';
        }
    }, false);
    function listObjs() {
        var prefix = 'testing';
        bucket.listObjects({
            Prefix: prefix
        }, function(err, data) {
            if (err) {
                results.innerHTML = 'ERROR: ' + err;
            } else {
                var objKeys = "";
                data.Contents.forEach(function(obj) {
                    objKeys += obj.Key + "<br>";
                });
                results.innerHTML = objKeys;
            }
        });
    }
    </script>
</body>

</html>

Pentru mai multe detalii, vă Rugăm să verificați - Github

 Joomler
Joomler
Răspuns editat 20 iunie 2017 в 8:23
37
0
 BraveNewCurrency
BraveNewCurrency
14 iulie 2013 в 2:19
2013-07-14T14:19:47+00:00
Mai mult
Sursă
Editează
#19890912

Te're să spui că vrei un "fără server" soluție. Dar asta înseamnă că nu au capacitatea de a pune orice de "dvs." codul în buclă. (NOTĂ: Odată ce ați da codul de la un client, l's "lor" codul acum.) Blocare în jos CORS nu este de gând să vă ajute: Oamenii pot scrie cu ușurință un non-instrument bazat pe web (sau web-based proxy), care adaugă corectă CORS antet să abuzeze de sistemul dumneavoastră.

Problema mare este că puteți't diferenția între diferiți utilizatori. Puteți't permite unui utilizator pentru a lista/accesa fișierele sale, dar a împiedica pe alții de la a face așa. Dacă detectați abuz, nu este nimic care le puteți face despre el, cu excepția schimba cheia. (Care atacatorul poate, probabil, doar obține din nou.)

Cel mai bun pariu este de a crea un "IAM utilizator" cu o cheie pentru client javascript. Doar da acces de scriere la doar o găleată. (dar, în mod ideal, nu permite ListBucket funcționare, care va face mai atractive pentru atacatori.)

Daca ai avea un server (chiar și un simplu micro exemplu de la $20/luna), ai putea semna tastele de pe server-ul dvs. în timp ce de monitorizare/de prevenire a abuzurilor în timp real. Fără un server, tot ce puteți face este de a monitoriza periodic pentru abuz în după-the-faptul. Aici's ce-as face:

  1. rotiți periodic cheile pentru că IAM utilizator: în Fiecare noapte, de a genera o nouă cheie pentru care IAM utilizator, și de a înlocui cele mai vechi cheie. Deoarece există 2 chei, fiecare cheie va fi valabil timp de 2 zile.

  2. permite S3 logare, și de a descărca busteni la fiecare oră. Setați alerte pe "prea multe imagini" și "prea multe descărcări". Veți dori să verificați ambele total dimensiunea fișierului și numărul de fișiere încărcate. Și veți dori să monitorizeze atât global totaluri, și, de asemenea, per-adresa IP total (cu un prag mai mic).

Aceste controale se poate face "fără server" pentru a le putea rula pe desktop-ul tau. (de exemplu, S3 nu toate de lucru, aceste procese acolo doar pentru a alerta pentru abuz de găleată S3, astfel încât să don't obține un uriaș AWS proiect de lege la sfârșitul lunii.)

16
0
 RajeevJ
RajeevJ
3 octombrie 2016 в 8:01
2016-10-03T08:01:48+00:00
Mai mult
Sursă
Editează
#19890918

Adăugând mai multe informații la răspunsul acceptat, puteți face referire la blog-ul meu pentru a vedea o versiune de rulare de cod, folosind AWS Semnătura versiunea 4.

Voi rezuma aici:

De îndată ce utilizatorul selectează un fișier pentru a fi încărcate fotografii, face următoarele:

  1. Fac un apel la serverul de web pentru a iniția un serviciu pentru a genera necesare params

  2. În acest serviciu, face un apel la AWS IAM serviciu pentru a obține temporar cred

  3. Odată ce ai credibilitate, de a crea o găleată comună (base 64 codificate string). Apoi semn găleată cu politica temporară secret cheie de acces pentru a genera final semnătura

  4. trimite parametrii necesari înapoi la UI

  5. Odată ce acest lucru este primit, de a crea un formular html object, setați necesare params și POST-l.

Pentru informații detaliate, vă rugăm să consultați https://wordpress1763.wordpress.com/2016/10/03/browser-based-upload-aws-signature-version-4/

 RajeevJ
RajeevJ
Răspuns editat 3 octombrie 2016 в 9:50
10
0
 OlliM
OlliM
25 iulie 2013 в 11:38
2013-07-25T11:38:42+00:00
Mai mult
Sursă
Editează
#19890915

Pentru a crea o semnătură, trebuie să-mi folosesc cheia secretă. Dar toate lucrurile se întâmplă pe partea de client, deci, cheia secretă pot fi ușor de arătat de la sursa paginii (chiar dacă am obfuscate/cripta sursele mele).

Acest lucru este în cazul în care ai înțeles greșit. Motivul semnăturile digitale sunt utilizate este astfel încât să puteți verifica ceva la fel de corect, fără a dezvălui secretul tău cheie. În acest caz, semnătura digitală este folosit pentru a preveni utilizatorul de modificarea politicii ați setat-o pentru formularul de post.

Semnături digitale, cum ar fi cea de aici sunt folosite de securitate în jurul web. Dacă cineva (NSA?) într-adevăr au fost capabili de a renunța la ele, ar fi mult mai obiective decât găleată S3 :)

4
0
Nilesh Pawar
Nilesh Pawar
19 septembrie 2017 в 10:14
2017-09-19T10:14:16+00:00
Mai mult
Sursă
Editează
#19890919

Mi-au dat un cod simplu pentru a încărca fișiere de Javascript browser-ul pentru a AWS S3 și lista toate fișierele din găleată S3.

Etape:

  1. Să știi cum de a crea Crea IdentityPoolId http://docs.aws.amazon.com/cognito/latest/developerguide/identity-pools.html
  2. Du-te la S3's pagina consola și de a deschide cors de configurare de la găleată proprietăți și scrie următorul cod XML în care.

<?xml version="1.0" encoding="UTF-8"?>

IA PUNE ȘTERGEȚI CAP *
  1. Creați un fișier HTML care conține următorul cod modifica datele de autentificare, deschideți fișierul în browser-ul și bucurați-vă.
<script type="text/javascript"> AWS.config.regiune = 'ap-nord-1'; // Regiune AWS.config.acreditările = new AWS.CognitoIdentityCredentials({ IdentityPoolId: 'ap-nord-1:*****-*****', }); var găleată = new AWS.S3({ params: { Galeata: 'MyBucket' } });

var fileChooser = document.getElementById('fișier-selector'); var butonul = document.getElementById('incarca-buton'); var rezultat = document.getElementById('rezultatele');

funcția de încărcare() { fișier var = fileChooser.fișiere[0]; console.log(fișier.nume);

dacă (fișier) { rezultate.innerHTML = ''; var params = { Cheie: n + '.pdf', ContentType: fișierul.tip, Corp: fișier }; găleată.incarca(params, funcția(err, date) { rezultate.innerHTML = err ? 'EROARE!' : 'ÎNCĂRCATE.'; }); } else { rezultate.innerHTML = 'Nimic nu a încărca.'; } }

</script> <input type="fișier" id="fișier-selector" /> <input type="butonul" onclick="încărcați()" value="Încărcați la S3">
Nilesh Pawar
Nilesh Pawar
Răspuns editat 27 august 2018 в 10:18
4
0
Ruediger Jungbeck
Ruediger Jungbeck
21 iulie 2013 в 10:43
2013-07-21T10:43:19+00:00
Mai mult
Sursă
Editează
#19890914

Dacă tu nu't au orice server side cod, de securitate depinde de securitate de acces la cod JavaScript pe partea de client (de exemplu, toată lumea care are codul-ar incarca ceva).

Deci, aș recomanda, pur și simplu a crea un special găleată S3 care este publică inscriptibile (dar nu poate fi citit), astfel încât să don't nevoie de nici semnat componente pe partea de client.

Găleată numele (un GUID de exemplu) va fi singura ta apărare împotriva malware încărcări (dar un potențial atacator nu poate folosi galeata pentru transferul de date, pentru că este scris numai pentru el)

Ruediger Jungbeck
Ruediger Jungbeck
Răspuns editat 8 mai 2014 в 4:46
2
0
Samir Patel
Samir Patel
13 noiembrie 2018 в 4:51
2018-11-13T16:51:57+00:00
Mai mult
Sursă
Editează
#19890920

Aici este cum de a genera un document de politică folosind nod și fără server

"use strict";

const uniqid = require('uniqid');
const crypto = require('crypto');

class Token {

    /**
     * @param {Object} config SSM Parameter store JSON config
     */
    constructor(config) {

        // Ensure some required properties are set in the SSM configuration object
        this.constructor._validateConfig(config);

        this.region = config.region; // AWS region e.g. us-west-2
        this.bucket = config.bucket; // Bucket name only
        this.bucketAcl = config.bucketAcl; // Bucket access policy [private, public-read]
        this.accessKey = config.accessKey; // Access key
        this.secretKey = config.secretKey; // Access key secret

        // Create a really unique videoKey, with folder prefix
        this.key = uniqid() + uniqid.process();

        // The policy requires the date to be this format e.g. 20181109
        const date = new Date().toISOString();
        this.dateString = date.substr(0, 4) + date.substr(5, 2) + date.substr(8, 2);

        // The number of minutes the policy will need to be used by before it expires
        this.policyExpireMinutes = 15;

        // HMAC encryption algorithm used to encrypt everything in the request
        this.encryptionAlgorithm = 'sha256';

        // Client uses encryption algorithm key while making request to S3
        this.clientEncryptionAlgorithm = 'AWS4-HMAC-SHA256';
    }

    /**
     * Returns the parameters that FE will use to directly upload to s3
     *
     * @returns {Object}
     */
    getS3FormParameters() {
        const credentialPath = this._amazonCredentialPath();
        const policy = this._s3UploadPolicy(credentialPath);
        const policyBase64 = new Buffer(JSON.stringify(policy)).toString('base64');
        const signature = this._s3UploadSignature(policyBase64);

        return {
            'key': this.key,
            'acl': this.bucketAcl,
            'success_action_status': '201',
            'policy': policyBase64,
            'endpoint': "https://" + this.bucket + ".s3-accelerate.amazonaws.com",
            'x-amz-algorithm': this.clientEncryptionAlgorithm,
            'x-amz-credential': credentialPath,
            'x-amz-date': this.dateString + 'T000000Z',
            'x-amz-signature': signature
        }
    }

    /**
     * Ensure all required properties are set in SSM Parameter Store Config
     *
     * @param {Object} config
     * @private
     */
    static _validateConfig(config) {
        if (!config.hasOwnProperty('bucket')) {
            throw "'bucket' is required in SSM Parameter Store Config";
        }
        if (!config.hasOwnProperty('region')) {
            throw "'region' is required in SSM Parameter Store Config";
        }
        if (!config.hasOwnProperty('accessKey')) {
            throw "'accessKey' is required in SSM Parameter Store Config";
        }
        if (!config.hasOwnProperty('secretKey')) {
            throw "'secretKey' is required in SSM Parameter Store Config";
        }
    }

    /**
     * Create a special string called a credentials path used in constructing an upload policy
     *
     * @returns {String}
     * @private
     */
    _amazonCredentialPath() {
        return this.accessKey + '/' + this.dateString + '/' + this.region + '/s3/aws4_request';
    }

    /**
     * Create an upload policy
     *
     * @param {String} credentialPath
     *
     * @returns {{expiration: string, conditions: *[]}}
     * @private
     */
    _s3UploadPolicy(credentialPath) {
        return {
            expiration: this._getPolicyExpirationISODate(),
            conditions: [
                {bucket: this.bucket},
                {key: this.key},
                {acl: this.bucketAcl},
                {success_action_status: "201"},
                {'x-amz-algorithm': 'AWS4-HMAC-SHA256'},
                {'x-amz-credential': credentialPath},
                {'x-amz-date': this.dateString + 'T000000Z'}
            ],
        }
    }

    /**
     * ISO formatted date string of when the policy will expire
     *
     * @returns {String}
     * @private
     */
    _getPolicyExpirationISODate() {
        return new Date((new Date).getTime() + (this.policyExpireMinutes * 60 * 1000)).toISOString();
    }

    /**
     * HMAC encode a string by a given key
     *
     * @param {String} key
     * @param {String} string
     *
     * @returns {String}
     * @private
     */
    _encryptHmac(key, string) {
        const hmac = crypto.createHmac(
            this.encryptionAlgorithm, key
        );
        hmac.end(string);

        return hmac.read();
    }

    /**
     * Create an upload signature from provided params
     * https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html#signing-request-intro
     *
     * @param policyBase64
     *
     * @returns {String}
     * @private
     */
    _s3UploadSignature(policyBase64) {
        const dateKey = this._encryptHmac('AWS4' + this.secretKey, this.dateString);
        const dateRegionKey = this._encryptHmac(dateKey, this.region);
        const dateRegionServiceKey = this._encryptHmac(dateRegionKey, 's3');
        const signingKey = this._encryptHmac(dateRegionServiceKey, 'aws4_request');

        return this._encryptHmac(signingKey, policyBase64).toString('hex');
    }
}

module.exports = Token;

Configurația obiect folosit este stocat în MUS Parametru Magazin și se pare că acest

{
    "bucket": "my-bucket-name",
    "region": "us-west-2",
    "bucketAcl": "private",
    "accessKey": "MY_ACCESS_KEY",
    "secretKey": "MY_SECRET_ACCESS_KEY",
}
1
0
 Jason
Jason
3 aprilie 2016 в 7:42
2016-04-03T07:42:36+00:00
Mai mult
Sursă
Editează
#19890917

Dacă sunteți dispus să utilizeze un serviciu 3rd party, auth0.com acceptă această integrare. La auth0 schimburi de servicii un 3rd petrecere SSO serviciu de autentificare pentru un AWS sesiune temporară token va permisiuni limitate.

A se vedea: https://github.com/auth0-samples/auth0-s3-sample/ și auth0 de documentare.

0
0
Comunități asemănătoare 2
JavaScript, România - Moldova
JavaScript, România - Moldova
288 utilizatori
Comunitatea Română JavaScript: github.com/js-ro Pentru confort, opriți notificările. Parteneri: @php_ro, @python_ro, @devops_ro, @seo_ro Offtop: @holywars_ro
Deschide telegram
DevOps - comunitatea Română
DevOps - comunitatea Română
15 utilizatori
Vorbim despre Kubernetes, CI/CD, Linux, docker, monitorizare, Cloud services, Prometheus, network și orice alte teme legate de administrarea serverelor.
Deschide telegram
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
Utilizatori
Toate
Nou
Populare
1
ALEX EPRST
Înregistrat 12 ore în urmă
2
Daniel Gogov
Înregistrat 1 săptămână în urmă
3
工藤 芳則
Înregistrat 2 săptămâni în urmă
4
Ирина Беляева
Înregistrat 2 săptămâni în urmă
5
Darya Arsenyeva
Înregistrat 3 săptămâni în urmă
ES
ID
JA
KO
RO
RU
© kzen.dev 2023
Sursă
stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire