mirror of
				https://github.com/minio/minio.git
				synced 2025-10-30 00:05:02 -04:00 
			
		
		
		
	Merge pull request #1054 from harshavardhana/json-web
jwt: Deprecate RSA usage, use HMAC instead.
This commit is contained in:
		
						commit
						dfc84dd451
					
				
							
								
								
									
										39
									
								
								Browser.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								Browser.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| ## Minio Browser | ||||
| 
 | ||||
| Minio Browser uses Json Web Tokens to authenticate JSON RPC requests. | ||||
| 
 | ||||
| Initial request generates a token for 'AccessKey' and 'SecretKey' | ||||
| provided by the user. | ||||
| 
 | ||||
| <blockquote> | ||||
| Currently these tokens expire after 10hrs, this is not configurable yet. | ||||
| </blockquote> | ||||
| 
 | ||||
| ### Start minio server | ||||
| 
 | ||||
| ``` | ||||
| minio server <testdir> | ||||
| ``` | ||||
| 
 | ||||
| ### JSON RPC APIs. | ||||
| 
 | ||||
| JSON RPC namespace is `Web`. | ||||
| 
 | ||||
| #### Auth Operations | ||||
| 
 | ||||
| * Login - waits for 'username, password' and on success replies a new Json Web Token (JWT). | ||||
| * ResetToken - resets token, requires password and token. | ||||
| * Logout - currently a dummy operation. | ||||
| 
 | ||||
| #### Bucket/Object Operations. | ||||
| 
 | ||||
| * ListBuckets - lists buckets, requires a valid token. | ||||
| * ListObjects - lists objects, requires a valid token. | ||||
| * MakeBucket - make a new bucket, requires a valid token. | ||||
| * GetObjectURL - generates a URL for download access, requires a valid token. | ||||
|   (generated URL is valid for 1hr) | ||||
| * PutObjectURL - generates a URL for upload access, requies a valid token. | ||||
|   (generated URL is valid for 1hr) | ||||
| 
 | ||||
| #### Server Operations.  | ||||
| * DiskInfo - get backend disk statistics. | ||||
							
								
								
									
										61
									
								
								JWT.md
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								JWT.md
									
									
									
									
									
								
							| @ -1,61 +0,0 @@ | ||||
| ### Generate RSA keys for JWT | ||||
| 
 | ||||
| ``` | ||||
| mkdir -p ~/.minio/web | ||||
| ``` | ||||
| 
 | ||||
| ``` | ||||
| openssl genrsa -out ~/.minio/web/private.key 2048 | ||||
| ``` | ||||
| 
 | ||||
| ``` | ||||
| openssl rsa -in ~/.minio/web/private.key -outform PEM -pubout -out ~/.minio/web/public.key | ||||
| ``` | ||||
| ### Start minio server | ||||
| 
 | ||||
| ``` | ||||
| minio server <testdir> | ||||
| ``` | ||||
| 
 | ||||
| ### Implemented JSON RPC APIs. | ||||
| 
 | ||||
| Namespace `Web` | ||||
| 
 | ||||
| * Login - waits for 'username, password' and on success replies a new JWT token. | ||||
| * ResetToken - resets token, requires password and token. | ||||
| * Logout - currently a dummy operation. | ||||
| * ListBuckets - lists buckets, requires valid token. | ||||
| * ListObjects - lists objects, requires valid token. | ||||
| * GetObjectURL - generates a url for download access, requires valid token. | ||||
| 
 | ||||
| ### Now you can use `webrpc.js` to make requests. | ||||
| 
 | ||||
| - Login example | ||||
| ```js | ||||
| var webRPC = require('webrpc'); | ||||
| var web = new webRPC("http://localhost:9001/rpc") | ||||
| 
 | ||||
| // Generate JWT Token. | ||||
| web.Login({"username": "YOUR-ACCESS-KEY-ID", "password": "YOUR-SECRET-ACCESS-KEY"}) | ||||
|   .then(function(data) { | ||||
|     console.log("success : ", data); | ||||
|   }) | ||||
|   .catch(function(error) { | ||||
|     console.log("fail : ", error.toString()); | ||||
|   }); | ||||
| ``` | ||||
| 
 | ||||
