AmazonS3 授權(quán) java

平時(shí)在開(kāi)發(fā)中有這樣一種場(chǎng)景夯膀,一個(gè)賬號(hào)動(dòng)態(tài)創(chuàng)建桶并生成對(duì)象继蜡;另外一個(gè)只讀賬號(hào)回俐,只有獲取對(duì)象的權(quán)限。這個(gè)時(shí)候稀并,AmazonS3 需要每創(chuàng)建一個(gè)桶仅颇,就要給只讀賬號(hào)授權(quán)一次。如果桶是經(jīng)常創(chuàng)建的碘举,通過(guò)管理界面控制臺(tái),都這樣授權(quán)忘瓦,不是很方便,也容易忘記做授權(quán)引颈。這個(gè)時(shí)候耕皮,我們可以通過(guò)sdk,在創(chuàng)建桶和上傳對(duì)象的時(shí)候蝙场,給相應(yīng)的只讀賬號(hào)授權(quán)凌停,讓其具有讀對(duì)象的權(quán)限。
讀寫賬號(hào):user-rw
只讀賬號(hào):user-read

1.用讀寫賬號(hào)的創(chuàng)建桶的時(shí)候售滤,授權(quán)只讀賬號(hào)能讀取桶的權(quán)限

 // 創(chuàng)建桶
    public Bucket creatingBucket(String bucketName)
    {
        Bucket bucket = null;
        try {
            bucket = xskyS3Base.getAmazonS3().createBucket(bucketName);
        }catch (AmazonServiceException ase) {
            log.error("Caught an AmazonServiceException when create buket:{} Error Message:{},HTTP Status Code:{}," +
                            "AWS Error Code:{},Error Type:{},Request ID:{}",bucketName,
                    ase.getMessage(),ase.getStatusCode(),ase.getErrorCode(),ase.getErrorType(),ase.getRequestId());
            throw new RRException("creatingBucket "+bucketName+" fail");
        }
        grantsBucketAcl(bucketName);
        return bucket;
    }

    public void grantsBucketAcl(String bucketName){
        try {
            String readUser = "user-read"
            if(StringUtils.isNotBlank(readUser)){
                AccessControlList acl = xskyS3Base.getAmazonS3().getBucketAcl(bucketName); //獲取桶的權(quán)限信息
                if(acl!=null){
                    Grantee grantee = new CanonicalGrantee(readUser);
                    acl.grantPermission(grantee,Permission.Read);//授權(quán)可讀
                    xskyS3Base.getAmazonS3().setBucketAcl(bucketName,acl);
                   
                    log.info("桶用戶:{}授權(quán)成功",readUser);
                }else{
                    log.error("通過(guò)桶:{}查詢不到acl信息",bucketName);
                }
            }
        } catch (SdkClientException e) {
            log.error("授權(quán)失敗",e);
        }
    }
  1. 初始化amazons3
import com.amazonaws.AmazonClientException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.chain.common.config.KsKyConifg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;


@Component
@Slf4j
public class XskyS3Base {

    @Autowired
    private KsKyConifg ksKyConifg;
    private AmazonS3 client = null;

    @PostConstruct
    private void init(){
        client = intXskyS3Basic(ksKyConifg.getServiceUrl(),ksKyConifg.getKeyId(),ksKyConifg.getKeySecret());
    }


    public AmazonS3 getAmazonS3(){
        return client;
    }
    //創(chuàng)建連接
    private AmazonS3 intXskyS3Basic(String serverUrl, String access_key, String secret_key) {
        AWSCredentials credentials = null;
        try {
            credentials = new BasicAWSCredentials(access_key, secret_key);
        } catch (Exception e) {
            log.error("Authentication failed access_key:{},secret_key:{}",access_key,secret_key,e);
            throw new AmazonClientException(
                    "Authentication failed access_key:"+access_key+",secret_key:"+secret_key, e);
        }
        //初始化S3 configure 的實(shí)例
        ClientConfiguration config = new ClientConfiguration();
        config.setProtocol(Protocol.HTTP);
        config.setUseExpectContinue(false);
        config.setMaxConnections(ksKyConifg.getClientMaxConnections());                // 最大連接數(shù) 200
        config.setConnectionTimeout(ksKyConifg.getClientConnectionTimeout());//10000
        config.setSocketTimeout(ksKyConifg.getClientSocketTimeout());//30000
        config.setConnectionTTL(ksKyConifg.getClientConnectionTTL());        // CPoolEntry 最大有效值.2 * 60 * 1000
        config.setConnectionMaxIdleMillis(ksKyConifg.getClientConnectionMaxIdleMillis());  // 客戶端能接受的最大 Keep-Alive 值 60 * 1000

        config.withUseExpectContinue(false);
        config.withSignerOverride("S3SignerType");
        AwsClientBuilder.EndpointConfiguration end_point = new AwsClientBuilder.EndpointConfiguration(serverUrl, "us-east-1");
        //創(chuàng)建連接,替換原AmazonS3Client接口
        client = AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withClientConfiguration(config)
                .withEndpointConfiguration(end_point)
                .withPathStyleAccessEnabled(true)
                .build();
        return client;
    }
}

