package main import ( "context" "fmt" "log" "net/http" "os" "strings" "github.com/coreos/go-oidc" "golang.org/x/oauth2" "golang.org/x/oauth2/microsoft" ) var ( clientID = os.Getenv("AZURE_CLIENT_ID") clientSecret = os.Getenv("AZURE_CLIENT_SECRET") redirectURL = os.Getenv("AZURE_REDIRECT_URL") // e.g., http://localhost:5000/callback tenantID = os.Getenv("AZURE_TENANT_ID") provider *oidc.Provider verifier *oidc.IDTokenVerifier oauth2Config *oauth2.Config ) func main() { nextIP, err := getNextFreeIP() if err != nil { fmt.Println("Error:", err) } else { fmt.Println("Next available IP:", nextIP) } ctx := context.Background() issuer := fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", tenantID) provider, err = oidc.NewProvider(ctx, issuer) if err != nil { log.Fatalf("failed to get provider: %v", err) } verifier = provider.Verifier(&oidc.Config{ClientID: clientID}) oauth2Config = &oauth2.Config{ ClientID: clientID, ClientSecret: clientSecret, Endpoint: microsoft.AzureADEndpoint(tenantID), RedirectURL: redirectURL, Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, } http.HandleFunc("/", handleIndex) http.HandleFunc("/callback", handleCallback) log.Println("Server started at http://localhost:5000") log.Fatal(http.ListenAndServe(":5000", nil)) } func handleIndex(w http.ResponseWriter, r *http.Request) { idTokenCookie, err := r.Cookie("id_token") if err != nil { log.Println("No id_token cookie found:", err) http.Redirect(w, r, oauth2Config.AuthCodeURL("state", oauth2.AccessTypeOffline), http.StatusFound) return } token, err := verifier.Verify(r.Context(), idTokenCookie.Value) if err != nil { log.Println("Token verification failed:", err) // Clear the invalid cookie to avoid another loop http.SetCookie(w, &http.Cookie{ Name: "id_token", Value: "", Path: "/", MaxAge: -1, HttpOnly: true, }) fmt.Printf("Tokent: %s", token) http.Redirect(w, r, oauth2Config.AuthCodeURL("state", oauth2.AccessTypeOffline), http.StatusFound) return } var claims struct { Email string `json:"email"` PreferredUsername string `json:"preferred_username"` Name string `json:"name"` } if err := token.Claims(&claims); err != nil { http.Error(w, "Failed to parse claims", http.StatusInternalServerError) return } email := claims.Email if email == "" { email = strings.Split(claims.PreferredUsername, "@")[0] } fmt.Fprintf(w, "Welcome! Logged in as: %s", email) } func handleCallback(w http.ResponseWriter, r *http.Request) { ctx := r.Context() code := r.URL.Query().Get("code") token, err := oauth2Config.Exchange(ctx, code) if err != nil { http.Error(w, "Token exchange failed", http.StatusInternalServerError) return } rawIDToken, ok := token.Extra("id_token").(string) if !ok { http.Error(w, "No id_token found", http.StatusInternalServerError) return } // Verify and set as cookie _, err = verifier.Verify(ctx, rawIDToken) if err != nil { http.Error(w, "Failed to verify ID token", http.StatusUnauthorized) return } // Set token as cookie http.SetCookie(w, &http.Cookie{ Name: "id_token", Value: rawIDToken, Path: "/", HttpOnly: true, }) http.Redirect(w, r, "/", http.StatusFound) }