| - ListBuckets example | ||||
| ```js | ||||
| var webRPC = require('webrpc'); | ||||
| var web = new webRPC("http://localhost:9001/rpc", "my-token") | ||||
| 
 | ||||
| // Generate Token. | ||||
| web.ListBuckets() | ||||
|   .then(function(data) { | ||||
|     console.log("Success : ", data); | ||||
|   }) | ||||
|   .catch(function(error) { | ||||
|     console.log("fail : ", error.toString()); | ||||
|   }); | ||||
| ``` | ||||
| @ -43,13 +43,13 @@ func (h authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||
| 	} | ||||
| 	// Validate Authorization header to be valid. | ||||
| 	jwt := InitJWT() | ||||
| 	token, err := jwtgo.ParseFromRequest(r, func(token *jwtgo.Token) (interface{}, error) { | ||||
| 		if _, ok := token.Method.(*jwtgo.SigningMethodRSA); !ok { | ||||
| 	token, e := jwtgo.ParseFromRequest(r, func(token *jwtgo.Token) (interface{}, error) { | ||||
| 		if _, ok := token.Method.(*jwtgo.SigningMethodHMAC); !ok { | ||||
| 			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) | ||||
| 		} | ||||
| 		return jwt.PublicKey, nil | ||||
| 		return jwt.secretAccessKey, nil | ||||
| 	}) | ||||
| 	if err != nil || !token.Valid { | ||||
| 	if e != nil || !token.Valid { | ||||
| 		w.WriteHeader(http.StatusUnauthorized) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										71
									
								
								jwt.go
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								jwt.go
									
									
									
									
									
								
							| @ -17,11 +17,7 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/rsa" | ||||
| 	"crypto/x509" | ||||
| 	"encoding/pem" | ||||
| 	"errors" | ||||
| 	"io/ioutil" | ||||
| 	"bytes" | ||||
| 	"time" | ||||
| 
 | ||||
| 	jwtgo "github.com/dgrijalva/jwt-go" | ||||
| @ -31,72 +27,47 @@ import ( | ||||
| 
 | ||||
| // JWT - jwt auth backend | ||||
| type JWT struct { | ||||
| 	// Public value. | ||||
| 	PublicKey *rsa.PublicKey | ||||
| 	// private values. | ||||
| 	privateKey      *rsa.PrivateKey | ||||
| 	accessKeyID     string | ||||
| 	secretAccessKey string | ||||
| 	accessKeyID     []byte | ||||
| 	secretAccessKey []byte | ||||
| } | ||||
| 
 | ||||
| // Default - each token expires in 10hrs. | ||||
| const ( | ||||
| 	jwtExpirationDelta = 10 | ||||
| 	tokenExpires time.Duration = 10 | ||||
| ) | ||||
| 
 | ||||
| // InitJWT - initialize. | ||||
| func InitJWT() *JWT { | ||||
| 	jwt := &JWT{ | ||||
| 		privateKey: getPrivateKey(), | ||||
| 	} | ||||
| 	// Validate if public key is of algorithm *rsa.PublicKey. | ||||
| 	var ok bool | ||||
| 	jwt.PublicKey, ok = jwt.privateKey.Public().(*rsa.PublicKey) | ||||
| 	if !ok { | ||||
| 		fatalIf(probe.NewError(errors.New("")), "Unsupported type of public key algorithm found.", nil) | ||||
| 	} | ||||
| 	// Load credentials configuration. | ||||
| 	jwt := &JWT{} | ||||
| 	// Load credentials. | ||||
| 	config, err := loadConfigV2() | ||||
| 	fatalIf(err.Trace("JWT"), "Unable to load configuration file.", nil) | ||||
| 
 | ||||
| 	// Save access, secret keys. | ||||
| 	jwt.accessKeyID = config.Credentials.AccessKeyID | ||||
| 	jwt.secretAccessKey = config.Credentials.SecretAccessKey | ||||
| 	jwt.accessKeyID = []byte(config.Credentials.AccessKeyID) | ||||
| 	jwt.secretAccessKey = []byte(config.Credentials.SecretAccessKey) | ||||
| 	return jwt | ||||
| } | ||||
| 
 | ||||
| // GenerateToken - generates a new Json Web Token based on the incoming user id. | ||||
| func (b *JWT) GenerateToken(userName string) (string, error) { | ||||
| 	token := jwtgo.New(jwtgo.SigningMethodRS512) | ||||
| func (jwt *JWT) GenerateToken(userName string) (string, *probe.Error) { | ||||
| 	token := jwtgo.New(jwtgo.SigningMethodHS512) | ||||
| 	// Token expires in 10hrs. | ||||
| 	token.Claims["exp"] = time.Now().Add(time.Hour * time.Duration(jwtExpirationDelta)).Unix() | ||||
| 	token.Claims["exp"] = time.Now().Add(time.Hour * tokenExpires).Unix() | ||||
| 	token.Claims["iat"] = time.Now().Unix() | ||||
| 	token.Claims["sub"] = userName | ||||
| 	tokenString, err := token.SignedString(b.privateKey) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	tokenString, e := token.SignedString(jwt.secretAccessKey) | ||||
| 	if e != nil { | ||||
| 		return "", probe.NewError(e) | ||||
| 	} | ||||
| 	return tokenString, nil | ||||
| } | ||||
| 
 | ||||
| // Authenticate - authenticates the username and password. | ||||
| func (b *JWT) Authenticate(username, password string) bool { | ||||
| 	hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(b.secretAccessKey), 10) | ||||
| 	if username == b.accessKeyID { | ||||
| 		return bcrypt.CompareHashAndPassword(hashedPassword, []byte(password)) == nil | ||||
| // Authenticate - authenticates incoming username and password. | ||||
| func (jwt *JWT) Authenticate(userName, password string) bool { | ||||
| 	if !bytes.Equal([]byte(userName), jwt.accessKeyID) { | ||||
| 		return false | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // getPrivateKey - get the generated private key. | ||||
| func getPrivateKey() *rsa.PrivateKey { | ||||
| 	pemBytes, err := ioutil.ReadFile(mustGetPrivateKeyPath()) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	data, _ := pem.Decode([]byte(pemBytes)) | ||||
| 	privateKeyImported, err := x509.ParsePKCS1PrivateKey(data.Bytes) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	return privateKeyImported | ||||
| 	hashedPassword, _ := bcrypt.GenerateFromPassword(jwt.secretAccessKey, bcrypt.DefaultCost) | ||||
| 	return bcrypt.CompareHashAndPassword(hashedPassword, []byte(password)) == nil | ||||
| } | ||||
|  | ||||
| @ -162,7 +162,7 @@ func (fs Filesystem) NewMultipartUpload(bucket, object string) (string, *probe.E | ||||
| 
 | ||||
| 	bucket = fs.denormalizeBucket(bucket) | ||||
| 	bucketPath := filepath.Join(fs.path, bucket) | ||||
| 	if _, e := os.Stat(bucketPath); e != nil { | ||||
| 	if _, e = os.Stat(bucketPath); e != nil { | ||||
| 		// check bucket exists | ||||
| 		if os.IsNotExist(e) { | ||||
| 			return "", probe.NewError(BucketNotFound{Bucket: bucket}) | ||||
| @ -172,7 +172,7 @@ func (fs Filesystem) NewMultipartUpload(bucket, object string) (string, *probe.E | ||||
| 
 | ||||
| 	objectPath := filepath.Join(bucketPath, object) | ||||
| 	objectDir := filepath.Dir(objectPath) | ||||
| 	if _, e := os.Stat(objectDir); e != nil { | ||||
| 	if _, e = os.Stat(objectDir); e != nil { | ||||
| 		if !os.IsNotExist(e) { | ||||
| 			return "", probe.NewError(e) | ||||
| 		} | ||||
|  | ||||
							
								
								
									
										29
									
								
								routers.go
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								routers.go
									
									
									
									
									
								
							| @ -46,12 +46,20 @@ type WebAPI struct { | ||||
| 	AccessLog bool | ||||
| 	// Minio client instance. | ||||
| 	Client minio.CloudStorageClient | ||||
| 
 | ||||
| 	// private params. | ||||
| 	inSecure   bool   // Enabled if TLS is false. | ||||
| 	apiAddress string // api destination address. | ||||
| 	// accessKeys kept to be used internally. | ||||
| 	accessKeyID     string | ||||
| 	secretAccessKey string | ||||
| } | ||||
| 
 | ||||
| func getWebAPIHandler(web *WebAPI) http.Handler { | ||||
| 	var mwHandlers = []MiddlewareHandler{ | ||||
| 		TimeValidityHandler, // Validate time. | ||||
| 		CorsHandler,         // CORS added only for testing purposes. | ||||
| 		AuthHandler,         // Authentication handler for verifying tokens. | ||||
| 	} | ||||
| 	if web.AccessLog { | ||||
| 		mwHandlers = append(mwHandlers, AccessLogHandler) | ||||
| @ -106,20 +114,27 @@ func registerCloudStorageAPI(mux *router.Router, a CloudStorageAPI) { | ||||
| // getNewWebAPI instantiate a new WebAPI. | ||||
| func getNewWebAPI(conf cloudServerConfig) *WebAPI { | ||||
| 	// Split host port. | ||||
| 	_, port, e := net.SplitHostPort(conf.Address) | ||||
| 	host, port, e := net.SplitHostPort(conf.Address) | ||||
| 	fatalIf(probe.NewError(e), "Unable to parse web addess.", nil) | ||||
| 
 | ||||
| 	// Default host to 'localhost'. | ||||
| 	host := "localhost" | ||||
| 	// Default host is 'localhost', if no host present. | ||||
| 	if host == "" { | ||||
| 		host = "localhost" | ||||
| 	} | ||||
| 
 | ||||
| 	// Initialize minio client for AWS Signature Version '4' | ||||
| 	client, e := minio.NewV4(net.JoinHostPort(host, port), conf.AccessKeyID, conf.SecretAccessKey, true) | ||||
| 	inSecure := !conf.TLS // Insecure true when TLS is false. | ||||
| 	client, e := minio.NewV4(net.JoinHostPort(host, port), conf.AccessKeyID, conf.SecretAccessKey, inSecure) | ||||
| 	fatalIf(probe.NewError(e), "Unable to initialize minio client", nil) | ||||
| 
 | ||||
| 	web := &WebAPI{ | ||||
| 		FSPath:    conf.Path, | ||||
| 		AccessLog: conf.AccessLog, | ||||
| 		Client:    client, | ||||
| 		FSPath:          conf.Path, | ||||
| 		AccessLog:       conf.AccessLog, | ||||
| 		Client:          client, | ||||
| 		inSecure:        inSecure, | ||||
| 		apiAddress:      conf.Address, | ||||
| 		accessKeyID:     conf.AccessKeyID, | ||||
| 		secretAccessKey: conf.SecretAccessKey, | ||||
| 	} | ||||
| 	return web | ||||
| } | ||||
|  | ||||
| @ -1,64 +0,0 @@ | ||||
| /* | ||||
|  * Minio Cloud Storage, (C) 2016 Minio, Inc. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 
 | ||||
| 	"github.com/minio/minio-xl/pkg/probe" | ||||
| 	"github.com/minio/minio/pkg/user" | ||||
| ) | ||||
| 
 | ||||
| var customWebConfigDir = "" | ||||
| 
 | ||||
| // getWebConfigDir get web config dir. | ||||
| func getWebConfigDir() (string, *probe.Error) { | ||||
| 	if customWebConfigDir != "" { | ||||
| 		return customWebConfigDir, nil | ||||
| 	} | ||||
| 	homeDir, e := user.HomeDir() | ||||
| 	if e != nil { | ||||
| 		return "", probe.NewError(e) | ||||
| 	} | ||||
| 	webConfigDir := filepath.Join(homeDir, ".minio", "web") | ||||
| 	return webConfigDir, nil | ||||
| } | ||||
| 
 | ||||
| func mustGetWebConfigDir() string { | ||||
| 	webConfigDir, err := getWebConfigDir() | ||||
| 	fatalIf(err.Trace(), "Unable to get config path.", nil) | ||||
| 	return webConfigDir | ||||
| } | ||||
| 
 | ||||
| // createWebConfigDir create users config path | ||||
| func createWebConfigDir() *probe.Error { | ||||
| 	webConfigDir, err := getWebConfigDir() | ||||
| 	if err != nil { | ||||
| 		return err.Trace() | ||||
| 	} | ||||
| 	if err := os.MkdirAll(webConfigDir, 0700); err != nil { | ||||
| 		return probe.NewError(err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func mustGetPrivateKeyPath() string { | ||||
| 	webConfigDir, err := getWebConfigDir() | ||||
| 	fatalIf(err.Trace(), "Unable to get config path.", nil) | ||||
| 	return webConfigDir + "/private.key" | ||||
| } | ||||
| @ -53,8 +53,16 @@ type ObjectInfo struct { | ||||
| 	Size int64 `json:"size"` | ||||
| } | ||||
| 
 | ||||
| // GetObjectURLArgs - get object url. | ||||
| // PutObjectURLArgs - args to generate url for upload access. | ||||
| type PutObjectURLArgs struct { | ||||
| 	TargetHost string `json:"targetHost"` | ||||
| 	BucketName string `json:"bucketName"` | ||||
| 	ObjectName string `json:"objectName"` | ||||
| } | ||||
| 
 | ||||
| // GetObjectURLArgs - args to generate url for download access. | ||||
| type GetObjectURLArgs struct { | ||||
| 	TargetHost string `json:"targetHost"` | ||||
| 	BucketName string `json:"bucketName"` | ||||
| 	ObjectName string `json:"objectName"` | ||||
| } | ||||
|  | ||||
| @ -18,10 +18,13 @@ package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| 
 | ||||
| 	jwtgo "github.com/dgrijalva/jwt-go" | ||||
| 	"github.com/minio/minio-go" | ||||
| 	"github.com/minio/minio-xl/pkg/probe" | ||||
| 	"github.com/minio/minio/pkg/disk" | ||||
| ) | ||||
| 
 | ||||
| @ -29,13 +32,13 @@ import ( | ||||
| // authenticated request. | ||||
| func isAuthenticated(req *http.Request) bool { | ||||
| 	jwt := InitJWT() | ||||
| 	tokenRequest, err := jwtgo.ParseFromRequest(req, func(token *jwtgo.Token) (interface{}, error) { | ||||
| 		if _, ok := token.Method.(*jwtgo.SigningMethodRSA); !ok { | ||||
| 	tokenRequest, e := jwtgo.ParseFromRequest(req, func(token *jwtgo.Token) (interface{}, error) { | ||||
| 		if _, ok := token.Method.(*jwtgo.SigningMethodHMAC); !ok { | ||||
| 			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) | ||||
| 		} | ||||
| 		return jwt.PublicKey, nil | ||||
| 		return jwt.secretAccessKey, nil | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 	if e != nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	return tokenRequest.Valid | ||||
| @ -46,9 +49,9 @@ func (web *WebAPI) DiskInfo(r *http.Request, args *DiskInfoArgs, reply *disk.Inf | ||||
| 	if !isAuthenticated(r) { | ||||
| 		return errUnAuthorizedRequest | ||||
| 	} | ||||
| 	info, err := disk.GetInfo(web.FSPath) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	info, e := disk.GetInfo(web.FSPath) | ||||
| 	if e != nil { | ||||
| 		return e | ||||
| 	} | ||||
| 	*reply = info | ||||
| 	return nil | ||||
| @ -67,9 +70,9 @@ func (web *WebAPI) ListBuckets(r *http.Request, args *ListBucketsArgs, reply *[] | ||||
| 	if !isAuthenticated(r) { | ||||
| 		return errUnAuthorizedRequest | ||||
| 	} | ||||
| 	buckets, err := web.Client.ListBuckets() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	buckets, e := web.Client.ListBuckets() | ||||
| 	if e != nil { | ||||
| 		return e | ||||
| 	} | ||||
| 	for _, bucket := range buckets { | ||||
| 		*reply = append(*reply, BucketInfo{ | ||||
| @ -101,16 +104,60 @@ func (web *WebAPI) ListObjects(r *http.Request, args *ListObjectsArgs, reply *[] | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // GetObjectURL - get object url. | ||||
| func getTargetHost(apiAddress, targetHost string) (string, *probe.Error) { | ||||
| 	if targetHost != "" { | ||||
| 		_, port, e := net.SplitHostPort(apiAddress) | ||||
| 		if e != nil { | ||||
| 			return "", probe.NewError(e) | ||||
| 		} | ||||
| 		host, _, e := net.SplitHostPort(targetHost) | ||||
| 		if e != nil { | ||||
| 			return "", probe.NewError(e) | ||||
| 		} | ||||
| 		targetHost = net.JoinHostPort(host, port) | ||||
| 	} | ||||
| 	return targetHost, nil | ||||
| } | ||||
| 
 | ||||
| // PutObjectURL - generates url for upload access. | ||||
| func (web *WebAPI) PutObjectURL(r *http.Request, args *PutObjectURLArgs, reply *string) error { | ||||
| 	if !isAuthenticated(r) { | ||||
| 		return errUnAuthorizedRequest | ||||
| 	} | ||||
| 	targetHost, err := getTargetHost(web.apiAddress, args.TargetHost) | ||||
| 	if err != nil { | ||||
| 		return probe.WrapError(err) | ||||
| 	} | ||||
| 	client, e := minio.NewV4(targetHost, web.accessKeyID, web.secretAccessKey, web.inSecure) | ||||
| 	if e != nil { | ||||
| 		return e | ||||
| 	} | ||||
| 	signedURLStr, e := client.PresignedPutObject(args.BucketName, args.ObjectName, time.Duration(60*60)*time.Second) | ||||
| 	if e != nil { | ||||
| 		return e | ||||
| 	} | ||||
| 	*reply = signedURLStr | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // GetObjectURL - generates url for download access. | ||||
| func (web *WebAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply *string) error { | ||||
| 	if !isAuthenticated(r) { | ||||
| 		return errUnAuthorizedRequest | ||||
| 	} | ||||
| 	urlStr, err := web.Client.PresignedGetObject(args.BucketName, args.ObjectName, time.Duration(60*60)*time.Second) | ||||
| 	targetHost, err := getTargetHost(web.apiAddress, args.TargetHost) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return probe.WrapError(err) | ||||
| 	} | ||||
| 	*reply = urlStr | ||||
| 	client, e := minio.NewV4(targetHost, web.accessKeyID, web.secretAccessKey, web.inSecure) | ||||
| 	if e != nil { | ||||
| 		return e | ||||
| 	} | ||||
| 	signedURLStr, e := client.PresignedGetObject(args.BucketName, args.ObjectName, time.Duration(60*60)*time.Second) | ||||
| 	if e != nil { | ||||
| 		return e | ||||
| 	} | ||||
| 	*reply = signedURLStr | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -120,7 +167,7 @@ func (web *WebAPI) Login(r *http.Request, args *LoginArgs, reply *AuthToken) err | ||||
| 	if jwt.Authenticate(args.Username, args.Password) { | ||||
| 		token, err := jwt.GenerateToken(args.Username) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 			return probe.WrapError(err.Trace()) | ||||
| 		} | ||||
| 		reply.Token = token | ||||
| 		return nil | ||||
| @ -134,7 +181,7 @@ func (web *WebAPI) RefreshToken(r *http.Request, args *LoginArgs, reply *AuthTok | ||||
| 		jwt := InitJWT() | ||||
| 		token, err := jwt.GenerateToken(args.Username) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 			return probe.WrapError(err.Trace()) | ||||
| 		} | ||||
| 		reply.Token = token | ||||
| 		return nil | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user