AWS 资源授权(Java)-获取S3上传token

目的

最近小编所在公司,项目要迁移到海外,很多之前国内使用的云服务(阿里云,百度云,腾讯云) 要更好成amazon。
aws的文档真的是一言难尽,所以小编整理了一些 aws 使用场景,方便大家参考和cv。

AWS 资源授权

资源授权以S3为例

场景

前端需要将图片上传的S3存储桶中,肯定不能直接给前端一对accessKey 和 secretKey 。
所以后端需要提供一个 有过期时间的S3存储桶的token,前端拿到这个token 作为上传凭证。

详情
  1. 引包
    使用v2版本
 </dependencyManagement>
		</dependencies>
             <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>2.16.60</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
     <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>sts</artifactId>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
        </dependency>
    </dependencies>
  1. 配置类
    前提需要有一对一对accessKey 和 secretKey ,并且该用户需要拥有sts:GetFederationToken 这个策略。
    上代码:
/**
 * @Author 
 * @Date: 2022/05/13/ 14:58
 * @Description
 */
@Data
@Service
@Configuration
public class AwsConfig {
    @Value("${aws.accessKey:}")
    private String accessKey;
    @Value("${aws.secretKey:}")
    private String secretKey;
    @Value("${aws.s3.env:}")
    private String env;
    @Value("${aws.s3.localRecord.region:}")
    private String localRecordRegion;
    @Value("${aws.s3.localRecord.bucket:}")
    private String localRecordBucket;
    @Value("${aws.s3.localRecord.durationSeconds:}")
    private Integer localRecordDurationSeconds;
    @Value("${aws.s3.localRecord.tempUserName:localRecordTemp}")
    private String localRecordTempUserName;
    @Value("${aws.s3.localRecord.host:}")
    private String localRecordHost;
    @Value("#{'${aws.sts.localRecord.action:}'.split(',')}")
    private List<String> localRecordStsAction;

    @Bean
    public StsClient stsClient() {
        AwsBasicCredentials awsCreds = AwsBasicCredentials.create(this.accessKey, this.secretKey);
        return StsClient.builder().credentialsProvider(StaticCredentialsProvider.create(awsCreds))
            .region(Region.of(this.localRecordRegion)).build();
    }
}

  1. Controller接口
@Slf4j
@Controller
@RequestMapping("/data")
public class FileController extends DataBaseController {

    @Resource
    private StsClient stsClient;
    @Autowired
    private AwsConfig awsConfig;
    @Autowired
    private RedisService redisService;

    @GetMapping("/local_record/s3_token")
    @ResponseBody
    public ResponseEntity<Response<LocalRecordUploadTokenVo>> getS3UploadToken(HttpServletRequest request) {
        Response<LocalRecordUploadTokenVo> response = new Response<>();
        HttpHeaders headers = new HttpHeaders();
        headers.setAccessControlAllowOrigin("*");
        LocalRecordUploadTokenVo uploadTokenCacheVo =
            redisService.get(RedisConstant.LOCAL_RECORD_S3_TOKEN, LocalRecordUploadTokenVo.class);
        if (uploadTokenCacheVo != null
            && uploadTokenCacheVo.getExpiredTime() > System.currentTimeMillis() / 1000 + 1200) {
            response.success().data(uploadTokenCacheVo);
            return new ResponseEntity<>(response, headers, HttpStatus.OK);
        }
        String policy = String.format(
            "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":%s,\"Resource\":\"arn:aws:s3:::%s/%s/*\"}]}",
            awsConfig.getLocalRecordStsAction(), awsConfig.getLocalRecordBucket(), awsConfig.getEnv());
        GetFederationTokenRequest build =
            GetFederationTokenRequest.builder().name(awsConfig.getLocalRecordTempUserName()).policy(policy)
                .durationSeconds(awsConfig.getLocalRecordDurationSeconds()).build();
        LocalRecordUploadTokenVo tokenVo;
        try {
            GetFederationTokenResponse federationToken = stsClient.getFederationToken(build);
            Credentials credentials = federationToken.credentials();
            tokenVo = new LocalRecordUploadTokenVo(federationToken.responseMetadata().requestId(), credentials);
            tokenVo.setBucket(awsConfig.getLocalRecordBucket());
            tokenVo.setRegion(awsConfig.getLocalRecordRegion());
            response.success().data(tokenVo);
            redisService.set(RedisConstant.LOCAL_RECORD_S3_TOKEN, tokenVo, 600L);
        } catch (Exception e) {
            log.error("FileController::getS3UploadToken 获取上传签名失败", e);
            response.success().message(e.getMessage());
        }
        return new ResponseEntity<>(response, headers, HttpStatus.OK);
    }
   }
 这里加了redis缓存
 awsConfig.getLocalRecordStsAction() 的值为"s3:GetObject","s3:PutObject","s3:PutObjectAcl"
 awsConfig.getEnv() 为环境类型 如qa online
 代码仅供参考
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值