diff --git a/README.md b/README.md index cf26d50..4a19bf5 100644 --- a/README.md +++ b/README.md @@ -892,8 +892,9 @@ The following `auth_opt_` options are supported by the `jwt` backend when remote | jwt_response_mode | status | N | Response type (status, json, text) | | jwt_params_mode | json | N | Data type (json, form) | | jwt_user_agent | mosquitto | N | User agent for requests | +| jwt_http_method | POST | N | Http method used (POST, GET, PUT) | -URIs (like jwt_getuser_uri) are expected to be in the form `/path`. For example, if jwt_with_tls is `false`, jwt_host is `localhost`, jwt_port `3000` and jwt_getuser_uri is `/user`, mosquitto will send a POST request to `http://localhost:3000/user` to get a response to check against. How data is sent (either json encoded or as form values) and received (as a simple http status code, a json encoded response or plain text), is given by options jwt_response_mode and jwt_params_mode. +URIs (like jwt_getuser_uri) are expected to be in the form `/path`. For example, if jwt_with_tls is `false`, jwt_host is `localhost`, jwt_port `3000` and jwt_getuser_uri is `/user`, mosquitto will send a http request to `http://localhost:3000/user` to get a response to check against. How data is sent (either json encoded or as form values) and received (as a simple http status code, a json encoded response or plain text), is given by options jwt_response_mode and jwt_params_mode. If the option `jwt_superuser_uri` is not set then `superuser` checks are disabled for this mode. @@ -1144,6 +1145,7 @@ The following `auth_opt_` options are supported: | http_params_mode | json | N | Data type (json, form) | | http_timeout | 5 | N | Timeout in seconds | | http_user_agent | mosquitto | N | User Agent to use in requests | +| http_method | POST | N | Http method used (POST, GET, PUT) | #### Response mode diff --git a/backends/http.go b/backends/http.go index e5b21fa..63c1509 100644 --- a/backends/http.go +++ b/backends/http.go @@ -25,6 +25,7 @@ type HTTP struct { WithTLS bool VerifyPeer bool ParamsMode string + httpMethod string ResponseMode string Timeout int Client *h.Client @@ -45,6 +46,7 @@ func NewHTTP(authOpts map[string]string, logLevel log.Level, version string) (HT VerifyPeer: false, ResponseMode: "status", ParamsMode: "json", + httpMethod: "POST", } missingOpts := "" @@ -62,6 +64,12 @@ func NewHTTP(authOpts map[string]string, logLevel log.Level, version string) (HT } } + if httpMethod, ok := authOpts["http_method"]; ok { + if httpMethod == "POST" || httpMethod == "GET" || httpMethod == "PUT" { + http.httpMethod = httpMethod + } + } + if userUri, ok := authOpts["http_getuser_uri"]; ok { http.UserUri = userUri } else { @@ -210,6 +218,13 @@ func (o HTTP) httpRequest(uri, username string, dataMap map[string]interface{}, var err error if o.ParamsMode == "form" { + if o.httpMethod != "POST" { + log.Errorf("error form param only supported for POST.") + err = fmt.Errorf("form only supported for POST, error code: %d", + 500) + return false, err + } + resp, err = o.Client.PostForm(fullUri, urlValues) } else { var dataJson []byte @@ -222,7 +237,7 @@ func (o HTTP) httpRequest(uri, username string, dataMap map[string]interface{}, contentReader := bytes.NewReader(dataJson) var req *h.Request - req, err = h.NewRequest("POST", fullUri, contentReader) + req, err = h.NewRequest(o.httpMethod, fullUri, contentReader) if err != nil { log.Errorf("req error: %s", err) @@ -236,7 +251,7 @@ func (o HTTP) httpRequest(uri, username string, dataMap map[string]interface{}, } if err != nil { - log.Errorf("POST error: %s", err) + log.Errorf("http request error: %s", err) return false, err } diff --git a/backends/jwt_remote.go b/backends/jwt_remote.go index 744c3a2..d1e857c 100644 --- a/backends/jwt_remote.go +++ b/backends/jwt_remote.go @@ -27,6 +27,7 @@ type remoteJWTChecker struct { verifyPeer bool paramsMode string + httpMethod string responseMode string options tokenOptions @@ -45,6 +46,7 @@ func NewRemoteJWTChecker(authOpts map[string]string, options tokenOptions, versi verifyPeer: false, responseMode: "status", paramsMode: "json", + httpMethod: "POST", options: options, } @@ -63,6 +65,12 @@ func NewRemoteJWTChecker(authOpts map[string]string, options tokenOptions, versi } } + if httpMethod, ok := authOpts["jwt_http_method"]; ok { + if httpMethod == "POST" || httpMethod == "GET" || httpMethod == "PUT" { + checker.httpMethod = httpMethod + } + } + if userUri, ok := authOpts["jwt_getuser_uri"]; ok { checker.userUri = userUri } else { @@ -239,7 +247,7 @@ func (o *remoteJWTChecker) jwtRequest(host, uri, token string, dataMap map[strin } contentReader := bytes.NewReader(dataJSON) - req, err = h.NewRequest("POST", fullURI, contentReader) + req, err = h.NewRequest(o.httpMethod, fullURI, contentReader) if err != nil { log.Errorf("req error: %s", err) @@ -248,7 +256,7 @@ func (o *remoteJWTChecker) jwtRequest(host, uri, token string, dataMap map[strin req.Header.Set("Content-Type", "application/json") req.Header.Set("User-Agent", o.userAgent) default: - req, err = h.NewRequest("POST", fullURI, strings.NewReader(urlValues.Encode())) + req, err = h.NewRequest(o.httpMethod, fullURI, strings.NewReader(urlValues.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("Content-Length", strconv.Itoa(len(urlValues.Encode()))) req.Header.Set("User-Agent", o.userAgent)