mirror of
https://github.com/kataras/iris.git
synced 2025-12-18 02:17:05 +00:00
Simplify the basicauth middleware
Former-commit-id: 8d184a434c992a884c5565bc22767ef295a1575a
This commit is contained in:
@@ -34,13 +34,12 @@ type (
|
||||
|
||||
//
|
||||
|
||||
// New takes one parameter, the Config returns a Handler
|
||||
// use: iris.Use(New(...)), iris.Get(...,New(...),...)
|
||||
// New accepts basicauth.Config and returns a new Handler
|
||||
// which will ask the client for basic auth (username, password),
|
||||
// validate that and if valid continues to the next handler, otherwise
|
||||
// throws a StatusUnauthorized http error code.
|
||||
func New(c Config) context.Handler {
|
||||
config := DefaultConfig()
|
||||
if c.ContextKey != "" {
|
||||
config.ContextKey = c.ContextKey
|
||||
}
|
||||
if c.Realm != "" {
|
||||
config.Realm = c.Realm
|
||||
}
|
||||
@@ -51,8 +50,10 @@ func New(c Config) context.Handler {
|
||||
return b.Serve
|
||||
}
|
||||
|
||||
// Default takes one parameter, the users returns a Handler
|
||||
// use: iris.Use(Default(...)), iris.Get(...,Default(...),...)
|
||||
// Default accepts only the users and returns a new Handler
|
||||
// which will ask the client for basic auth (username, password),
|
||||
// validate that and if valid continues to the next handler, otherwise
|
||||
// throws a StatusUnauthorized http error code.
|
||||
func Default(users map[string]string) context.Handler {
|
||||
c := DefaultConfig()
|
||||
c.Users = users
|
||||
@@ -101,26 +102,23 @@ func (b *basicAuthMiddleware) askForCredentials(ctx context.Context) {
|
||||
// Serve the actual middleware
|
||||
func (b *basicAuthMiddleware) Serve(ctx context.Context) {
|
||||
|
||||
if auth, found := b.findAuth(ctx.GetHeader("Authorization")); !found {
|
||||
auth, found := b.findAuth(ctx.GetHeader("Authorization"))
|
||||
if !found {
|
||||
b.askForCredentials(ctx)
|
||||
return
|
||||
// don't continue to the next handler
|
||||
} else {
|
||||
// all ok set the context's value in order to be getable from the next handler
|
||||
ctx.Values().Set(b.config.ContextKey, auth.Username)
|
||||
if b.expireEnabled {
|
||||
|
||||
if auth.logged == false {
|
||||
auth.expires = time.Now().Add(b.config.Expires)
|
||||
auth.logged = true
|
||||
}
|
||||
|
||||
if time.Now().After(auth.expires) {
|
||||
b.askForCredentials(ctx) // ask for authentication again
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
ctx.Next() // continue
|
||||
}
|
||||
// all ok
|
||||
if b.expireEnabled {
|
||||
if auth.logged == false {
|
||||
auth.expires = time.Now().Add(b.config.Expires)
|
||||
auth.logged = true
|
||||
}
|
||||
|
||||
if time.Now().After(auth.expires) {
|
||||
b.askForCredentials(ctx) // ask for authentication again
|
||||
return
|
||||
}
|
||||
}
|
||||
ctx.Next() // continue
|
||||
}
|
||||
|
||||
67
middleware/basicauth/basicauth_test.go
Normal file
67
middleware/basicauth/basicauth_test.go
Normal file
@@ -0,0 +1,67 @@
|
||||
// black-box testing
|
||||
package basicauth_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris"
|
||||
"github.com/kataras/iris/context"
|
||||
"github.com/kataras/iris/httptest"
|
||||
"github.com/kataras/iris/middleware/basicauth"
|
||||
)
|
||||
|
||||
func buildApp() *iris.Application {
|
||||
app := iris.New()
|
||||
|
||||
authConfig := basicauth.Config{
|
||||
Users: map[string]string{"myusername": "mypassword"},
|
||||
}
|
||||
|
||||
authentication := basicauth.New(authConfig)
|
||||
|
||||
app.Get("/", func(ctx context.Context) { ctx.Redirect("/admin") })
|
||||
|
||||
// to party
|
||||
|
||||
needAuth := app.Party("/admin", authentication)
|
||||
{
|
||||
//http://localhost:8080/admin
|
||||
needAuth.Get("/", h)
|
||||
// http://localhost:8080/admin/profile
|
||||
needAuth.Get("/profile", h)
|
||||
|
||||
// http://localhost:8080/admin/settings
|
||||
needAuth.Get("/settings", h)
|
||||
}
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func h(ctx context.Context) {
|
||||
username, password, _ := ctx.Request().BasicAuth()
|
||||
// third parameter it will be always true because the middleware
|
||||
// makes sure for that, otherwise this handler will not be executed.
|
||||
|
||||
ctx.Writef("%s %s:%s", ctx.Path(), username, password)
|
||||
}
|
||||
func TestBasicAuth(t *testing.T) {
|
||||
app := buildApp()
|
||||
e := httptest.New(app, t)
|
||||
|
||||
// redirects to /admin without basic auth
|
||||
e.GET("/").Expect().Status(iris.StatusUnauthorized)
|
||||
// without basic auth
|
||||
e.GET("/admin").Expect().Status(iris.StatusUnauthorized)
|
||||
|
||||
// with valid basic auth
|
||||
e.GET("/admin").WithBasicAuth("myusername", "mypassword").Expect().
|
||||
Status(iris.StatusOK).Body().Equal("/admin myusername:mypassword")
|
||||
e.GET("/admin/profile").WithBasicAuth("myusername", "mypassword").Expect().
|
||||
Status(iris.StatusOK).Body().Equal("/admin/profile myusername:mypassword")
|
||||
e.GET("/admin/settings").WithBasicAuth("myusername", "mypassword").Expect().
|
||||
Status(iris.StatusOK).Body().Equal("/admin/settings myusername:mypassword")
|
||||
|
||||
// with invalid basic auth
|
||||
e.GET("/admin/settings").WithBasicAuth("invalidusername", "invalidpassword").
|
||||
Expect().Status(iris.StatusUnauthorized)
|
||||
}
|
||||
@@ -13,9 +13,6 @@ import (
|
||||
const (
|
||||
// DefaultBasicAuthRealm is "Authorization Required"
|
||||
DefaultBasicAuthRealm = "Authorization Required"
|
||||
// DefaultBasicAuthContextKey is the "auth"
|
||||
// this key is used to do context.Set("user", theUsernameFromBasicAuth)
|
||||
DefaultBasicAuthContextKey = "user"
|
||||
)
|
||||
|
||||
// DefaultExpireTime zero time
|
||||
@@ -27,18 +24,16 @@ type Config struct {
|
||||
Users map[string]string
|
||||
// Realm http://tools.ietf.org/html/rfc2617#section-1.2. Default is "Authorization Required"
|
||||
Realm string
|
||||
// ContextKey the key for ctx.GetString(...). Default is 'user'
|
||||
ContextKey string
|
||||
// Expires expiration duration, default is 0 never expires
|
||||
Expires time.Duration
|
||||
}
|
||||
|
||||
// DefaultConfig returns the default configs for the BasicAuth middleware
|
||||
func DefaultConfig() Config {
|
||||
return Config{make(map[string]string), DefaultBasicAuthRealm, DefaultBasicAuthContextKey, 0}
|
||||
return Config{make(map[string]string), DefaultBasicAuthRealm, 0}
|
||||
}
|
||||
|
||||
// User returns the user from context key same as 'ctx.GetString("user")' but cannot be used by the developer, this is only here in order to understand how you can get the authenticated username
|
||||
func (c Config) User(ctx context.Context) string {
|
||||
return ctx.Values().GetString(c.ContextKey)
|
||||
// User returns the user from context key same as ctx.Request().BasicAuth().
|
||||
func (c Config) User(ctx context.Context) (string, string, bool) {
|
||||
return ctx.Request().BasicAuth()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user