Add Namespace to CombinedAuthHandler
This commit is contained in:
parent
3a378eb7d6
commit
7206d5f964
@ -15,18 +15,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// CombinedAuthHandler wraps a server and authenticates requests
|
// CombinedAuthHandler wraps a server and authenticates requests
|
||||||
func CombinedAuthHandler(namespace string, r resolver.Resolver, h http.Handler) http.Handler {
|
func CombinedAuthHandler(prefix, namespace string, r resolver.Resolver, h http.Handler) http.Handler {
|
||||||
if r == nil {
|
if r == nil {
|
||||||
r = path.NewResolver()
|
r = path.NewResolver()
|
||||||
}
|
}
|
||||||
if len(namespace) == 0 {
|
|
||||||
namespace = "go.micro"
|
|
||||||
}
|
|
||||||
|
|
||||||
return authHandler{
|
return authHandler{
|
||||||
handler: h,
|
handler: h,
|
||||||
resolver: r,
|
resolver: r,
|
||||||
auth: auth.DefaultAuth,
|
auth: auth.DefaultAuth,
|
||||||
|
servicePrefix: prefix,
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,17 +34,13 @@ type authHandler struct {
|
|||||||
auth auth.Auth
|
auth auth.Auth
|
||||||
resolver resolver.Resolver
|
resolver resolver.Resolver
|
||||||
namespace string
|
namespace string
|
||||||
|
servicePrefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h authHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (h authHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
// Determine the namespace
|
// Determine the namespace and set it in the header
|
||||||
namespace, err := namespaceFromRequest(req)
|
namespace := h.namespaceFromRequest(req)
|
||||||
if err != nil {
|
fmt.Printf("Namespace is %v\n", namespace)
|
||||||
logger.Error(err)
|
|
||||||
namespace = auth.DefaultNamespace
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the namespace in the header
|
|
||||||
req.Header.Set(auth.NamespaceKey, namespace)
|
req.Header.Set(auth.NamespaceKey, namespace)
|
||||||
|
|
||||||
// Extract the token from the request
|
// Extract the token from the request
|
||||||
@ -96,7 +90,7 @@ func (h authHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// construct the resource name, e.g. home => go.micro.web.home
|
// construct the resource name, e.g. home => go.micro.web.home
|
||||||
resName := h.namespace
|
resName := h.servicePrefix
|
||||||
if len(endpoint.Name) > 0 {
|
if len(endpoint.Name) > 0 {
|
||||||
resName = resName + "." + endpoint.Name
|
resName = resName + "." + endpoint.Name
|
||||||
}
|
}
|
||||||
@ -138,39 +132,47 @@ func (h authHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
http.Redirect(w, req, loginWithRedirect, http.StatusTemporaryRedirect)
|
http.Redirect(w, req, loginWithRedirect, http.StatusTemporaryRedirect)
|
||||||
}
|
}
|
||||||
|
|
||||||
func namespaceFromRequest(req *http.Request) (string, error) {
|
func (h authHandler) namespaceFromRequest(req *http.Request) string {
|
||||||
// needed to tmp debug host in prod. will be removed.
|
// check to see what the provided namespace is, we only do
|
||||||
logger.Infof("Host is '%v'; URL Host is '%v'; URL Hostname is '%v'", req.Host, req.URL.Host, req.URL.Hostname())
|
// domain mapping if the namespace is set to 'domain'
|
||||||
|
if h.namespace != "domain" {
|
||||||
|
return h.namespace
|
||||||
|
}
|
||||||
|
|
||||||
// determine the host, e.g. dev.micro.mu:8080
|
// determine the host, e.g. dev.micro.mu:8080
|
||||||
host := req.URL.Hostname()
|
var host string
|
||||||
if len(host) == 0 {
|
if h, _, err := net.SplitHostPort(req.Host); err == nil {
|
||||||
// fallback to req.Host
|
host = h // host does contain a port
|
||||||
host, _, _ = net.SplitHostPort(req.Host)
|
} else {
|
||||||
|
host = req.Host // host does not contain a port
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for the micro.mu domain
|
||||||
|
if strings.HasSuffix(host, "micro.mu") {
|
||||||
|
return auth.DefaultNamespace
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for an ip address
|
// check for an ip address
|
||||||
if net.ParseIP(host) != nil {
|
if net.ParseIP(host) != nil {
|
||||||
return auth.DefaultNamespace, nil
|
return auth.DefaultNamespace
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for dev enviroment
|
// check for dev enviroment
|
||||||
if host == "localhost" || host == "127.0.0.1" {
|
if host == "localhost" || host == "127.0.0.1" {
|
||||||
return auth.DefaultNamespace, nil
|
return auth.DefaultNamespace
|
||||||
}
|
}
|
||||||
|
|
||||||
// if host is not a subdomain, deturn default namespace
|
// if host is not a subdomain, deturn default namespace
|
||||||
comps := strings.Split(host, ".")
|
comps := strings.Split(host, ".")
|
||||||
if len(comps) != 3 {
|
if len(comps) < 3 {
|
||||||
return auth.DefaultNamespace, nil
|
return auth.DefaultNamespace
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for the micro.mu domain
|
// return the reversed subdomain as the namespace
|
||||||
domain := fmt.Sprintf("%v.%v", comps[1], comps[2])
|
nComps := comps[0 : len(comps)-2]
|
||||||
if domain == "micro.mu" {
|
for i := len(nComps)/2 - 1; i >= 0; i-- {
|
||||||
return auth.DefaultNamespace, nil
|
opp := len(nComps) - 1 - i
|
||||||
|
nComps[i], nComps[opp] = nComps[opp], nComps[i]
|
||||||
}
|
}
|
||||||
|
return strings.Join(nComps, ".")
|
||||||
// return the subdomain as the host
|
|
||||||
return comps[0], nil
|
|
||||||
}
|
}
|
||||||
|
34
api/server/auth/auth_test.go
Normal file
34
api/server/auth/auth_test.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/micro/go-micro/v2/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNamespaceFromRequest(t *testing.T) {
|
||||||
|
tt := []struct {
|
||||||
|
Host string
|
||||||
|
Namespace string
|
||||||
|
}{
|
||||||
|
{Host: "micro.mu", Namespace: auth.DefaultNamespace},
|
||||||
|
{Host: "web.micro.mu", Namespace: auth.DefaultNamespace},
|
||||||
|
{Host: "api.micro.mu", Namespace: auth.DefaultNamespace},
|
||||||
|
{Host: "myapp.com", Namespace: auth.DefaultNamespace},
|
||||||
|
{Host: "staging.myapp.com", Namespace: "staging"},
|
||||||
|
{Host: "staging.myapp.m3o.app", Namespace: "myapp.staging"},
|
||||||
|
{Host: "127.0.0.1", Namespace: auth.DefaultNamespace},
|
||||||
|
{Host: "localhost", Namespace: auth.DefaultNamespace},
|
||||||
|
{Host: "81.151.101.146", Namespace: auth.DefaultNamespace},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tt {
|
||||||
|
t.Run(tc.Host, func(t *testing.T) {
|
||||||
|
ns := namespaceFromRequest(&http.Request{Host: tc.Host})
|
||||||
|
if ns != tc.Namespace {
|
||||||
|
t.Errorf("Expected namespace %v for host %v, actually got %v", tc.Namespace, tc.Host, ns)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -53,7 +53,7 @@ func (s *httpServer) Init(opts ...server.Option) error {
|
|||||||
|
|
||||||
func (s *httpServer) Handle(path string, handler http.Handler) {
|
func (s *httpServer) Handle(path string, handler http.Handler) {
|
||||||
h := handlers.CombinedLoggingHandler(os.Stdout, handler)
|
h := handlers.CombinedLoggingHandler(os.Stdout, handler)
|
||||||
h = auth.CombinedAuthHandler(s.opts.Namespace, s.opts.Resolver, handler)
|
h = auth.CombinedAuthHandler(s.opts.ServiceNamespace, s.opts.Namespace, s.opts.Resolver, handler)
|
||||||
|
|
||||||
if s.opts.EnableCORS {
|
if s.opts.EnableCORS {
|
||||||
h = cors.CombinedCORSHandler(h)
|
h = cors.CombinedCORSHandler(h)
|
||||||
|
@ -16,8 +16,9 @@ type Options struct {
|
|||||||
EnableTLS bool
|
EnableTLS bool
|
||||||
ACMEHosts []string
|
ACMEHosts []string
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
Namespace string
|
|
||||||
Resolver resolver.Resolver
|
Resolver resolver.Resolver
|
||||||
|
Namespace string
|
||||||
|
ServiceNamespace string
|
||||||
}
|
}
|
||||||
|
|
||||||
func EnableCORS(b bool) Option {
|
func EnableCORS(b bool) Option {
|
||||||
@ -56,6 +57,12 @@ func TLSConfig(t *tls.Config) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ServiceNamespace(n string) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.ServiceNamespace = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Namespace(n string) Option {
|
func Namespace(n string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Namespace = n
|
o.Namespace = n
|
||||||
|
Loading…
Reference in New Issue
Block a user