github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/proxy/server/auth.go (about) 1 package server 2 3 import ( 4 "context" 5 "strings" 6 7 "github.com/tickoalcantara12/micro/v3/service/auth" 8 "github.com/tickoalcantara12/micro/v3/service/context/metadata" 9 "github.com/tickoalcantara12/micro/v3/service/errors" 10 "github.com/tickoalcantara12/micro/v3/service/server" 11 inauth "github.com/tickoalcantara12/micro/v3/util/auth" 12 "github.com/tickoalcantara12/micro/v3/util/auth/namespace" 13 ) 14 15 // authHandler wraps a server handler to perform auth 16 func authHandler() server.HandlerWrapper { 17 return func(h server.HandlerFunc) server.HandlerFunc { 18 return func(ctx context.Context, req server.Request, rsp interface{}) error { 19 // Extract the token if the header is present. We will inspect the token regardless of if it's 20 // present or not since noop auth will return a blank account upon Inspecting a blank token. 21 var token string 22 if header, ok := metadata.Get(ctx, "Authorization"); ok { 23 // Ensure the correct scheme is being used 24 if !strings.HasPrefix(header, inauth.BearerScheme) { 25 return errors.Unauthorized(req.Service(), "invalid authorization header. expected Bearer schema") 26 } 27 28 // Strip the bearer scheme prefix 29 token = strings.TrimPrefix(header, inauth.BearerScheme) 30 } 31 32 // Inspect the token and decode an account 33 account, _ := auth.Inspect(token) 34 35 // Extract the namespace header 36 ns, ok := metadata.Get(ctx, "Micro-Namespace") 37 if !ok && account != nil { 38 ns = account.Issuer 39 ctx = metadata.Set(ctx, "Micro-Namespace", ns) 40 } else if !ok { 41 ns = namespace.DefaultNamespace 42 ctx = metadata.Set(ctx, "Micro-Namespace", ns) 43 } 44 45 // construct the resource 46 res := &auth.Resource{ 47 Type: "service", 48 Name: req.Service(), 49 Endpoint: req.Endpoint(), 50 } 51 52 // Verify the caller has access to the resource. 53 err := auth.Verify(account, res, auth.VerifyNamespace(ns)) 54 if err == auth.ErrForbidden && account != nil { 55 return errors.Forbidden(req.Service(), "Forbidden call made to %v:%v by %v", req.Service(), req.Endpoint(), account.ID) 56 } else if err == auth.ErrForbidden { 57 return errors.Unauthorized(req.Service(), "Unauthorized call made to %v:%v", req.Service(), req.Endpoint()) 58 } else if err != nil { 59 return errors.InternalServerError("proxy", "Error authorizing request: %v", err) 60 } 61 62 // The user is authorised, allow the call 63 return h(ctx, req, rsp) 64 } 65 } 66 }