diff --git a/docs/2-usage/05-authentication.md b/docs/2-usage/05-authentication.md index 69447c2b..f222eb9f 100644 --- a/docs/2-usage/05-authentication.md +++ b/docs/2-usage/05-authentication.md @@ -299,23 +299,23 @@ Authorization: Bearer username:password ### RTSP -Pass the token as password, with an arbitrary user: +Pass the token as query parameter: ``` -rtsp://user:jwt@localhost:8554/mystream +rtsp://localhost:8554/mystream?jwt=jwt ``` -WARNING: FFmpeg implementation of RTSP does not support passwords that are longer than 1024 characters, therefore you have to configure your identity server in order to produce JWTs that are shorter than this threshold. +WARNING: FFmpeg implementation of RTSP does not support URLs that are longer than 4096 characters (this is the [MAX_URL_SIZE constant](https://github.com/FFmpeg/FFmpeg/blob/f951aa9ef382d6bb517e05d04d52710f751de427/libavformat/internal.h#L30)), therefore you have to configure your identity server in order to produce JWTs that are shorter than this threshold. ### RTMP -Pass the token as password, with an arbitrary user: +Pass the token as query parameter: ``` -rtmp://localhost/mystream?user=user&pass=jwt +rtmp://localhost/mystream?jwt=jwt ``` -WARNING: FFmpeg implementation of RTMP does not support passwords and query parameters that are longer than 1024 characters, therefore you have to configure your identity server in order to produce JWTs that are shorter than this threshold. +WARNING: FFmpeg implementation of RTMP does not support query parameters that are longer than 1024 characters, therefore you have to configure your identity server in order to produce JWTs that are shorter than this threshold. ### SRT @@ -339,4 +339,4 @@ In OBS Studio, this is the "Bearer Token" field. If the `Authorization: Bearer` token cannot be directly provided (for instance, with web browsers that directly access _MediaMTX_ and show a credential dialog), you can pass the token as password, using an arbitrary user. -In web browsers, if you need to automatically fill credentials from a parent web page, see [Embed streams in a website](embed-streams-in-a-website). +In web browsers, if you need to automatically fill credentials from a parent web page, read [Embed streams in a website](embed-streams-in-a-website). diff --git a/internal/auth/manager.go b/internal/auth/manager.go index c554baf1..0ce5bb56 100644 --- a/internal/auth/manager.go +++ b/internal/auth/manager.go @@ -27,6 +27,14 @@ const ( jwksRefreshPeriod = 60 * 60 * time.Second ) +func isHTTP(req *Request) bool { + return req.Protocol == ProtocolHLS || req.Protocol == ProtocolWebRTC || + req.Action == conf.AuthActionPlayback || + req.Action == conf.AuthActionAPI || + req.Action == conf.AuthActionMetrics || + req.Action == conf.AuthActionPprof +} + func matchesPermission(perms []conf.AuthInternalUserPermission, req *Request) bool { for _, perm := range perms { if perm.Action == req.Action { @@ -224,7 +232,8 @@ func (m *Manager) authenticateJWT(req *Request) error { case req.Credentials.Pass != "": encodedJWT = req.Credentials.Pass - case m.JWTInHTTPQuery: + // always allow passing JWT through query parameters with RTSP and RTMP since there's no alternative. + case req.Protocol == ProtocolRTSP || req.Protocol == ProtocolRTMP || (isHTTP(req) && m.JWTInHTTPQuery): var v url.Values v, err = url.ParseQuery(req.Query) if err != nil { diff --git a/mediamtx.yml b/mediamtx.yml index ed408420..81ce37be 100644 --- a/mediamtx.yml +++ b/mediamtx.yml @@ -148,7 +148,7 @@ authJWTClaimKey: mediamtx_permissions # Format is the same as the one of user permissions. authJWTExclude: [] # allow passing the JWT through query parameters of HTTP requests (i.e. ?jwt=JWT). -# This is a security risk and will be disabled by default in the future. +# This is a security risk and will be disabled in the future. authJWTInHTTPQuery: true ###############################################