Skip to content
Snippets Groups Projects
Commit 30f8c432 authored by Sergey Yakubov's avatar Sergey Yakubov
Browse files

switch broker to JWT tokens

parent a6523936
No related branches found
No related tags found
No related merge requests found
Showing
with 85 additions and 53 deletions
......@@ -33,9 +33,9 @@ func subjectFromRequest(request TokenRequest) string {
for key,value := range request.Subject {
switch key {
case "beamline":
return "bl_" + value
return utils.SubjectFromBeamline(value)
case "beamtimeId":
return "bt_" + value
return utils.SubjectFromBeamtime(value)
default:
return value
}
......
......@@ -154,34 +154,24 @@ func needHostAuthorization(creds SourceCredentials) bool {
}
func checkToken(token string, subject_expect string) (accessType string, err error) {
claims,err := Auth.UserAuth().CheckAndGetContent(token)
var extra_claim utils.AccessTokenExtraClaim
subject,err := Auth.UserAuth().CheckAndGetContent(token,&extra_claim)
if err!=nil {
return "",err
}
cclaims,ok:=claims.(*utils.CustomClaims)
if !ok {
return "",errors.New("wrong token claims")
}
if cclaims.Subject!=subject_expect {
if subject!=subject_expect {
return "",errors.New("wrong token for "+subject_expect)
}
var extra_claim utils.AccessTokenExtraClaim
ecMap,ok:=cclaims.ExtraClaims.(map[string]interface{})
if !ok {
return "",errors.New("wrong token extra claims")
}
err = utils.MapToStruct(ecMap, &extra_claim)
return extra_claim.AccessType,err
}
func authorizeByToken(creds SourceCredentials) (accessType string, err error) {
subject_expect:=""
if (creds.BeamtimeId != "auto") {
subject_expect = "bt_"+creds.BeamtimeId
subject_expect = utils.SubjectFromBeamtime(creds.BeamtimeId)
} else {
subject_expect = "bl_" + creds.Beamline
subject_expect = utils.SubjectFromBeamline(creds.Beamline)
}
return checkToken(creds.Token,subject_expect)
}
......
......@@ -39,7 +39,7 @@ func folderTokenResponce(token string) []byte{
}
func checkBeamtimeToken(request folderTokenRequest) error {
_,err := checkToken(request.Token,"bt_"+request.BeamtimeId)
_,err := checkToken(request.Token,utils.SubjectFromBeamtime(request.BeamtimeId))
return err
}
......
......@@ -58,7 +58,7 @@ func processRequest(w http.ResponseWriter, r *http.Request, op string, extra_par
return
}
if err := testAuth(r, db_name); err != nil {
if err := authorize(r, db_name); err != nil {
writeAuthAnswer(w, "get "+op, db_name, err.Error())
return
}
......
......@@ -26,8 +26,15 @@ const expectedStream = "stream"
func prepareTestAuth() {
expectedBeamtimeId = "beamtime_id"
expectedDBName = expectedBeamtimeId + "_" + expectedSource
auth = utils.NewHMACAuth("secret")
token, err := auth.GenerateToken(&expectedBeamtimeId)
auth = utils.NewJWTAuth("secret")
var claims utils.CustomClaims
var extraClaim utils.AccessTokenExtraClaim
claims.Subject = utils.SubjectFromBeamtime(expectedBeamtimeId)
extraClaim.AccessType = "read"
claims.ExtraClaims = &extraClaim
token, err := auth.GenerateToken(&claims)
if err != nil {
panic(err)
}
......@@ -107,7 +114,7 @@ func TestProcessRequestTestSuite(t *testing.T) {
}
func (suite *ProcessRequestTestSuite) TestProcessRequestWithWrongToken() {
logger.MockLog.On("Error", mock.MatchedBy(containsMatcher("wrong token")))
logger.MockLog.On("Error", mock.MatchedBy(containsMatcher("wrong JWT token")))
w := doRequest("/database/" + expectedBeamtimeId + "/" + expectedSource + "/" + expectedStream + "/" + expectedGroupID + "/next" + suffixWithWrongToken)
......
......@@ -2,6 +2,7 @@ package server
import (
"asapo_common/logger"
"asapo_common/utils"
"errors"
"net/http"
"strconv"
......@@ -43,18 +44,37 @@ func datasetRequested(r *http.Request) (bool,int) {
return valueTrue(r, "dataset"),valueInt(r,"minsize")
}
func testAuth(r *http.Request, beamtime_id string) error {
token_got := r.URL.Query().Get("token")
func authorize(r *http.Request, beamtime_id string) error {
token := r.URL.Query().Get("token")
if len(token_got) == 0 {
if len(token) == 0 {
return errors.New("cannot extract token from request")
}
token_expect, _ := auth.GenerateToken(&beamtime_id)
var extra_claim utils.AccessTokenExtraClaim
subject,err := auth.CheckAndGetContent(token,&extra_claim)
if err!=nil {
return err
}
if token_got != token_expect {
return errors.New("wrong token")
err = checkSubject(subject, beamtime_id)
if err != nil {
return err
}
return checkAccessType(extra_claim)
}
func checkSubject(subject string, beamtime_id string) error {
if subject != utils.SubjectFromBeamtime(beamtime_id) {
return errors.New("wrong token subject")
}
return nil
}
func checkAccessType(extra_claim utils.AccessTokenExtraClaim) error {
if extra_claim.AccessType != "read" && extra_claim.AccessType != "write" {
return errors.New("wrong token access type")
}
return nil
}
......@@ -29,7 +29,7 @@ func createAuth() (utils.Auth, error) {
if err != nil {
return nil, err
}
return utils.NewHMACAuth(secret), nil
return utils.NewJWTAuth(secret), nil
}
func ReadConfig(fname string) (log.Level, error) {
......
......@@ -6,7 +6,6 @@ import (
"crypto/sha256"
"encoding/base64"
"errors"
"fmt"
"github.com/dgrijalva/jwt-go"
"net/http"
"net/url"
......@@ -32,7 +31,15 @@ type Auth interface {
GenerateToken(...interface{}) (string, error)
ProcessAuth(http.HandlerFunc, string) http.HandlerFunc
Name() string
CheckAndGetContent(token string, payload ...interface{}) (interface{}, error)
CheckAndGetContent(token string, extraClaims interface{}, payload ...interface{}) (string,error)
}
func SubjectFromBeamtime(bt string)string {
return "bt_"+bt
}
func SubjectFromBeamline(bl string)string {
return "bl_"+bl
}
......@@ -154,14 +161,23 @@ func ProcessJWTAuth(fn http.HandlerFunc, key string) http.HandlerFunc {
}
}
func (a *JWTAuth) CheckAndGetContent(token string, payload ...interface{}) (interface{}, error) {
func (a *JWTAuth) CheckAndGetContent(token string, extraClaims interface{}, payload ...interface{}) (subject string,err error) {
// payload ignored
claims, ok := CheckJWTToken(token,a.Key)
c, ok := CheckJWTToken(token,a.Key)
if !ok {
return "",errors.New("wrong JWT token")
}
claim,ok := c.(*CustomClaims)
if !ok {
fmt.Println("hello ",token,a.Key)
return nil,errors.New("wrong JWT token")
return "",errors.New("cannot get CustomClaims")
}
subject = claim.Subject
if extraClaims!=nil {
err = MapToStruct(claim.ExtraClaims.(map[string]interface{}), extraClaims)
}
return claims,nil
return subject,err
}
......@@ -262,20 +278,20 @@ func ProcessHMACAuth(fn http.HandlerFunc, payload, key string) http.HandlerFunc
}
}
func (a *HMACAuth) CheckAndGetContent(token string, payload ...interface{}) (interface{}, error) {
func (a *HMACAuth) CheckAndGetContent(token string, _ interface{}, payload ...interface{}) (string,error) {
if len(payload) != 1 {
return nil, errors.New("wrong payload")
return "",errors.New("wrong payload")
}
value, ok := payload[0].(string)
if !ok {
return "", errors.New("wrong payload")
return "",errors.New("wrong payload")
}
ok = CheckHMACToken(token,value,a.Key)
if !ok {
return nil,errors.New("wrong HMAC token")
return "",errors.New("wrong HMAC token")
}
return nil,nil
return value,nil
}
......
......@@ -33,7 +33,7 @@ func TestGenerateJWTToken(t *testing.T) {
}
var HJWTAuthtests = []struct {
var JWTAuthtests = []struct {
Mode string
Key string
User string
......@@ -50,7 +50,7 @@ var HJWTAuthtests = []struct {
}
func TestProcessJWTAuth(t *testing.T) {
for _, test := range HJWTAuthtests {
for _, test := range JWTAuthtests {
req, _ := http.NewRequest("POST", "http://blabla", nil)
var claim JobClaim
......
......@@ -21,12 +21,12 @@ cp beamtime-metadata* beamline/p07/current/
#tokens
AdminToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTNvcGpyaXB0MzNlb2ZjbWJuZyIsInN1YiI6ImFkbWluIiwiRXh0cmFDbGFpbXMiOnsiQWNjZXNzVHlwZSI6ImNyZWF0ZSJ9fQ.uRjtGPaRpOlOfKroijHRgMDNaZHnXsVPf0JaJ1XMg7o
#curl -v --silent -H "Authorization: Bearer $AdminToken" --data '{"Subject": {"beamtimeId":"12345678"},"DaysValid":123,"AccessType":"read"}' 127.0.0.1:5007/admin/issue --stderr - | tee /dev/stderr | grep "bt_12345678"
#curl -v --silent -H "Authorization: Bearer blabla" --data '{"Subject": {"beamtimeId":"12345678"},"DaysValid":123,"AccessType":"read"}' 127.0.0.1:5007/admin/issue --stderr - | tee /dev/stderr | grep "token does not match"
curl -v --silent -H "Authorization: Bearer $AdminToken" --data '{"Subject": {"beamtimeId":"12345678"},"DaysValid":123,"AccessType":"read"}' 127.0.0.1:5007/admin/issue --stderr - | tee /dev/stderr | grep "bt_12345678"
curl -v --silent -H "Authorization: Bearer blabla" --data '{"Subject": {"beamtimeId":"12345678"},"DaysValid":123,"AccessType":"read"}' 127.0.0.1:5007/admin/issue --stderr - | tee /dev/stderr | grep "token does not match"
#curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:5007/authorize --stderr - #| tee /dev/stderr | grep c20180508-000-COM20181
#curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:5007/authorize --stderr - | tee /dev/stderr | grep p00
#curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:5007/authorize --stderr - | tee /dev/stderr | grep detector
curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:5007/authorize --stderr - | tee /dev/stderr | grep c20180508-000-COM20181
curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:5007/authorize --stderr - | tee /dev/stderr | grep p00
curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:5007/authorize --stderr - | tee /dev/stderr | grep detector
token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTNxZWpyaXB0MzUybHQxNjhyZyIsInN1YiI6ImJ0X2MyMDE4MDUwOC0wMDAtQ09NMjAxODEiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlIjoicmVhZCJ9fQ.MDuQa_f0yOcn35xIgiCfoVVT56oTQ5tSiuKu9VqO_tE #token for c20180508-000-COM20181
......@@ -49,12 +49,10 @@ curl -v --silent --data "{\"SourceCredentials\":\"raw%auto%p07%detector%$token\"
curl -v --silent --data "{\"SourceCredentials\":\"raw%auto%p07%detector%$token\",\"OriginHost\":\"127.0.0.1:5007\"}" 127.0.0.1:5007/authorize --stderr - | tee /dev/stderr | grep /asap3/petra3/gpfs/p07/2020/data/11111111
#read access
curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:5007/authorize --stderr - | tee /dev/stderr | grep read
curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:5007/authorize --stderr - | tee /dev/stderr | grep read
#write access
token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTNxcmFyaXB0MzVjcWpuMmUxZyIsInN1YiI6ImJsX3AwNyIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.KQFj3hOJRpc7hPqwJyYmnQ31IrR1zSz4EifUuulmP5E # for beamlne p07, write access
token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTQ4MG1yaXB0Mzc2Z2xvNWo3MCIsInN1YiI6ImJsX3AwNyIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJ3cml0ZSJ9fQ.8e4Xo1w-ICJzKjOwj2sGtpVfGppSGgPHv1yPLJwsdSA # for beamlne p07, write access
curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:5007/authorize --stderr - | tee /dev/stderr | grep write
rm -rf asap3 beamline
\ No newline at end of file
......@@ -15,7 +15,8 @@ C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"processed%%c20180
C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"raw%%c20180508-000-COM20181%%%%detector%%wrong\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr 401 || goto :error
C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"raw%%auto%%p07%%detector%%-pZmisCNjAbjT2gFBKs3OB2kNOU79SNsfHud0bV8gS4=\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr 11111111 || goto :error
set token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMTNxcmFyaXB0MzVjcWpuMmUxZyIsInN1YiI6ImJsX3AwNyIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGUiOiJyZWFkIn19.KQFj3hOJRpc7hPqwJyYmnQ31IrR1zSz4EifUuulmP5E"
C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"raw%%auto%%p07%%detector%%%token%\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr 11111111 || goto :error
goto :clean
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment