add sessionTokenHandler

This commit is contained in:
Wenkai Yin 2016-04-13 15:54:29 +08:00
parent dc293e2289
commit 64d0fd56ce
2 changed files with 97 additions and 14 deletions

View File

@ -23,13 +23,17 @@ import (
"net/url"
"strings"
"github.com/astaxie/beego"
"github.com/vmware/harbor/dao"
"github.com/vmware/harbor/models"
"github.com/vmware/harbor/service/utils"
"github.com/vmware/harbor/utils/log"
)
// Handler authorizes the request when encounters a 401 error
type Handler interface {
// Scheme : basic, bearer
Scheme() string
// Schema : basic, bearer
Schema() string
//AuthorizeRequest adds basic auth or token auth to the header of request
AuthorizeRequest(req *http.Request, params map[string]string) error
}
@ -40,7 +44,7 @@ type Credential struct {
Username string
// Password ...
Password string
//SecretKey ...
// SecretKey ...
SecretKey string
}
@ -48,15 +52,15 @@ type token struct {
Token string `json:"token"`
}
type tokenHandler struct {
type standardTokenHandler struct {
client *http.Client
credential *Credential
}
// NewTokenHandler ...
// TODO deal with https
func NewTokenHandler(credential *Credential) Handler {
return &tokenHandler{
func NewStandardTokenHandler(credential *Credential) Handler {
return &standardTokenHandler{
client: &http.Client{
Transport: http.DefaultTransport,
},
@ -65,19 +69,18 @@ func NewTokenHandler(credential *Credential) Handler {
}
// Scheme : see interface AuthHandler
func (t *tokenHandler) Scheme() string {
func (t *standardTokenHandler) Schema() string {
return "bearer"
}
// AuthorizeRequest : see interface AuthHandler
func (t *tokenHandler) AuthorizeRequest(req *http.Request, params map[string]string) error {
func (t *standardTokenHandler) AuthorizeRequest(req *http.Request, params map[string]string) error {
realm, ok := params["realm"]
if !ok {
return errors.New("no realm")
}
service := params["service"]
scope := params["scope"]
u, err := url.Parse(realm)
@ -125,7 +128,73 @@ func (t *tokenHandler) AuthorizeRequest(req *http.Request, params map[string]str
req.Header.Add(http.CanonicalHeaderKey("Authorization"), fmt.Sprintf("Bearer %s", tk.Token))
log.Debugf("request token successfully | %s %s", req.Method, req.URL)
log.Debugf("standardTokenHandler generated token successfully | %s %s", req.Method, req.URL)
return nil
}
type sessionTokenHandler struct {
sessionID string
}
func NewSessionTokenHandler(sessionID string) Handler {
return &sessionTokenHandler{
sessionID: sessionID,
}
}
func (s *sessionTokenHandler) Schema() string {
return "bearer"
}
func (s *sessionTokenHandler) AuthorizeRequest(req *http.Request, params map[string]string) error {
session, err := beego.GlobalSessions.GetSessionStore(s.sessionID)
if err != nil {
return err
}
username, ok := session.Get("username").(string)
if !ok {
return errors.New("username in session can not be converted to string")
}
if len(username) == 0 {
userID, ok := session.Get("userId").(int)
if !ok {
return errors.New("userId in session can not be converted to int")
}
u := models.User{
UserID: userID,
}
user, err := dao.GetUser(u)
if err != nil {
return err
}
if user == nil {
return fmt.Errorf("user with id %d does not exist", userID)
}
username = user.Username
}
service := params["service"]
scopes := []string{}
scope := params["scope"]
if len(scope) != 0 {
scopes = strings.Split(scope, " ")
}
token, err := utils.GenTokenForUI(username, service, scopes)
if err != nil {
return err
}
req.Header.Add(http.CanonicalHeaderKey("Authorization"), fmt.Sprintf("Bearer %s", token))
log.Debugf("sessionTokenHandler generated token successfully | %s %s", req.Method, req.URL)
return nil
}

View File

@ -24,10 +24,24 @@ import (
// NewHTTPClientAuthHandlersEmbeded return a http.Client which will authorize the request
// and send it again when encounters a 401 error
func NewHTTPClientAuthHandlersEmbeded(credential *auth.Credential) *http.Client {
func NewClientStandardAuthHandlersEmbeded(credential *auth.Credential) *http.Client {
handlers := []auth.Handler{}
tokenHandler := auth.NewTokenHandler(credential)
tokenHandler := auth.NewStandardTokenHandler(credential)
handlers = append(handlers, tokenHandler)
transport := NewAuthTransport(http.DefaultTransport, handlers)
return &http.Client{
Transport: transport,
}
}
func NewClientSessionAuthHandlersEmbeded(sessionID string) *http.Client {
handlers := []auth.Handler{}
tokenHandler := auth.NewSessionTokenHandler(sessionID)
handlers = append(handlers, tokenHandler)
@ -73,8 +87,8 @@ func (a *authTransport) RoundTrip(req *http.Request) (*http.Response, error) {
scheme := challenge.Scheme
for _, handler := range a.handlers {
if scheme != handler.Scheme() {
log.Debugf("scheme not match: %s %s, skip", scheme, handler.Scheme())
if scheme != handler.Schema() {
log.Debugf("scheme not match: %s %s, skip", scheme, handler.Schema())
continue
}