Code Monkey home page Code Monkey logo

emqx-auth-jwt's Introduction

emqx-auth-jwt

EMQX JWT Authentication Plugin

Build

make && make tests

Configure the Plugin

File: etc/plugins/emqx_auth_jwt.conf

## HMAC Hash Secret.
##
## Value: String
auth.jwt.secret = emqxsecret

## From where the JWT string can be got
##
## Value: username | password
## Default: password
auth.jwt.from = password

## RSA or ECDSA public key file.
##
## Value: File
## auth.jwt.pubkey = etc/certs/jwt_public_key.pem

## Enable to verify claims fields
##
## Value: on | off
auth.jwt.verify_claims = off

## The checklist of claims to validate
##
## Value: String
## auth.jwt.verify_claims.$name = expected
##
## Variables:
##  - %u: username
##  - %c: clientid
# auth.jwt.verify_claims.username = %u

Load the Plugin

./bin/emqx_ctl plugins load emqx_auth_jwt

Example

mosquitto_pub -t 'pub' -m 'hello' -i test -u test -P eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYm9iIiwiYWdlIjoyOX0.bIV_ZQ8D5nQi0LT8AVkpM4Pd6wmlbpR9S8nOLJAsA8o

Algorithms

The JWT spec supports several algorithms for cryptographic signing. This plugin currently supports:

  • HS256 - HMAC using SHA-256 hash algorithm

  • HS384 - HMAC using SHA-384 hash algorithm

  • HS512 - HMAC using SHA-512 hash algorithm

  • RS256 - RSA with the SHA-256 hash algorithm

  • RS384 - RSA with the SHA-384 hash algorithm

  • RS512 - RSA with the SHA-512 hash algorithm

  • ES256 - ECDSA using the P-256 curve

  • ES384 - ECDSA using the P-384 curve

  • ES512 - ECDSA using the P-512 curve

License

Apache License Version 2.0

Author

EMQX Team.

emqx-auth-jwt's People

Contributors

emqplus avatar gilbertwong96 avatar hjianbo avatar huangdan avatar linjunjj avatar rory-z avatar spring2maz avatar terry-xiaoyu avatar tigercl avatar turtledeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

emqx-auth-jwt's Issues

JWT not passing check

I have a nodejs app that creates JWT tokens for users and it uses the default alg HS256, and I have set the secret on the node app and the emqtt plugin to be the same but I keep getting the 'password_error' in the logs. What am I doing wrong?

I'm using the paho android client and I put the JWT in the password field

EDIT:

I have found this inner case statement to be throwing the error. What i don't understand is it is decoding fine, but its being encoded a second time?