3.上傳對(duì)象并授予權(quán)限

   public PutObjectResult putObject(String bucketName, String key, File file)
    {
        PutObjectResult putResult = null;
        try {
            ObjectMetadata metadata = new ObjectMetadata();
            PutObjectRequest putRequest = new PutObjectRequest(bucketName, key, file);
                //設(shè)置認(rèn)證只讀,這種授權(quán)需要有賬號(hào)的方式才能讀取
                putRequest.setCannedAcl(CannedAccessControlList.AuthenticatedRead);
                //還有種CannedAccessControlList.PublicRead罚拟,這個(gè)打開(kāi)台诗,會(huì)再瀏覽器地址能直接打開(kāi)下載錄音
            putResult = xskyS3Base.getAmazonS3().putObject(putRequest);
        }catch(AmazonServiceException ase) {
            log.error("Caught an AmazonServiceException when put object of:{} Error Message:{},HTTP Status Code:{}," +
                            "AWS Error Code:{},Error Type:{},Request ID:{} error:{}",key,
                    ase.getMessage(),ase.getStatusCode(),ase.getErrorCode(),ase.getErrorType(),ase.getRequestId(),ase.getErrorMessage(),ase);
            throw new RRException("putObject to bucket:"+bucketName+",key:"+key+" fail");
        }
        return putResult;
    }

另外一種方式,也在給每個(gè)對(duì)象設(shè)置權(quán)限赐俗;這種方式需要對(duì)象上傳后拉队,再設(shè)置。這種方式的缺點(diǎn)就是阻逮,單獨(dú)授權(quán)的時(shí)候粱快,需要另外再發(fā)起一次網(wǎng)絡(luò)請(qǐng)求授權(quán)

 //對(duì)每個(gè)對(duì)象進(jìn)行授權(quán)
    public void grantsObject(String bucketName,String key){
        try {
            String readUser = "user-read";
            if(StringUtils.isNotBlank(readUser)&&StringUtils.isNotBlank(bucketName)&&StringUtils.isNotBlank(key)){
                AccessControlList acl =  xskyS3Base.getAmazonS3().getObjectAcl(bucketName,key);
                if(acl!=null){
                    Grantee grantee = new CanonicalGrantee(readUser);
                    acl.grantPermission(grantee,Permission.Read);
                    xskyS3Base.getAmazonS3().setObjectAcl(bucketName,key,acl);
                    log.info("授權(quán)對(duì)象的只讀賬號(hào)");
                }else{
                    log.error("根據(jù)桶:{}和key:{}查詢不到對(duì)象的acl信息無(wú)法對(duì)只讀賬號(hào)授權(quán)對(duì)象權(quán)限失敗",bucketName,key);
                }
            }
        } catch (SdkClientException e) {
            log.error("只讀賬號(hào)授權(quán)對(duì)象權(quán)限失敗,桶:{}和key:{}",bucketName,key,e);
        }
    }

其他授權(quán)通知
1.EmailAddressGrantee,可以將對(duì)象發(fā)送到某個(gè)郵件地址

  1. GroupGrantee 組授權(quán)

直接生成公共的url地址

 xskyS3Base.getAmazonS3().setObjectAcl(bucketName, key,CannedAccessControlList.PublicRead);
            //獲取一個(gè)request
            GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(bucketName, key);
            //生成公用的url
            URL url = xskyS3Base.getAmazonS3().generatePresignedUrl(urlRequest);

生成過(guò)期時(shí)間的對(duì)象

  GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(bucketName, key);
            java.util.Date expiration = new java.util.Date();
            long milliSeconds = expiration.getTime();
            milliSeconds += 1000 * 60 * 60; // Add 1 hour.
            expiration.setTime(milliSeconds);
            urlRequest.setExpiration(expiration); //設(shè)置過(guò)期時(shí)間
            URL url = xskyS3Base.getAmazonS3().generatePresignedUrl(urlRequest);
            
            UploadObject(url);
            
            
         public static void UploadObject(URL url) throws IOException
    {
        HttpURLConnection connection=(HttpURLConnection) url.openConnection();
        connection.setDoOutput(true);
        connection.setRequestMethod("PUT");
        OutputStreamWriter out = new OutputStreamWriter(
                connection.getOutputStream());
        out.write("This text uploaded as object.");
        out.close();
        int responseCode = connection.getResponseCode();
        System.out.println("Service returned response code " + responseCode);

    }

參考:
https://zhuanlan.zhihu.com/p/194272308
https://blog.csdn.net/hellozhxy/article/details/84070837
https://blog.csdn.net/anhuidelinger/article/details/9831861

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夺鲜,一起剝皮案震驚了整個(gè)濱河市皆尔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌币励,老刑警劉巖慷蠕,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異食呻,居然都是意外死亡流炕,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門仅胞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)每辟,“玉大人,你說(shuō)我怎么就攤上這事干旧∏郏” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵椎眯,是天一觀的道長(zhǎng)挠将。 經(jīng)常有香客問(wèn)我,道長(zhǎng)编整,這世上最難降的妖魔是什么舔稀? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮掌测,結(jié)果婚禮上内贮,老公的妹妹穿的比我還像新娘。我一直安慰自己汞斧,他們只是感情好夜郁,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著断箫,像睡著了一般拂酣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仲义,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天婶熬,我揣著相機(jī)與錄音剑勾,去河邊找鬼。 笑死赵颅,一個(gè)胖子當(dāng)著我的面吹牛虽另,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播饺谬,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼捂刺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了募寨?” 一聲冷哼從身側(cè)響起族展,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拔鹰,沒(méi)想到半個(gè)月后仪缸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡列肢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年恰画,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓷马。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拴还,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欧聘,到底是詐尸還是另有隱情片林,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布怀骤,位于F島的核電站拇厢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏晒喷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一访敌、第九天 我趴在偏房一處隱蔽的房頂上張望凉敲。 院中可真熱鬧,春花似錦寺旺、人聲如沸爷抓。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蓝撇。三九已至,卻和暖如春陈莽,著一層夾襖步出監(jiān)牢的瞬間渤昌,已是汗流浹背虽抄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留独柑,地道東北人迈窟。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像忌栅,于是被迫代替她去往敵國(guó)和親车酣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容