By default, all S3 buckets and objects are private and only the account that owns the objects has permissions to access them. You can however generate pre-signed url for the S3 objects and share it with anyone. Generating pre-signed url requires valid security credentials.
In this example, I have an object welcome.html in my S3 bucket named aws-presigned.

S3 object welcome.html is currently not accessible from the browser.

To generate pre-signed url for welcome.html, I used the command:
aws s3 presign –expires-in 30 s3://aws-presigned/welcome.html where 30 is the expiration time in seconds and aws-presigned/welcome.html is the object key.
The EC2 Instance that I used to generate pre-signed URL has access to S3 through an IAM role. Thus the credentials used to generate this pre-signed url are from the IAM role.

Copy the pre-signed url generated from above command into the browser and voila!! The welcome.html file is now accessible. You can share this pre-signed url with anyone that requires access to the object.

The url is valid only for the expiration duration specified in the request. After the duration has expired, you will see the below output from the pre-signed url.

Thus using pre-signed url, you can securely share S3 objects with users that do not have AWS account without making the bucket or objects public.