Dürüst olmak gerekirse, uygulamanıza bağlayabileceğiniz ve uygulamaların iş mantığı ve gereksinimlerine bağlı olan birçok kimlik doğrulama yöntemi ve tekniği vardır.
Örneğin Oauth2, LDAP, yerel kimlik doğrulama, vb.
Cevabım , yerel kimlik doğrulamayı aradığınızı varsayar; bu da uygulamanızdaki kullanıcının kimliklerini yönettiğiniz anlamına gelir. Sunucu, kullanıcıların ve yöneticilerin Hesapları yönetmesine ve güvenilir iletişimi sağlamak için kendilerini Sunucu'ya nasıl tanımlamak istediklerine izin veren bir dizi harici API'yi göstermelidir. kullanıcı bilgilerini içeren bir DB tablosu oluşturacaksınız. güvenlik nedeniyle şifrenin sağlandığı yer Bkz . Parola veritabanında nasıl saklanır?
aşağıdaki yöntemlerden birini kullanarak kullanıcıların kimliğini doğrulamak için uygulama gereksinimlerini varsayalım:
temel kimlik doğrulama (kullanıcı adı, şifre):
Bu kimlik doğrulama yöntemi, base64 içinde kodlanan ve rfc7617'de tanımlanan Yetkilendirme üstbilgisinde ayarlanan kullanıcı kimlik bilgilerine bağlıdır , temel olarak uygulama kullanıcı yetkisini çözdüğünde ve şifresini DB içinde karşılaştırmak için parolayı yeniden oluşturur eşleşirse hash doğrulanmışsa, aksi takdirde kullanıcıya 401 durum kodu döndürür.
sertifika tabanlı kimlik doğrulama:
Bu kimlik doğrulama yöntemi, bir kullanıcıyı tanımlamak için Dijital Sertifikaya bağlıdır ve x509 kimlik doğrulaması olarak bilinir, bu nedenle uygulama kullanıcı isteklerini aldığında istemcinin sertifikasını okur ve sağlanan CA Kök sertifikasına uygun olduğunu doğrular APP.
taşıyıcı belirteci:
Bu kimlik doğrulama yöntemi kısa ömürlü Erişim belirteçlerine bağlıdır, Taşıyıcı belirteci, genellikle bir oturum açma isteğine yanıt olarak sunucu tarafından oluşturulan şifreli bir dizedir. böylece uygulama kullanıcı isteklerini aldığında yetkilendirmeyi okur ve kullanıcının kimliğini doğrulamak için jetonu doğrular.
Ancak, go-guardian'ı
, kimlik doğrulaması kütüphanesi için stratejiler olarak bilinen genişletilebilir bir kimlik doğrulama yöntemleri seti ile öneriyoruz . Temel olarak Go-Guardian, esnekliği en üst düzeye çıkaran ve geliştirici tarafından karar alınmasına izin veren belirli bir veritabanı şeması oluşturmaz veya herhangi bir veritabanı şeması kabul etmez.
Bir go-guard kimlik doğrulayıcısının kurulumu basittir.
Burada yukarıdaki yöntemlerin tam örneği.
package main
import (
"context"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"log"
"net/http"
"sync"
"github.com/golang/groupcache/lru"
"github.com/gorilla/mux"
"github.com/shaj13/go-guardian/auth"
"github.com/shaj13/go-guardian/auth/strategies/basic"
"github.com/shaj13/go-guardian/auth/strategies/bearer"
gx509 "github.com/shaj13/go-guardian/auth/strategies/x509"
"github.com/shaj13/go-guardian/store"
)
var authenticator auth.Authenticator
var cache store.Cache
func middleware(next http.Handler) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("Executing Auth Middleware")
user, err := authenticator.Authenticate(r)
if err != nil {
code := http.StatusUnauthorized
http.Error(w, http.StatusText(code), code)
return
}
log.Printf("User %s Authenticated\n", user.UserName())
next.ServeHTTP(w, r)
})
}
func Resource(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Resource!!\n"))
}
func Login(w http.ResponseWriter, r *http.Request) {
token := "90d64460d14870c08c81352a05dedd3465940a7"
user := auth.NewDefaultUser("admin", "1", nil, nil)
cache.Store(token, user, r)
body := fmt.Sprintf("token: %s \n", token)
w.Write([]byte(body))
}
func main() {
opts := x509.VerifyOptions{}
opts.KeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
opts.Roots = x509.NewCertPool()
// Read Root Ca Certificate
opts.Roots.AddCert(readCertificate("<root-ca>"))
cache = &store.LRU{
lru.New(100),
&sync.Mutex{},
}
// create strategies
x509Strategy := gx509.New(opts)
basicStrategy := basic.New(validateUser, cache)
tokenStrategy := bearer.New(bearer.NoOpAuthenticate, cache)
authenticator = auth.New()
authenticator.EnableStrategy(gx509.StrategyKey, x509Strategy)
authenticator.EnableStrategy(basic.StrategyKey, basicStrategy)
authenticator.EnableStrategy(bearer.CachedStrategyKey, tokenStrategy)
r := mux.NewRouter()
r.HandleFunc("/resource", middleware(http.HandlerFunc(Resource)))
r.HandleFunc("/login", middleware(http.HandlerFunc(Login)))
log.Fatal(http.ListenAndServeTLS(":8080", "<server-cert>", "<server-key>", r))
}
func validateUser(ctx context.Context, r *http.Request, userName, password string) (auth.Info, error) {
// here connect to db or any other service to fetch user and validate it.
if userName == "stackoverflow" && password == "stackoverflow" {
return auth.NewDefaultUser("stackoverflow", "10", nil, nil), nil
}
return nil, fmt.Errorf("Invalid credentials")
}
func readCertificate(file string) *x509.Certificate {
data, err := ioutil.ReadFile(file)
if err != nil {
log.Fatalf("error reading %s: %v", file, err)
}
p, _ := pem.Decode(data)
cert, err := x509.ParseCertificate(p.Bytes)
if err != nil {
log.Fatalf("error parseing certificate %s: %v", file, err)
}
return cert
}
Kullanımı:
curl -k https://127.0.0.1:8080/login -u stackoverflow:stackoverflow
token: 90d64460d14870c08c81352a05dedd3465940a7
- Bir jetonla kimlik doğrulaması yapın:
curl -k https://127.0.0.1:8080/resource -H "Authorization: Bearer 90d64460d14870c08c81352a05dedd3465940a7"
Resource!!
- Bir kullanıcı kimlik bilgileriyle kimlik doğrulaması yapın:
curl -k https://127.0.0.1:8080/resource -u stackoverflow:stackoverflow
Resource!!
- Bir kullanıcı sertifikası ile kimlik doğrulaması:
curl --cert client.pem --key client-key.pem --cacert ca.pem https://127.0.0.1:8080/resource
Resource!!
Aynı anda birden fazla kimlik doğrulama yöntemini etkinleştirebilirsiniz. Genellikle en az iki yöntem kullanmalısınız