diff --git a/asapo_tools/src/asapo_tools/cli/token.go b/asapo_tools/src/asapo_tools/cli/token.go index 3f0ecfe7ccbd5b53d5a296e125058e5bd2c3e3fb..6e9fae44af774a98e25693025a1758c429627fa4 100644 --- a/asapo_tools/src/asapo_tools/cli/token.go +++ b/asapo_tools/src/asapo_tools/cli/token.go @@ -13,13 +13,8 @@ type tokenFlags struct { } func generateToken(id string,secret string) string { - jwt := utils.NewJWTAuth(secret) - load := utils.JobClaim{id} - - var c utils.CustomClaims - c.ExtraClaims = &load - - token,err := jwt.GenerateToken(&c) + hmac := utils.NewHMACAuth(secret) + token,err := hmac.GenerateToken(&id) if (err!=nil) { fmt.Println(err.Error()) diff --git a/asapo_tools/src/asapo_tools/cli/token_test.go b/asapo_tools/src/asapo_tools/cli/token_test.go index 4149f9ae48b1b19b7110eff8c1ada26e955fac36..4d443f3c493f86aceb6156e5638aeb2f802a71bb 100644 --- a/asapo_tools/src/asapo_tools/cli/token_test.go +++ b/asapo_tools/src/asapo_tools/cli/token_test.go @@ -17,8 +17,7 @@ var tokenTests = []struct { {command{args: []string{"beamtime_id"}}, "secret", "no secret parameter"}, {command{args: []string{"-secret","secret.tmp"}}, "beamtime id", "no file"}, {command{args: []string{"-secret","not_existing_file","beamtime_id"}}, "not_existing_file", "no file"}, - {command{args: []string{"-secret","secret.tmp","beamtime_id"}}, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." + - "eyJFeHRyYUNsYWltcyI6eyJCZWFtdGltZUlkIjoiYmVhbXRpbWVfaWQifX0.OEYaJfOL6-0yY7B7zW73l372ZnR9GF2IUYMLuDQtmSo", "no file"}, + {command{args: []string{"-secret","secret.tmp","beamtime_id"}}, "eodk3s5ZXwACLGyVA63MZYcOTWuWE4bceI9Vxl9zejI=", "no file"}, } func TestParseTokenFlags(t *testing.T) { diff --git a/common/go/src/asapo_common/utils/authorization.go b/common/go/src/asapo_common/utils/authorization.go index ff8f69d210c170bcad7bbf8add02421e110a7843..a79bb68089785d709afd68be39d04394b9323ae6 100644 --- a/common/go/src/asapo_common/utils/authorization.go +++ b/common/go/src/asapo_common/utils/authorization.go @@ -7,6 +7,9 @@ import ( "strings" "context" "github.com/dgrijalva/jwt-go" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" ) type AuthorizationRequest struct { @@ -170,3 +173,65 @@ func JobClaimFromContext(r *http.Request, val interface{}) error { return MapToStruct(claim.ExtraClaims.(map[string]interface{}), val) } +type HMACAuth struct { + Key string +} + +func NewHMACAuth(key string) *HMACAuth { + a := HMACAuth{key} + return &a +} + +func generateHMACToken(value string, key string) string { + mac := hmac.New(sha256.New, []byte(key)) + mac.Write([]byte(value)) + + return base64.URLEncoding.EncodeToString(mac.Sum(nil)) +} + +func (h HMACAuth) GenerateToken(val ...interface{}) (string, error) { + if len(val) != 1 { + return "", errors.New("Wrong claims") + } + value, ok := val[0].(*string) + if !ok { + return "", errors.New("Wrong claims") + } + + sha := generateHMACToken(*value, h.Key) + return sha, nil +} + +func ProcessHMACAuth(fn http.HandlerFunc, key string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + authType, token, err := ExtractAuthInfo(r) + + if err != nil { + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + // todo extract beamline from request + value := "beamline" + if authType == "HMAC-SHA-256" { + if !checkHMACToken(value, token, key) { + http.Error(w, "Internal authorization error - tocken does not match", http.StatusUnauthorized) + return + } + } else { + http.Error(w, "Internal authorization error - wrong auth type", http.StatusUnauthorized) + return + } + fn(w, r) + } +} + +func checkHMACToken(value string, token, key string) bool { + + if token == "" { + return false + } + + generated_token := generateHMACToken(value, key) + return token == generated_token +}