So I have a go application that is trying to authorize the user using two mechanisms:
- CSP (in which the app-key (ak) request header must be present in the request)
- OAuth (i will use the azp claim to set the name of service)
So I have to do the name-spacing in my service on the basis of type of authorization the user has used (User is free to choose any one of them).
So there is a design issue which I am not able to resolve:
func setServiceName(appKeys, oAuthUserMap map[string]string, logger log.Logger) func(inner http.Handler) http.Handler {
return func(inner http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
ak := req.Header.Get("ak")
claims, _ := req.Context().Value(oauth.JWTContextKey("claims")).(jwt.MapClaims)
authClaim, errorMessage, keyMap, middlewareError := checkAuthType(ak, claims, appKeys, oAuthUserMap)
if authClaim == "" || authClaim == "<nil>" {
// return error for "Invalid Authorization" as none of the request header is present
}
if val, ok := keyMap[authClaim]; ok {
// if value is not empty, then there must be a mapping existing between authClaim and service name
// serve the request
}
// return error according to the type of authorization used i.e. Invalid APP KEY in case of CSP or Invalid Credentials in case of Oauth
})
}
}
// this function checks the type of authorization used and returns the paramters respectively
func checkAuthType(ak string, claims jwt.MapClaims, appKeys, oAuthUserMap map[string]string) (authClaim,
errorMessage string, keyMap map[string]string, middlewareError error) {
if ak != "" {
keyMap = appKeys
errorMessage = "Invalid APP KEY provided"
middlewareError = // i will return a custom error here
authClaim = ak
}
azp := claims["azp"]
oauthClaim := fmt.Sprint(azp)
if oauthClaim != "<nil>" {
keyMap = oAuthUserMap
errorMessage = "Invalid Credentials"
middlewareError = // i will return a custom error here
authClaim = oauthClaim
}
return authClaim, errorMessage, keyMap, middlewareError
}
Things to keep in mind while seeing the code:
- This
setServiceName
is a middleware that i will be using in my application
- I have to return different errors on basis of type of authorization mechanism used
- The
appKeys
andoAuthUserMap
are two maps that i will populate on the basis of environment variables set in configs and i have to useappKeys
map for name-spacing in case of CSP and the later in case of OAuth
authClaim
will help me in finding the value from the key in map that will be used for namespacing
Problems I am facing:
- If I keep all the if statements inside the
setServiceName
middleware function the cognitive complexity will increase and that's not acceptable - the function
checkAuthType
is not a very good function as it is performing simple if-else logic that can be shifted inside the middleware function only
Please help me in solving this design issue. The function checkAuthType
doesn't seem to be much useful as it contains only if-else logic but at the same time i have to take care of cognitive complexity of setServiceName
.
Aucun commentaire:
Enregistrer un commentaire