istio.io/istio@v0.0.0-20240520182934-d79c90f27776/samples/jwt-server/src/main.go (about) 1 // Copyright Istio Authors 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 15 package main 16 17 import ( 18 "flag" 19 "fmt" 20 "log" 21 "net" 22 "net/http" 23 "os" 24 "os/signal" 25 "sync" 26 "syscall" 27 "time" 28 ) 29 30 const ( 31 // nolint: lll 32 jwtKey = "{ \"keys\":[ {\"e\":\"AQAB\",\"kid\":\"tT_w9LRNrY7wJalGsTYSt7rutZi86Gvyc0EKR4CaQAw\",\"kty\":\"RSA\",\"n\":\"raJ7ZEhMfrBUo2werGKOow9an1B6Ukc6dKY2hNi10eaQe9ehJCjLpmJpePxoqaCi2VYt6gncLfhEV71JDGsodbfYMlaxwWTt6lXBcjlVXHWDXLC45rHVfi9FjSSXloHqmSStpjv3mrW3R6fx2VeVVP_mrA6ZHtcynq6ecJqO11STvVoeeM3lEsASVSWsUrKltC1Crfo0sI7YG34QjophVTEi8B9gVepAJZV-Bso5sinRABnxfLUM7DU5c8MO114uvXThgSIuAOM9PbViSC3X6Y9Gsjsy881HGO-EJaUCrwSWnwQW5sp0TktrYL70-M4_ug-X51Yt_PErmncKupx8Hw\"}]}" 33 ) 34 35 var ( 36 httpPort = flag.String("http", "8000", "HTTP server port") 37 httpsPort = flag.String("https", "8443", "HTTPS server port") 38 serverCert = flag.String("cert", "", "Optional, the name of server's certificate file") 39 serverkey = flag.String("key", "", "Optional, the name of server's private key") 40 ) 41 42 // JWTServer implements the sample server that serves jwt keys. 43 type JWTServer struct { 44 httpServer *http.Server 45 // For test only 46 httpPort chan int 47 // For https test 48 httpsPort chan int 49 // https server certificate 50 serverCertificate string 51 // https server private key 52 serverPrivateKey string 53 } 54 55 // ServeHTTP serves the JWT Keys. 56 func (s *JWTServer) ServeHTTP(response http.ResponseWriter, request *http.Request) { 57 // Add artificious delay based on delay query 58 delayParam := request.URL.Query().Get("delay") 59 if delayParam != "" { 60 delayDuration, err := time.ParseDuration(delayParam) 61 if err != nil { 62 // Handle invalid delay parameter 63 response.WriteHeader(http.StatusBadRequest) 64 response.Write([]byte("Invalid delay parameter")) 65 return 66 } 67 68 // If delay parameter is provided and valid, add delay 69 if delayDuration > 0 { 70 time.Sleep(delayDuration) 71 } 72 } 73 74 response.WriteHeader(http.StatusOK) 75 response.Write([]byte(string(jwtKey))) 76 } 77 78 func (s *JWTServer) startHTTP(address string, wg *sync.WaitGroup) { 79 defer func() { 80 wg.Done() 81 log.Printf("Stopped JWT HTTP server") 82 }() 83 84 listener, err := net.Listen("tcp", address) 85 if err != nil { 86 log.Fatalf("Failed to create HTTP server: %v", err) 87 } 88 // Store the port for test only. 89 s.httpPort <- listener.Addr().(*net.TCPAddr).Port 90 s.httpServer = &http.Server{Handler: s} 91 92 log.Printf("Starting HTTP server at %s", listener.Addr()) 93 if err := s.httpServer.Serve(listener); err != nil { 94 log.Fatalf("Failed to start HTTP server: %v", err) 95 } 96 } 97 98 func (s *JWTServer) startHTTPS(address string, wg *sync.WaitGroup) { 99 defer func() { 100 wg.Done() 101 log.Printf("Stopped JWT HTTPS server") 102 }() 103 104 listener, err := net.Listen("tcp", address) 105 if err != nil { 106 log.Fatalf("Failed to create HTTPS server: %v", err) 107 } 108 // Store the port for test only. 109 s.httpsPort <- listener.Addr().(*net.TCPAddr).Port 110 s.httpServer = &http.Server{Handler: s} 111 112 log.Printf("Starting HTTPS server on port %s", address) 113 if err := s.httpServer.ServeTLS(listener, s.serverCertificate, s.serverPrivateKey); err != nil { 114 log.Fatalf("Failed to start HTTPS server: %v", err) 115 } 116 } 117 118 func (s *JWTServer) runHTTP(httpAddr string) { 119 var wg sync.WaitGroup 120 wg.Add(1) 121 go s.startHTTP(httpAddr, &wg) 122 wg.Wait() 123 } 124 125 func (s *JWTServer) runHTTPS(httpsAddr string) { 126 var wg sync.WaitGroup 127 wg.Add(1) 128 go s.startHTTPS(httpsAddr, &wg) 129 wg.Wait() 130 } 131 132 func (s *JWTServer) stop() { 133 s.httpServer.Close() 134 } 135 136 func NewJwtServer(certificate string, key string) *JWTServer { 137 return &JWTServer{ 138 httpPort: make(chan int, 1), 139 httpsPort: make(chan int, 1), 140 serverCertificate: certificate, 141 serverPrivateKey: key, 142 } 143 } 144 145 func main() { 146 flag.Parse() 147 s := NewJwtServer(*serverCert, *serverkey) 148 go s.runHTTP(fmt.Sprintf(":%s", *httpPort)) 149 if s.serverCertificate != "" && s.serverPrivateKey != "" { 150 go s.runHTTPS(fmt.Sprintf(":%s", *httpsPort)) 151 } 152 defer s.stop() 153 154 // Wait for the process to be shutdown. 155 sigs := make(chan os.Signal, 1) 156 signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) 157 <-sigs 158 }