92 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package auth
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"net/http"
 | |
| 	"net/url"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/micro/go-micro/v2/auth"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	// DefaultExcludes is the paths which are allowed by default
 | |
| 	DefaultExcludes = []string{"/favicon.ico"}
 | |
| )
 | |
| 
 | |
| // CombinedAuthHandler wraps a server and authenticates requests
 | |
| func CombinedAuthHandler(h http.Handler) http.Handler {
 | |
| 	return authHandler{
 | |
| 		handler: h,
 | |
| 		auth:    auth.DefaultAuth,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type authHandler struct {
 | |
| 	handler http.Handler
 | |
| 	auth    auth.Auth
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	// BearerScheme is the prefix in the auth header
 | |
| 	BearerScheme = "Bearer "
 | |
| )
 | |
| 
 | |
| func (h authHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
 | |
| 	// Extract the token from the request
 | |
| 	var token string
 | |
| 	if header := req.Header.Get("Authorization"); len(header) > 0 {
 | |
| 		// Extract the auth token from the request
 | |
| 		if strings.HasPrefix(header, BearerScheme) {
 | |
| 			token = header[len(BearerScheme):]
 | |
| 		}
 | |
| 	} else {
 | |
| 		// Get the token out the cookies if not provided in headers
 | |
| 		if c, err := req.Cookie("micro-token"); err == nil && c != nil {
 | |
| 			token = strings.TrimPrefix(c.Value, auth.CookieName+"=")
 | |
| 			req.Header.Set("Authorization", BearerScheme+token)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Return if the user disabled auth on this endpoint
 | |
| 	excludes := h.auth.Options().Exclude
 | |
| 	excludes = append(excludes, DefaultExcludes...)
 | |
| 
 | |
| 	loginURL := h.auth.Options().LoginURL
 | |
| 	if len(loginURL) > 0 {
 | |
| 		excludes = append(excludes, loginURL)
 | |
| 	}
 | |
| 
 | |
| 	for _, e := range excludes {
 | |
| 		// is a standard exclude, e.g. /rpc
 | |
| 		if e == req.URL.Path {
 | |
| 			h.handler.ServeHTTP(w, req)
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		// is a wildcard exclude, e.g. /services/*
 | |
| 		wildcard := strings.Replace(e, "*", "", 1)
 | |
| 		if strings.HasSuffix(e, "*") && strings.HasPrefix(req.URL.Path, wildcard) {
 | |
| 			h.handler.ServeHTTP(w, req)
 | |
| 			return
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// If the token is valid, allow the request
 | |
| 	if _, err := h.auth.Verify(token); err == nil {
 | |
| 		h.handler.ServeHTTP(w, req)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	// If there is no auth login url set, 401
 | |
| 	if loginURL == "" {
 | |
| 		w.WriteHeader(401)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	// Redirect to the login path
 | |
| 	params := url.Values{"redirect_to": {req.URL.Path}}
 | |
| 	loginWithRedirect := fmt.Sprintf("%v?%v", loginURL, params.Encode())
 | |
| 	http.Redirect(w, req, loginWithRedirect, http.StatusTemporaryRedirect)
 | |
| }
 |