basic.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Copyright 2014 beego Author. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Package auth provides handlers to enable basic auth support.
  15. // Simple Usage:
  16. // import(
  17. // "github.com/astaxie/beego"
  18. // "github.com/astaxie/beego/plugins/auth"
  19. // )
  20. //
  21. // func main(){
  22. // // authenticate every request
  23. // beego.InsertFilter("*", beego.BeforeRouter,auth.Basic("username","secretpassword"))
  24. // beego.Run()
  25. // }
  26. //
  27. //
  28. // Advanced Usage:
  29. //
  30. // func SecretAuth(username, password string) bool {
  31. // return username == "astaxie" && password == "helloBeego"
  32. // }
  33. // authPlugin := auth.NewBasicAuthenticator(SecretAuth, "Authorization Required")
  34. // beego.InsertFilter("*", beego.BeforeRouter,authPlugin)
  35. package auth
  36. import (
  37. "encoding/base64"
  38. "net/http"
  39. "strings"
  40. "github.com/astaxie/beego"
  41. "github.com/astaxie/beego/context"
  42. )
  43. var defaultRealm = "Authorization Required"
  44. // Basic is the http basic auth
  45. func Basic(username string, password string) beego.FilterFunc {
  46. secrets := func(user, pass string) bool {
  47. return user == username && pass == password
  48. }
  49. return NewBasicAuthenticator(secrets, defaultRealm)
  50. }
  51. // NewBasicAuthenticator return the BasicAuth
  52. func NewBasicAuthenticator(secrets SecretProvider, Realm string) beego.FilterFunc {
  53. return func(ctx *context.Context) {
  54. a := &BasicAuth{Secrets: secrets, Realm: Realm}
  55. if username := a.CheckAuth(ctx.Request); username == "" {
  56. a.RequireAuth(ctx.ResponseWriter, ctx.Request)
  57. }
  58. }
  59. }
  60. // SecretProvider is the SecretProvider function
  61. type SecretProvider func(user, pass string) bool
  62. // BasicAuth store the SecretProvider and Realm
  63. type BasicAuth struct {
  64. Secrets SecretProvider
  65. Realm string
  66. }
  67. // CheckAuth Checks the username/password combination from the request. Returns
  68. // either an empty string (authentication failed) or the name of the
  69. // authenticated user.
  70. // Supports MD5 and SHA1 password entries
  71. func (a *BasicAuth) CheckAuth(r *http.Request) string {
  72. s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
  73. if len(s) != 2 || s[0] != "Basic" {
  74. return ""
  75. }
  76. b, err := base64.StdEncoding.DecodeString(s[1])
  77. if err != nil {
  78. return ""
  79. }
  80. pair := strings.SplitN(string(b), ":", 2)
  81. if len(pair) != 2 {
  82. return ""
  83. }
  84. if a.Secrets(pair[0], pair[1]) {
  85. return pair[0]
  86. }
  87. return ""
  88. }
  89. // RequireAuth http.Handler for BasicAuth which initiates the authentication process
  90. // (or requires reauthentication).
  91. func (a *BasicAuth) RequireAuth(w http.ResponseWriter, r *http.Request) {
  92. w.Header().Set("WWW-Authenticate", `Basic realm="`+a.Realm+`"`)
  93. w.WriteHeader(401)
  94. w.Write([]byte("401 Unauthorized\n"))
  95. }