Namespace requests coming via api & web

This commit is contained in:
Ben Toogood 2020-04-02 17:01:06 +01:00
parent 0241197c6a
commit 4999f6dfd4
6 changed files with 189 additions and 86 deletions

View File

@ -2,11 +2,15 @@ package auth
import (
"fmt"
"net"
"net/http"
"net/url"
"strings"
"github.com/micro/go-micro/v2/api/resolver"
"github.com/micro/go-micro/v2/api/resolver/path"
"github.com/micro/go-micro/v2/auth"
"github.com/micro/go-micro/v2/logger"
)
// CombinedAuthHandler wraps a server and authenticates requests
@ -14,15 +18,28 @@ func CombinedAuthHandler(h http.Handler) http.Handler {
return authHandler{
handler: h,
auth: auth.DefaultAuth,
resolver: path.NewResolver(),
// namespace:
}
}
type authHandler struct {
handler http.Handler
auth auth.Auth
resolver resolver.Resolver
}
func (h authHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// Determine the namespace
namespace, err := namespaceFromRequest(req)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
// Set the namespace in the header
req.Header.Set(auth.NamespaceKey, namespace)
// Extract the token from the request
var token string
if header := req.Header.Get("Authorization"); len(header) > 0 {
@ -43,23 +60,39 @@ func (h authHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// account doesn't necesserially mean a forbidden request
acc, err := h.auth.Inspect(token)
if err != nil {
acc = &auth.Account{}
acc = &auth.Account{Namespace: namespace}
}
// Check the accounts namespace matches the namespace we're operating
// within. If not forbid the request and log the occurance.
if acc.Namespace != namespace {
logger.Warnf("Cross namespace request forbidden: account %v (%v) requested access to %v in the %v namespace", acc.ID, acc.Namespace, req.URL.Path, namespace)
w.WriteHeader(http.StatusForbidden)
}
// WIP: Determine the name of the service being requested
// endpoint, err := h.resolver.Resolve(req)
// fmt.Printf("EndpointName: %v\n", endpoint.Name)
// fmt.Printf("EndpointMethod: %v\n", endpoint.Method)
// fmt.Printf("EndpointPath: %v\n", endpoint.Path)
// Perform the verification check to see if the account has access to
// the resource they're requesting
err = h.auth.Verify(acc, &auth.Resource{
Type: "service",
Name: "go.micro.web",
Endpoint: req.URL.Path,
Namespace: namespace,
})
// The account has the necessary permissions to access the
// resource
// The account has the necessary permissions to access the resource
if err == nil {
h.handler.ServeHTTP(w, req)
return
}
// The account is set, but they don't have enough permissions,
// hence we 403.
// The account is set, but they don't have enough permissions, hence
// we return a forbidden error.
if len(acc.ID) > 0 {
w.WriteHeader(http.StatusForbidden)
return
@ -77,3 +110,36 @@ func (h authHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
loginWithRedirect := fmt.Sprintf("%v?%v", loginURL, params.Encode())
http.Redirect(w, req, loginWithRedirect, http.StatusTemporaryRedirect)
}
func namespaceFromRequest(req *http.Request) (string, error) {
// check for an ip address
if net.ParseIP(req.Host) != nil {
return auth.DefaultNamespace, nil
}
// split the host to remove the port
host, _, err := net.SplitHostPort(req.Host)
if err != nil {
return "", err
}
// check for dev enviroment
if host == "localhost" || host == "127.0.0.1" {
return auth.DefaultNamespace, nil
}
// if host is not a subdomain, deturn default namespace
comps := strings.Split(host, ".")
if len(comps) != 3 {
return auth.DefaultNamespace, nil
}
// check for the micro.mu domain
domain := fmt.Sprintf("%v.%v", comps[1], comps[2])
if domain == "micro.mu" {
return auth.DefaultNamespace, nil
}
// return the subdomain as the host
return comps[0], nil
}

View File

@ -21,8 +21,6 @@ var (
ErrInvalidRole = errors.New("invalid role")
// ErrForbidden is returned when a user does not have the necessary roles to access a resource
ErrForbidden = errors.New("resource forbidden")
// BearerScheme used for Authorization header
BearerScheme = "Bearer "
)
// Auth providers authentication and authorization
@ -50,11 +48,13 @@ type Auth interface {
// Resource is an entity such as a user or
type Resource struct {
// Name of the resource
Name string
Name string `json:"name"`
// Type of resource, e.g.
Type string
Type string `json:"type"`
// Endpoint resource e.g NotesService.Create
Endpoint string
Endpoint string `json:"endpoint"`
// Namespace the resource belongs to
Namespace string `json:"namespace"`
}
// Account provided by an auth provider
@ -69,7 +69,7 @@ type Account struct {
Roles []string `json:"roles"`
// Any other associated metadata
Metadata map[string]string `json:"metadata"`
// Namespace the account belongs to, default blank
// Namespace the account belongs to
Namespace string `json:"namespace"`
// Secret for the account, e.g. the password
Secret string `json:"secret"`
@ -88,12 +88,18 @@ type Token struct {
}
const (
// DefaultNamespace used for auth
DefaultNamespace = "micro"
// NamespaceKey is the key used when storing the namespace in metadata
NamespaceKey = "Micro-Namespace"
// MetadataKey is the key used when storing the account in metadata
MetadataKey = "auth-account"
// TokenCookieName is the name of the cookie which stores the auth token
TokenCookieName = "micro-token"
// SecretCookieName is the name of the cookie which stores the auth secret
SecretCookieName = "micro-secret"
// BearerScheme used for Authorization header
BearerScheme = "Bearer "
)
// AccountFromContext gets the account from the context, which

View File

@ -42,6 +42,7 @@ func (n *noop) Generate(id string, opts ...GenerateOption) (*Account, error) {
Roles: options.Roles,
Secret: options.Secret,
Metadata: options.Metadata,
Namespace: DefaultNamespace,
}, nil
}
@ -64,6 +65,7 @@ func (n *noop) Verify(acc *Account, res *Resource) error {
func (n *noop) Inspect(token string) (*Account, error) {
return &Account{
ID: uuid.New().String(),
Namespace: DefaultNamespace,
}, nil
}

View File

@ -272,6 +272,7 @@ type Resource struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Endpoint string `protobuf:"bytes,3,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
Namespace string `protobuf:"bytes,4,opt,name=namespace,proto3" json:"namespace,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -323,6 +324,13 @@ func (m *Resource) GetEndpoint() string {
return ""
}
func (m *Resource) GetNamespace() string {
if m != nil {
return m.Namespace
}
return ""
}
type GenerateRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Roles []string `protobuf:"bytes,2,rep,name=roles,proto3" json:"roles,omitempty"`
@ -1123,12 +1131,12 @@ func init() {
}
var fileDescriptor_11312eec02fd5712 = []byte{
// 896 bytes of a gzipped FileDescriptorProto
// 901 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0x4b, 0x6f, 0xdb, 0x46,
0x10, 0x36, 0x49, 0x89, 0x92, 0x47, 0x0f, 0x0b, 0x1b, 0x27, 0x25, 0x98, 0x47, 0x1d, 0xa6, 0x28,
0xdc, 0xa0, 0xa1, 0x0b, 0xe5, 0xd0, 0x47, 0x2e, 0x35, 0x22, 0x41, 0x4d, 0xda, 0xa8, 0x28, 0x91,
0x22, 0xbd, 0x14, 0x01, 0x43, 0x4d, 0x6d, 0xc2, 0x32, 0xc9, 0xee, 0x2e, 0x8d, 0xfa, 0x52, 0xa0,
0xa7, 0xde, 0x7a, 0xea, 0x4f, 0xe8, 0xcf, 0xea, 0xbd, 0x7f, 0xa3, 0xe0, 0x3e, 0x28, 0x91, 0xa2,
0x22, 0xbd, 0x14, 0x01, 0x43, 0x4d, 0x6d, 0xc2, 0x32, 0xc9, 0xee, 0x2e, 0x8d, 0xea, 0x52, 0xa0,
0xa7, 0xde, 0x7a, 0xea, 0x4f, 0xe8, 0xcf, 0xea, 0xbd, 0x7f, 0xa3, 0xe0, 0x3e, 0x68, 0x91, 0xa2,
0x02, 0xa3, 0xf5, 0x21, 0xb7, 0x9d, 0x07, 0x67, 0xe6, 0xfb, 0x66, 0x76, 0xb8, 0xf0, 0xe9, 0x49,
0xcc, 0x4f, 0xf3, 0x37, 0x7e, 0x94, 0x9e, 0x1f, 0x9d, 0xc7, 0x11, 0x4d, 0x8f, 0x4e, 0xd2, 0x47,
0xf2, 0x10, 0xe6, 0xfc, 0xf4, 0x88, 0x21, 0xbd, 0x88, 0x23, 0x3c, 0xca, 0x68, 0xca, 0xa5, 0xca,
@ -1139,45 +1147,46 @@ var fileDescriptor_11312eec02fd5712 = []byte{
0x4c, 0xc8, 0x7d, 0xe8, 0x87, 0x51, 0x84, 0x8c, 0xbd, 0xe6, 0x85, 0xec, 0x18, 0x07, 0xc6, 0xe1,
0x6e, 0xd0, 0x93, 0x3a, 0xe9, 0xf2, 0x00, 0x06, 0x14, 0x7f, 0xa2, 0xc8, 0x4e, 0x95, 0x8f, 0x29,
0x7c, 0xfa, 0x4a, 0x29, 0x9d, 0x1c, 0xe8, 0x44, 0x14, 0x43, 0x8e, 0x0b, 0xc7, 0x3a, 0x30, 0x0e,
0xad, 0x40, 0x8b, 0xe4, 0x16, 0xd8, 0xf8, 0x4b, 0x16, 0xd3, 0x4b, 0xa7, 0x25, 0x0c, 0x4a, 0xf2,
0xfe, 0x34, 0xa1, 0xa3, 0x2a, 0x23, 0x43, 0x30, 0xe3, 0x85, 0xca, 0x6d, 0xc6, 0x0b, 0x42, 0xa0,
0xc5, 0x2f, 0x33, 0x54, 0x99, 0xc4, 0x99, 0xec, 0x43, 0x9b, 0xa6, 0x4b, 0x64, 0x8e, 0x75, 0x60,
0x1d, 0xee, 0x06, 0x52, 0x20, 0x5f, 0x42, 0xf7, 0x1c, 0x79, 0xb8, 0x08, 0x79, 0xe8, 0xb4, 0x04,
0xfa, 0x0f, 0x9a, 0xd1, 0xfb, 0x2f, 0x94, 0xdb, 0x34, 0xe1, 0xf4, 0x32, 0x28, 0xbf, 0x22, 0x77,
0x60, 0x37, 0x09, 0xcf, 0x91, 0x65, 0x61, 0x84, 0x4e, 0x5b, 0x24, 0x5c, 0x29, 0x88, 0x0b, 0xdd,
0x8c, 0xa6, 0x17, 0xf1, 0x02, 0xa9, 0x63, 0x0b, 0x63, 0x29, 0x17, 0xc8, 0x18, 0x46, 0x14, 0xb9,
0xd3, 0x11, 0x16, 0x25, 0xb9, 0x4f, 0x60, 0x50, 0x49, 0x46, 0x46, 0x60, 0x9d, 0xe1, 0xa5, 0xc2,
0x57, 0x1c, 0x0b, 0x30, 0x17, 0xe1, 0x32, 0xd7, 0x08, 0xa5, 0xf0, 0x85, 0xf9, 0x99, 0xe1, 0xcd,
0xa1, 0x1b, 0x20, 0x4b, 0x73, 0x1a, 0x61, 0x41, 0x43, 0x51, 0x89, 0xfa, 0x50, 0x9c, 0x1b, 0xa9,
0x71, 0xa1, 0x8b, 0xc9, 0x22, 0x4b, 0xe3, 0x84, 0x0b, 0xf6, 0x77, 0x83, 0x52, 0xf6, 0xfe, 0x32,
0x61, 0x6f, 0x86, 0x09, 0xd2, 0x90, 0xa3, 0x1a, 0xa5, 0x0d, 0xba, 0x4b, 0x6a, 0xcd, 0x75, 0x6a,
0xbf, 0x5a, 0xa3, 0xd6, 0x12, 0xd4, 0x7e, 0x5c, 0xa3, 0xb6, 0x16, 0xf7, 0x6a, 0x14, 0xb7, 0xea,
0x14, 0xaf, 0x68, 0x6c, 0xaf, 0xd3, 0x58, 0x22, 0xb5, 0xab, 0x48, 0xcb, 0x76, 0x74, 0xaa, 0xed,
0xf8, 0x7f, 0xb4, 0x4f, 0x60, 0xb4, 0x42, 0xa3, 0x6e, 0xd6, 0x27, 0xd0, 0x51, 0x37, 0x46, 0xc4,
0xd8, 0x7e, 0xb1, 0xb4, 0x9b, 0xf7, 0x0a, 0xfa, 0x33, 0x1a, 0x26, 0x5c, 0x13, 0x4d, 0xa0, 0x55,
0x70, 0xa9, 0x1b, 0x58, 0x9c, 0xc9, 0x63, 0xe8, 0x52, 0xd5, 0x60, 0x51, 0x46, 0x6f, 0xfc, 0x5e,
0x2d, 0xac, 0xee, 0x7f, 0x50, 0x3a, 0x7a, 0x7b, 0x30, 0x50, 0x81, 0x65, 0x6d, 0xde, 0x0f, 0x30,
0x08, 0xf0, 0x22, 0x3d, 0xc3, 0x6b, 0x4f, 0x35, 0x82, 0xa1, 0x8e, 0xac, 0x72, 0x7d, 0x08, 0xc3,
0x67, 0x09, 0xcb, 0x30, 0x2a, 0x71, 0xed, 0x43, 0x7b, 0x7d, 0x5d, 0x48, 0xc1, 0x7b, 0x0a, 0x7b,
0xa5, 0xdf, 0x7f, 0xa6, 0xf0, 0x57, 0xe8, 0x8b, 0x8d, 0xb2, 0x6d, 0x56, 0x57, 0xd3, 0x62, 0x56,
0xa6, 0x65, 0x63, 0x4b, 0x59, 0x0d, 0x5b, 0xea, 0x3e, 0xf4, 0x85, 0xf1, 0x75, 0x65, 0x23, 0xf5,
0x84, 0x6e, 0x2a, 0xd7, 0xd2, 0x13, 0x18, 0xa8, 0xfc, 0x0a, 0xc2, 0xc3, 0x75, 0xac, 0xbd, 0xf1,
0x7e, 0x0d, 0x80, 0x74, 0x56, 0x0c, 0xfc, 0x61, 0x40, 0x2b, 0xc8, 0x97, 0xd8, 0xb4, 0xd0, 0x44,
0x77, 0xcc, 0x2d, 0xdd, 0xb1, 0xae, 0xd8, 0x1d, 0xf2, 0x08, 0x6c, 0xb9, 0x9b, 0x45, 0xed, 0xc3,
0xf1, 0xcd, 0x4d, 0x3e, 0x91, 0xb1, 0x40, 0x39, 0x79, 0xbf, 0x1b, 0x30, 0x78, 0x2a, 0x16, 0xf1,
0x75, 0xcf, 0xc9, 0x5a, 0x25, 0xd6, 0x55, 0x2a, 0x19, 0xc1, 0x50, 0x17, 0xa2, 0xc6, 0xaa, 0xa8,
0x6d, 0x82, 0x4b, 0x7c, 0x27, 0x6a, 0xd3, 0x85, 0xa8, 0xda, 0x06, 0xd0, 0x2b, 0x7e, 0xb6, 0xfa,
0xdf, 0xfb, 0x39, 0xf4, 0xa5, 0xa8, 0x66, 0xe2, 0x23, 0x68, 0xd3, 0xbc, 0x58, 0x98, 0xf2, 0x87,
0x7b, 0xa3, 0x5e, 0x51, 0xbe, 0xc4, 0x40, 0x7a, 0x3c, 0xf4, 0xc1, 0x96, 0xd9, 0x48, 0x0f, 0x3a,
0xdf, 0xcf, 0xbf, 0x9e, 0x7f, 0xfb, 0x6a, 0x3e, 0xda, 0x29, 0x84, 0x59, 0x70, 0x3c, 0x7f, 0x39,
0x9d, 0x8c, 0x0c, 0x02, 0x60, 0x4f, 0xa6, 0xf3, 0x67, 0xd3, 0xc9, 0xc8, 0x1c, 0xff, 0x63, 0x40,
0xeb, 0x38, 0xe7, 0xa7, 0xe4, 0x05, 0x74, 0xf5, 0x46, 0x22, 0xf7, 0xde, 0xbe, 0x78, 0xdd, 0xf7,
0xb7, 0xda, 0x15, 0x9e, 0x1d, 0xf2, 0x1c, 0x3a, 0xea, 0x72, 0x92, 0xbb, 0x35, 0xef, 0xea, 0xe5,
0x76, 0xef, 0x6d, 0x33, 0x97, 0xb1, 0x26, 0xfa, 0xf5, 0x70, 0xbb, 0xf1, 0x32, 0xa8, 0x38, 0x77,
0x9a, 0x8d, 0x3a, 0xca, 0xf8, 0x47, 0xe8, 0xea, 0xc7, 0x0c, 0xf9, 0x0e, 0x5a, 0x05, 0xc1, 0xc4,
0xab, 0x7d, 0xd3, 0xf0, 0x10, 0x72, 0x1f, 0xbc, 0xd5, 0xa7, 0x0c, 0xff, 0xb7, 0x01, 0xed, 0xa2,
0x11, 0x8c, 0xcc, 0xc0, 0x96, 0xa3, 0x47, 0xea, 0x25, 0x55, 0xae, 0x86, 0x7b, 0x77, 0x8b, 0xb5,
0xc4, 0x3d, 0x03, 0x5b, 0xce, 0xc9, 0x46, 0xa0, 0xca, 0x1c, 0x6f, 0x04, 0xaa, 0x0d, 0xd7, 0x0e,
0x39, 0x56, 0x70, 0xdd, 0x06, 0x28, 0x3a, 0xc8, 0xed, 0x46, 0x9b, 0x0e, 0xf1, 0xc6, 0x16, 0x6f,
0xc7, 0xc7, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x4b, 0x8f, 0xf4, 0x22, 0x76, 0x0a, 0x00, 0x00,
0xad, 0x40, 0x8b, 0xe4, 0x16, 0xd8, 0xf8, 0x4b, 0x16, 0xd3, 0x95, 0xd3, 0x12, 0x06, 0x25, 0x79,
0x7f, 0x9a, 0xd0, 0x51, 0x95, 0x91, 0x21, 0x98, 0xf1, 0x42, 0xe5, 0x36, 0xe3, 0x05, 0x21, 0xd0,
0xe2, 0xab, 0x0c, 0x55, 0x26, 0x71, 0x26, 0xfb, 0xd0, 0xa6, 0xe9, 0x12, 0x99, 0x63, 0x1d, 0x58,
0x87, 0xbb, 0x81, 0x14, 0xc8, 0x97, 0xd0, 0x3d, 0x47, 0x1e, 0x2e, 0x42, 0x1e, 0x3a, 0x2d, 0x81,
0xfe, 0x83, 0x66, 0xf4, 0xfe, 0x0b, 0xe5, 0x36, 0x4d, 0x38, 0x5d, 0x05, 0xe5, 0x57, 0xe4, 0x0e,
0xec, 0x26, 0xe1, 0x39, 0xb2, 0x2c, 0x8c, 0xd0, 0x69, 0x8b, 0x84, 0x97, 0x0a, 0xe2, 0x42, 0x37,
0xa3, 0xe9, 0x45, 0xbc, 0x40, 0xea, 0xd8, 0xc2, 0x58, 0xca, 0x05, 0x32, 0x86, 0x11, 0x45, 0xee,
0x74, 0x84, 0x45, 0x49, 0xee, 0x13, 0x18, 0x54, 0x92, 0x91, 0x11, 0x58, 0x67, 0xb8, 0x52, 0xf8,
0x8a, 0x63, 0x01, 0xe6, 0x22, 0x5c, 0xe6, 0x1a, 0xa1, 0x14, 0xbe, 0x30, 0x3f, 0x33, 0xbc, 0x25,
0x74, 0x03, 0x64, 0x69, 0x4e, 0x23, 0x2c, 0x68, 0x28, 0x2a, 0x51, 0x1f, 0x8a, 0x73, 0x23, 0x35,
0x2e, 0x74, 0x31, 0x59, 0x64, 0x69, 0x9c, 0x70, 0xc1, 0xfe, 0x6e, 0x50, 0xca, 0x55, 0x78, 0xad,
0x1a, 0x3c, 0xef, 0x2f, 0x13, 0xf6, 0x66, 0x98, 0x20, 0x0d, 0x39, 0xaa, 0x41, 0xdb, 0x68, 0x46,
0x49, 0xbc, 0xb9, 0x4e, 0xfc, 0x57, 0x6b, 0xc4, 0x5b, 0x82, 0xf8, 0x8f, 0x6b, 0xc4, 0xd7, 0xe2,
0x5e, 0xad, 0x01, 0xf5, 0x0a, 0xd7, 0x48, 0x6e, 0xaf, 0x93, 0x5c, 0xf2, 0x60, 0x57, 0x79, 0x28,
0x9b, 0xd5, 0xa9, 0x36, 0xeb, 0xff, 0x35, 0x65, 0x02, 0xa3, 0x4b, 0x34, 0xea, 0xde, 0x7d, 0x02,
0x1d, 0x75, 0x9f, 0x44, 0x8c, 0xed, 0xd7, 0x4e, 0xbb, 0x79, 0xaf, 0xa0, 0x3f, 0xa3, 0x61, 0xc2,
0x35, 0xd1, 0x04, 0x5a, 0x05, 0x97, 0xba, 0xbd, 0xc5, 0x99, 0x3c, 0x86, 0x2e, 0x55, 0xed, 0x17,
0x65, 0xf4, 0xc6, 0xef, 0xd5, 0xc2, 0xea, 0xe9, 0x08, 0x4a, 0x47, 0x6f, 0x0f, 0x06, 0x2a, 0xb0,
0xac, 0xcd, 0xfb, 0x01, 0x06, 0x01, 0x5e, 0xa4, 0x67, 0x78, 0xed, 0xa9, 0x46, 0x30, 0xd4, 0x91,
0x55, 0xae, 0x0f, 0x61, 0xf8, 0x2c, 0x61, 0x19, 0x46, 0x25, 0xae, 0x7d, 0x68, 0xaf, 0x2f, 0x13,
0x29, 0x78, 0x4f, 0x61, 0xaf, 0xf4, 0xfb, 0xcf, 0x14, 0xfe, 0x0a, 0x7d, 0xb1, 0x6f, 0xb6, 0xcd,
0xea, 0xe5, 0xb4, 0x98, 0x95, 0x69, 0xd9, 0xd8, 0x61, 0x56, 0xc3, 0x0e, 0xbb, 0x0f, 0x7d, 0x61,
0x7c, 0x5d, 0xd9, 0x57, 0x3d, 0xa1, 0x9b, 0xca, 0xa5, 0xf5, 0x04, 0x06, 0x2a, 0xbf, 0x82, 0xf0,
0x70, 0x1d, 0x6b, 0x6f, 0xbc, 0x5f, 0x03, 0x20, 0x9d, 0x15, 0x03, 0x7f, 0x18, 0xd0, 0x0a, 0xf2,
0x25, 0x36, 0xad, 0x3b, 0xd1, 0x1d, 0x73, 0x4b, 0x77, 0xac, 0x2b, 0x76, 0x87, 0x3c, 0x02, 0x5b,
0x6e, 0x6e, 0x51, 0xfb, 0x70, 0x7c, 0x73, 0x93, 0x4f, 0x64, 0x2c, 0x50, 0x4e, 0xde, 0xef, 0x06,
0x0c, 0x9e, 0x8a, 0x35, 0x7d, 0xdd, 0x73, 0xb2, 0x56, 0x89, 0x75, 0x95, 0x4a, 0x46, 0x30, 0xd4,
0x85, 0xa8, 0xb1, 0x2a, 0x6a, 0x9b, 0xe0, 0x12, 0xdf, 0x89, 0xda, 0x74, 0x21, 0xaa, 0xb6, 0x01,
0xf4, 0x8a, 0x5f, 0xb1, 0xfe, 0x33, 0x7f, 0x0e, 0x7d, 0x29, 0xaa, 0x99, 0xf8, 0x08, 0xda, 0x34,
0x2f, 0x16, 0xa6, 0xfc, 0x1d, 0xdf, 0xa8, 0x57, 0x94, 0x2f, 0x31, 0x90, 0x1e, 0x0f, 0x7d, 0xb0,
0x65, 0x36, 0xd2, 0x83, 0xce, 0xf7, 0xf3, 0xaf, 0xe7, 0xdf, 0xbe, 0x9a, 0x8f, 0x76, 0x0a, 0x61,
0x16, 0x1c, 0xcf, 0x5f, 0x4e, 0x27, 0x23, 0x83, 0x00, 0xd8, 0x93, 0xe9, 0xfc, 0xd9, 0x74, 0x32,
0x32, 0xc7, 0xff, 0x18, 0xd0, 0x3a, 0xce, 0xf9, 0x29, 0x79, 0x01, 0x5d, 0xbd, 0x91, 0xc8, 0xbd,
0xb7, 0x2f, 0x5e, 0xf7, 0xfd, 0xad, 0x76, 0x85, 0x67, 0x87, 0x3c, 0x87, 0x8e, 0xba, 0x9c, 0xe4,
0x6e, 0xcd, 0xbb, 0x7a, 0xb9, 0xdd, 0x7b, 0xdb, 0xcc, 0x65, 0xac, 0x89, 0x7e, 0x5b, 0xdc, 0x6e,
0xbc, 0x0c, 0x2a, 0xce, 0x9d, 0x66, 0xa3, 0x8e, 0x32, 0xfe, 0x11, 0xba, 0xfa, 0xa9, 0x43, 0xbe,
0x83, 0x56, 0x41, 0x30, 0xf1, 0x6a, 0xdf, 0x34, 0x3c, 0x93, 0xdc, 0x07, 0x6f, 0xf5, 0x29, 0xc3,
0xff, 0x6d, 0x40, 0xbb, 0x68, 0x04, 0x23, 0x33, 0xb0, 0xe5, 0xe8, 0x91, 0x7a, 0x49, 0x95, 0xab,
0xe1, 0xde, 0xdd, 0x62, 0x2d, 0x71, 0xcf, 0xc0, 0x96, 0x73, 0xb2, 0x11, 0xa8, 0x32, 0xc7, 0x1b,
0x81, 0x6a, 0xc3, 0xb5, 0x43, 0x8e, 0x15, 0x5c, 0xb7, 0x01, 0x8a, 0x0e, 0x72, 0xbb, 0xd1, 0xa6,
0x43, 0xbc, 0xb1, 0xc5, 0xcb, 0xf2, 0xf1, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xfa, 0x51, 0x05,
0x6e, 0x94, 0x0a, 0x00, 0x00,
}

View File

@ -46,6 +46,7 @@ message Resource{
string name = 1;
string type = 2;
string endpoint = 3;
string namespace = 4;
}
message GenerateRequest {

View File

@ -132,6 +132,7 @@ func (s *svc) Grant(role string, res *auth.Resource) error {
Role: role,
Access: pb.Access_GRANTED,
Resource: &pb.Resource{
Namespace: res.Namespace,
Type: res.Type,
Name: res.Name,
Endpoint: res.Endpoint,
@ -146,6 +147,7 @@ func (s *svc) Revoke(role string, res *auth.Resource) error {
Role: role,
Access: pb.Access_GRANTED,
Resource: &pb.Resource{
Namespace: res.Namespace,
Type: res.Type,
Name: res.Name,
Endpoint: res.Endpoint,
@ -157,10 +159,11 @@ func (s *svc) Revoke(role string, res *auth.Resource) error {
// Verify an account has access to a resource
func (s *svc) Verify(acc *auth.Account, res *auth.Resource) error {
queries := [][]string{
{res.Type, res.Name, res.Endpoint}, // check for specific role, e.g. service.foo.ListFoo:admin (role is checked in accessForRule)
{res.Type, res.Name, "*"}, // check for wildcard endpoint, e.g. service.foo*
{res.Type, "*"}, // check for wildcard name, e.g. service.*
{"*"}, // check for wildcard type, e.g. *
{res.Namespace, res.Type, res.Name, res.Endpoint}, // check for specific role, e.g. service.foo.ListFoo:admin (role is checked in accessForRule)
{res.Namespace, res.Type, res.Name, "*"}, // check for wildcard endpoint, e.g. service.foo*
{res.Namespace, res.Type, "*"}, // check for wildcard name, e.g. service.*
{res.Namespace, "*"}, // check for wildcard type, e.g. *
{"*"}, // check for wildcard namespace
}
// endpoint is a url which can have wildcard excludes, e.g.
@ -172,23 +175,30 @@ func (s *svc) Verify(acc *auth.Account, res *auth.Resource) error {
}
}
// set a default account id to log
logID := acc.ID
if len(logID) == 0 {
logID = "[no account]"
}
for _, q := range queries {
for _, rule := range s.listRules(q...) {
switch accessForRule(rule, acc, res) {
case pb.Access_UNKNOWN:
continue // rule did not specify access, check the next rule
case pb.Access_GRANTED:
log.Infof("%v granted access to %v:%v:%v by rule %v", acc.ID, res.Type, res.Name, res.Endpoint, rule.Id)
log.Infof("%v:%v granted access to %v:%v:%v:%v by rule %v", acc.Namespace, logID, res.Namespace, res.Type, res.Name, res.Endpoint, rule.Id)
return nil // rule grants the account access to the resource
case pb.Access_DENIED:
log.Infof("%v denied access to %v:%v:%v by rule %v", acc.ID, res.Type, res.Name, res.Endpoint, rule.Id)
log.Infof("%v:%v denied access to %v:%v:%v:%v by rule %v", acc.Namespace, logID, res.Namespace, res.Type, res.Name, res.Endpoint, rule.Id)
return auth.ErrForbidden // rule denies access to the resource
}
}
}
// no rules were found for the resource, default to denying access
log.Infof("%v denied access to %v:%v:%v by lack of rule (%v rules found)", acc.ID, res.Type, res.Name, res.Endpoint, len(s.rules))
log.Infof("%v:%v denied access to %v:%v:%v:%v by lack of rule (%v rules found for namespace)", acc.Namespace, logID, res.Namespace, res.Type, res.Name, res.Endpoint, len(s.listRules(res.Namespace)))
fmt.Println(s.rules)
return auth.ErrForbidden
}
@ -249,19 +259,28 @@ func accessForRule(rule *pb.Rule, acc *auth.Account, res *auth.Resource) pb.Acce
return pb.Access_UNKNOWN
}
// listRules gets all the rules from the store which have an id
// prefix matching the filters
// listRules gets all the rules from the store which match the filters.
// filters are namespace, type, name and then endpoint.
func (s *svc) listRules(filters ...string) []*pb.Rule {
s.Lock()
defer s.Unlock()
prefix := strings.Join(filters, ruleJoinKey)
var rules []*pb.Rule
for _, r := range s.rules {
if strings.HasPrefix(r.Id, prefix) {
rules = append(rules, r)
if len(filters) > 0 && r.Resource.Namespace != filters[0] {
continue
}
if len(filters) > 1 && r.Resource.Type != filters[1] {
continue
}
if len(filters) > 2 && r.Resource.Name != filters[2] {
continue
}
if len(filters) > 3 && r.Resource.Endpoint != filters[3] {
continue
}
rules = append(rules, r)
}
return rules