httpServer.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // +build examples
  2. package main
  3. import (
  4. "encoding/hex"
  5. "errors"
  6. "fmt"
  7. "log"
  8. "net/http"
  9. "os"
  10. "github.com/gorilla/sessions"
  11. "github.com/jcmturner/goidentity/v6"
  12. "github.com/jcmturner/gokrb5/v8/keytab"
  13. "github.com/jcmturner/gokrb5/v8/service"
  14. "github.com/jcmturner/gokrb5/v8/spnego"
  15. "github.com/jcmturner/gokrb5/v8/test/testdata"
  16. )
  17. const (
  18. port = ":9080"
  19. )
  20. func main() {
  21. //defer profile.Start(profile.TraceProfile).Stop()
  22. // Create logger
  23. l := log.New(os.Stderr, "GOKRB5 Service: ", log.Ldate|log.Ltime|log.Lshortfile)
  24. // Load the service's keytab
  25. b, _ := hex.DecodeString(testdata.HTTP_KEYTAB)
  26. kt := keytab.New()
  27. kt.Unmarshal(b)
  28. // Create the application's specific handler
  29. th := http.HandlerFunc(testAppHandler)
  30. // Set up handler mappings wrapping in the SPNEGOKRB5Authenticate handler wrapper
  31. mux := http.NewServeMux()
  32. mux.Handle("/", spnego.SPNEGOKRB5Authenticate(th, kt, service.Logger(l), service.SessionManager(NewSessionMgr("gokrb5"))))
  33. // Start up the web server
  34. log.Fatal(http.ListenAndServe(port, mux))
  35. }
  36. // Simple application specific handler
  37. func testAppHandler(w http.ResponseWriter, r *http.Request) {
  38. w.WriteHeader(http.StatusOK)
  39. creds := goidentity.FromHTTPRequestContext(r)
  40. fmt.Fprintf(w,
  41. `<html>
  42. <h1>GOKRB5 Handler</h1>
  43. <ul>
  44. <li>Authenticed user: %s</li>
  45. <li>User's realm: %s</li>
  46. <li>Authn time: %v</li>
  47. <li>Session ID: %s</li>
  48. <ul>
  49. </html>`,
  50. creds.UserName(),
  51. creds.Domain(),
  52. creds.AuthTime(),
  53. creds.SessionID(),
  54. )
  55. return
  56. }
  57. type SessionMgr struct {
  58. skey []byte
  59. store sessions.Store
  60. cookieName string
  61. }
  62. func NewSessionMgr(cookieName string) SessionMgr {
  63. skey := []byte("thisistestsecret") // Best practice is to load this key from a secure location.
  64. return SessionMgr{
  65. skey: skey,
  66. store: sessions.NewCookieStore(skey),
  67. cookieName: cookieName,
  68. }
  69. }
  70. func (smgr SessionMgr) Get(r *http.Request, k string) ([]byte, error) {
  71. s, err := smgr.store.Get(r, smgr.cookieName)
  72. if err != nil {
  73. return nil, err
  74. }
  75. if s == nil {
  76. return nil, errors.New("nil session")
  77. }
  78. b, ok := s.Values[k].([]byte)
  79. if !ok {
  80. return nil, fmt.Errorf("could not get bytes held in session at %s", k)
  81. }
  82. return b, nil
  83. }
  84. func (smgr SessionMgr) New(w http.ResponseWriter, r *http.Request, k string, v []byte) error {
  85. s, err := smgr.store.New(r, smgr.cookieName)
  86. if err != nil {
  87. return fmt.Errorf("could not get new session from session manager: %v", err)
  88. }
  89. s.Values[k] = v
  90. return s.Save(r, w)
  91. }