make sure that the jwt encryption key is configurable by the end user.

This commit is contained in:
Jason Kulatunga 2022-09-13 21:41:10 -04:00
parent 129d728d34
commit edd8587ab2
4 changed files with 17 additions and 10 deletions

View File

@ -6,9 +6,6 @@ import (
"time" "time"
) )
//TODO: this key should be dynamically generated/taken from config file.
var jwtKey = []byte("supersecretkey")
//TODO: this should match the ID and username for the user. //TODO: this should match the ID and username for the user.
type JWTClaim struct { type JWTClaim struct {
Username string `json:"username"` Username string `json:"username"`
@ -16,7 +13,7 @@ type JWTClaim struct {
jwt.StandardClaims jwt.StandardClaims
} }
func GenerateJWT(username string) (tokenString string, err error) { func GenerateJWT(encryptionKey string, username string) (tokenString string, err error) {
expirationTime := time.Now().Add(2 * time.Hour) expirationTime := time.Now().Add(2 * time.Hour)
claims := &JWTClaim{ claims := &JWTClaim{
Username: username, Username: username,
@ -26,11 +23,11 @@ func GenerateJWT(username string) (tokenString string, err error) {
}, },
} }
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err = token.SignedString(jwtKey) tokenString, err = token.SignedString([]byte(encryptionKey))
return return
} }
func ValidateToken(signedToken string) (*JWTClaim, error) { func ValidateToken(encryptionKey string, signedToken string) (*JWTClaim, error) {
token, err := jwt.ParseWithClaims( token, err := jwt.ParseWithClaims(
signedToken, signedToken,
&JWTClaim{}, &JWTClaim{},
@ -38,7 +35,7 @@ func ValidateToken(signedToken string) (*JWTClaim, error) {
if jwt.SigningMethodHS256 != token.Method { if jwt.SigningMethodHS256 != token.Method {
return nil, errors.New("Invalid signing algorithm") return nil, errors.New("Invalid signing algorithm")
} }
return []byte(jwtKey), nil return []byte(encryptionKey), nil
}, },
) )
if err != nil { if err != nil {

View File

@ -3,6 +3,7 @@ package handler
import ( import (
"fmt" "fmt"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/auth" "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/auth"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/config"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/database" "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/database"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/models" "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/models"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -11,6 +12,7 @@ import (
func AuthSignup(c *gin.Context) { func AuthSignup(c *gin.Context) {
databaseRepo := c.MustGet("REPOSITORY").(database.DatabaseRepository) databaseRepo := c.MustGet("REPOSITORY").(database.DatabaseRepository)
appConfig := c.MustGet("CONFIG").(config.Interface)
var user models.User var user models.User
if err := c.ShouldBindJSON(&user); err != nil { if err := c.ShouldBindJSON(&user); err != nil {
@ -24,7 +26,7 @@ func AuthSignup(c *gin.Context) {
} }
// return JWT // return JWT
tokenString, err := auth.GenerateJWT(user.Username) tokenString, err := auth.GenerateJWT(appConfig.GetString("web.jwt.encryptionKey"), user.Username)
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"success": false}) c.JSON(http.StatusInternalServerError, gin.H{"success": false})
return return
@ -35,6 +37,7 @@ func AuthSignup(c *gin.Context) {
func AuthSignin(c *gin.Context) { func AuthSignin(c *gin.Context) {
databaseRepo := c.MustGet("REPOSITORY").(database.DatabaseRepository) databaseRepo := c.MustGet("REPOSITORY").(database.DatabaseRepository)
appConfig := c.MustGet("CONFIG").(config.Interface)
var user models.User var user models.User
if err := c.ShouldBindJSON(&user); err != nil { if err := c.ShouldBindJSON(&user); err != nil {
@ -55,7 +58,7 @@ func AuthSignin(c *gin.Context) {
} }
// return JWT // return JWT
tokenString, err := auth.GenerateJWT(user.Username) tokenString, err := auth.GenerateJWT(appConfig.GetString("web.jwt.encryptionKey"), user.Username)
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "an error occurred generating JWT token"}) c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "an error occurred generating JWT token"})
return return

View File

@ -2,6 +2,7 @@ package middleware
import ( import (
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/auth" "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/auth"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/config"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"log" "log"
"net/http" "net/http"
@ -10,6 +11,8 @@ import (
func RequireAuth() gin.HandlerFunc { func RequireAuth() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
appConfig := c.MustGet("CONFIG").(config.Interface)
authHeader := c.GetHeader("Authorization") authHeader := c.GetHeader("Authorization")
authHeaderParts := strings.Split(authHeader, " ") authHeaderParts := strings.Split(authHeader, " ")
@ -27,13 +30,14 @@ func RequireAuth() gin.HandlerFunc {
c.Abort() c.Abort()
return return
} }
claim, err := auth.ValidateToken(tokenString) claim, err := auth.ValidateToken(appConfig.GetString("web.jwt.encryptionKey"), tokenString)
if err != nil { if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"success": false, "error": err.Error()}) c.JSON(http.StatusUnauthorized, gin.H{"success": false, "error": err.Error()})
c.Abort() c.Abort()
return return
} }
//todo, is this shared between all sessions??
c.Set("AUTH_TOKEN", tokenString) c.Set("AUTH_TOKEN", tokenString)
c.Set("AUTH_USERNAME", claim.Username) c.Set("AUTH_USERNAME", claim.Username)

View File

@ -6,6 +6,9 @@
version: 1 version: 1
web: web:
jwt:
# used to encrypt/validate JWT session key (used for authentication)
encryptionKey: 'changethissupersecretkey'
listen: listen:
port: 9090 port: 9090
host: 0.0.0.0 host: 0.0.0.0