case jwt:encode(Jwt#jwt.alg, jsx:decode(Jwt#jwt.body), Secret) of
    {ok, Password} -> ok;
    _              -> {error, password_error}
end;

Validate username

The thing here is that if I have a valid JWT token, and if I know another username than my own, I can use this JWT to authenticate as the other user (any user actually, just need one valid JWT)

Is there a work around for this?
Originally posted by @rajivramv in #33 (comment)

JWE support

Hello!

Do you have plans to support JWE?
It would be very nice!

Handle exception in java client when token is expired

Is there a clear way to handle exceptions when jwt token is expired ?

In javascript client such as mqtt.js , when i send expired token to password field in connect method, offline method is called.In Java though, there is a package called: Eclipse Paho 'connectionLost' event is called.here is the thing :

By and large, there is not an appropriate way to handle token expiration exception in clients.
connection lost event could occure everywhere and every time, not just in token expiration
for instance : when mqtt server is offline or when s.th happend to connection. so there is not a transparent way to handle this.
1. What happens in backend side when an expired token is sent in password field ?
2. What event should be called in client side ?
3. How do detect in clients that emqx server denies the connection because there is an expired jwt token ?

Recheck exp claim

Hello, create job.
How would we react on the token expiration during subscribed session?
For example, we subscribed to some topic, and later within couple minutes a token would be expired.
Should't we disconnect the client?
I tested with the mosquitto client, like:

mosquitto_sub -C 1 -V mqttv5 -L mqtt://eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6IjEiLCJvcmciOjEsInJvbGUiOlsiYWRtaW4iLCJtYW5hZ2VyIl0sImV4cCI6MTYzMzgwNzU5NywiaWF0IjoxNjMzODA1Nzk3fQ.YKfEr4QfW8eXoy2s1XRDXAYDXcnBg_VL5j5j5lCxpLOed5o35p1P3WXuVSrH1Azyw0S4quawGMqeN-tGkuMXAsuJLiGAu_5Mp3u4FgDxNf0dlFFZFhredrdws1pOpphLruIXjtoFjsjLsPqr4VT9eo0QP7I0hdzcLLJ8UJsVjdSjOiVFcOakaSoZoa-tnK_DUlv7LKSYaviWICLCXJLaktlZrz3AD3RiErEbGAWQIlee6vfT9CiM_gKu8hZ2HO1ZmWfDFXS77YTNHZT9M3sUPpHgBgc-ZKlpfjIMWMI1svjMaFz24cyyWVEYLcWf9ymMktNw55ZcHtZyWCoUyT_lAQ@127.0.0.1:1883/sensor/1 -i 1 -q 2 -d -v -c

Connect to mqtt with a single password character

Hello,
Recently i have come across some issues connecting to mqtt while jwt auth is active.
as matter of a fact, when i connect to emqtt with simple password for instance 123456,this will connect to it successfully.
I am pretty sure that mqtt.allow_anonymous is false but any password is possible when i connect to mqtt. another thing is that when i set jwt token in password it works properly, even it checks the validity of the token but other characters will be passed.
emqtt version => docker version emqx/emqx

I checked this issue with tools such as MQTT Clients apps for instance mqttBox and mqtt.js in javascript.


mqtt.connect(MQTT_SOCKET_ENDPOINT, {
                    clean: false,
                    clientId: 'client_id',
                    username : 'username',
                    password : '123456'
 })

if this is not a problem what am i missing ?
was emqx-auth-jwt deleted from latest version of emqx ?

thank you in advance for your thoughtful answers.

login failed for rsa_pubkey_undefined

The option auth.jwt.pubkey = etc/certs/jwt_public_key.pem defined correctly and file exists. Pubkey is also correct and it works well with other software.
Also plugin works with HMAC but not RSA256 pub key. I can see only "login failed for rsa_pubkey_undefined" in debug log but it is not a clue. What is wrong and what should I do to fix this error?

Thank you!

RS256 not working

I am currently using emqx broker on kubernetes with anonymous auth internally.

Now wanted to expose it through websocket and was trying to use this plugin for auth.

However it turns out only HS256 alg type works with a secret.

I am using the latest emqx/emqx docker image v3.2.3, see startup logs:

node.max_ports=1048576
listener.tcp.external.acceptors=64
auth.jwt.secret=secret
listener.ssl.external.acceptors=32
node.process_limit=2097152
node.max_ets_tables=2097152
auth.jwt.verify_claims=off
listener.ws.external.acceptors=16
auth.jwt.pubkey=/etc/certs/issuer_cert.pem
auth.jwt.from=password
[email protected]
EMQX_LOADED_PLUGINS=emqx_management | emqx_dashboard | emqx_retainer | emqx_recon | emqx_auth_jwt
emqx v3.2.3 is started successfully!

I've configured both secret and public key.
secret: secret (i know this is not secure)

  • This cred works with the password field:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYm9iIiwiYWdlIjoyOX0.pbkBN3mEWDb2a6mLkoLXRirneliafU8ww_OhmuC1kI4
  • This one gives invalid_signature as expected:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYm9iIiwiYWdlIjoyOX0.pbkBN3mEWDb2a6mLkoLXRirneliafU8ww_OhmuC1kI4

Both above token is HS256.
Now this RS256 token gives weird error:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.FThNm4IGfWKNfZxrVjrzqUz3p7l5lm3b-HpbhqZhukNylQWx643ulhGznn4JdZqL8eYwp9Vevk2IB5Jm_VoUWODK9mKOnlzd9wVHwuJ1I8YcQuDBqe1ySOhZwqWSQWhnLEtpk6MrDCV8qQDqmDFFvN0nvzdqoyQlJzrud32RdykvjrkJGgiNhTCCPSJUHnDv2GP2E7930IHPEU2HvQvhqYgXeO6e_xhC0KlAMUSlG5yaaVxOTMXlEgjKy9l_U0Mrg3W0Q5DcYLIrIkRjnxI_SE2OKAdKxre0Zj-HbU9aJqvSAIOgjDDfJ-ddV7VgF_llZlvOze87HfvTRB5VwIGHkA

Error in log:
2019-09-16 05:22:47.512 [warning] [email protected]:57430 [Protocol] Client test_client (Username: 'test_user') login failed for badarg

Can not set auth.jwt.verify_claims.$name by env var

Hello!

I have working config file for JWT auth plugin wich do well all I need.
But I do prefer to use env vars to configure it.
I can set all params but not auth.jwt.verify_claims.$name
Env var have to be in upper case, but claims in JWT are in lowercase.
I had tried to use both EMQX_AUTH__JWT__VERIFY_CLAIMS__USERNAME=%u and EMQX_AUTH__JWT__VERIFY_CLAIMS__username=%u but with no luck.
I mean, it accept any valid JWT even if claims is not right.

Is it a bug and will be fixed or not?

Thank you!

Some help with key/cert please...

EMQX v4.0.6
Ubuntu 18.04 - installed from repo

I am new to EMQX, and trying to set up jwt-auth from vanilla in a dev environment. I am following the docs.

emqx_auth_jwt.conf is:

# etc/plugins/emqx_auth_jwt.conf

## Key
auth.jwt.secret = emqxsecret

## The way the client carries the token
## Value: username | password
auth.jwt.from = password


## Advanced options
## Public key file, certificate is used when signing the key
auth.jwt.pubkey = etc/certs/jwt_public_key.pem

## Value: on | off
auth.jwt.verify_claims = off

## auth.jwt.verify_claims.$name = expected

## Variables:
##  - %u: username
##  - %c: clientid
# auth.jwt.verify_claims.username = %u

etc/certs/jwt_public_key.pem does not exist from clean install (Ubuntu 18.04), and I cannot find instructions for creating it from "emqxsecret".

I have tried:

  1. creating fresh private / public keys and using the new public.pem
  2. commenting out auth.jwt.pubkey = etc/certs/jwt_public_key.pem

But in all circumstances, when trying to start the emqx_auth_jwt plugin from dashboard, I am getting the following error:

{emqx_auth_jwt, {bad_return, {{emqx_auth_jwt_app,start,[normal,[]]}, {'EXIT', {{badmatch,{error,enoent}}, [{emqx_auth_jwt_app,read_pubkey,0, [{file, "/emqx-rel/_build/emqx-pkg/lib/emqx_auth_jwt/src/emqx_auth_jwt_app.erl"}, {line,63}]}, {emqx_auth_jwt_app,auth_env,0, [{file, "/emqx-rel/_build/emqx-pkg/lib/emqx_auth_jwt/src/emqx_auth_jwt_app.erl"}, {line,55}]}, {emqx_auth_jwt_app,start,2, [{file, "/emqx-rel/_build/emqx-pkg/lib/emqx_auth_jwt/src/emqx_auth_jwt_app.erl"}, {line,35}]}, {application_master,start_it_old,4, [{file,"application_master.erl"},{line,277}]}]}}}}}

I believe that this is not an error, but me missing some basic key/cert concept here, but I cannot find documentation to help get me up and running.

Thanks in advance...

Cannot match header

不太懂erlang,但是看了半天后感觉src/emq_auth_jwt.erl的39行左右是有问题的。

在我的应用中,Header的内容是:{"alg":"HS256","typ":"JWT"},而在emq-auth-jwt中Header的内容是:{"typ":"JWT","alg":"HS256"}。结果就是正确的密码串连接时却得到以下错误内容:

12:21:32.501 [error] JWT encode fail:{ok,<<"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDQ3MDA0NDgsImlzcyI6InV3ZWVyIiwidWlkIjoiNTlhNmE4MzdlZjNhZDFkYTE3NGIwODAyIiwibW9kIjo2fQ.UTlV66DfXzqbMg_yh5fq5HowDcEa67MnGVxaGtbwyPk">>}

能不能修正一下,谢谢

how to verify jwt?

Hello,

I'm trying to understand how to connect android app to emqtt broker using jwt for authentication.

I've set up with emq-auth-jwt plugin and secret key, username and pwd(JWT), so looks it works.

However, even if I put any string as username and pwd like "1" or any string not JWT, it's also working.(suppose to be verified)

is it correct way to use jwt?

Thanks!!!

Expired token

Hi, Is it possibile validate token using a expired field?

Example:

{
  "alg": "RS256",
  "typ": "JWT"
}
{
  "exp": 1521030758,
  "id": 1,
  "iat": 1521027158
}

Many thanks

Option to disable signature-type "none"

It would be nice to have a configuration option to disallow certain signature-types for JWT tokens or at least the "none"-type.

It will be nice if that worked "out of the box" at some point.
Thank you for your consideration.

Option to pass the jwt pubkey through environment variable

I am suggesting an enhancement. The config file has option to configure auth.jwt.pubkey like this:

## RSA or ECDSA public key file.
##
## Value: File
auth.jwt.pubkey = etc/certs/jwt_public_key.pem

which can be passed as env var to EMQX like this:
EMQX_AUTH__JWT__PUBKEY="etc/certs/jwt_public_key.pem"

It would be nice if you could pass the value of the key through the env var (maybe detect if it's a path in the filesystem or a certificate) like this EMQX_AUTH__JWT__PUBKEY="MIIBIjA..AB".

We are deploying EMQX with docker and I can use the official image to configure everything related to emqx-auth-http through env vars, but for this plugin I have to create a new docker image just to add the certificate file.

ACL implementation

I see that all authentication plugin have ACL (mysql, postgree, etc)

In this plugin it's possibile for all client subscribe to all topics if client know topic structure
My idea was to have inside the jwt the names of the topic where client can subscribe or publish

{
  "id": 5,
  "iat": 1522935842,
  "exp": 1522939442
 "topics" ["x","y","z"]
}

Is it a bad idea? Is there anything else that allows you to do this already?

Set username from JWT

We are currently looking to migrate from GCP IOT to emqx, but need the ability to extract username from JWT token(Our devices don't have a username). Is it possible to add an option for this plugin to set username from JWT field?

why not support RS512?

Hi,
Why module emq-auth-jwt not support RS512? my system use RS512 for support public/private key. how can i use jwt support RS512 with emq-auth-jwt?

Questions: Can this jwt plugin support multiple public keys?

Use scenario:

User have tens of thousand of device that will connected to the cloud through MQTT protocol.
Each device will has it's unique key pare for authentication,
The client will use the private key for create the JWT token.

Question:
Then how can we configure the public keys for all of those devices?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.