Authentication failed when using flask_pymongo
Question:
I’m sure that the MONGO_URI is correct because it works well in pymongo.
but when using flask_pymongo, it doesn’t work…
here is my test code:
from flask import Flask
from flask_pymongo import PyMongo
app = Flask(__name__)
app.config['MONGO_URI'] ='mongodb://root:aaa2016@localhost:27017/mongo_test'
mongo = PyMongo(app, config_prefix='MONGO')
@app.route('/')
def hello_world():
mongo.db.user.insert({'username': "aaa"})
return 'Hello World!'
if __name__ == '__main__':
app.run()
run it and visit 127.0.0.1:5000, a response of 500 is given..
OperationFailure: Authentication failed.
127.0.0.1 - - [21/Jun/2016 20:40:25] "GET / HTTP/1.1" 500 -
any help will be appreciated.
update:
here is the traceback:
File "C:Python27libsite-packagesflaskapp.py", line 2000, in __call__
return self.wsgi_app(environ, start_response)
File "C:Python27libsite-packagesflaskapp.py", line 1991, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "C:Python27libsite-packagesflaskapp.py", line 1567, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:Python27libsite-packagesflaskapp.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "C:Python27libsite-packagesflaskapp.py", line 1641, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:Python27libsite-packagesflaskapp.py", line 1544, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:Python27libsite-packagesflaskapp.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "C:Python27libsite-packagesflaskapp.py", line 1625, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "F:PycharmProjectsflask_flask_.py", line 12, in hello_world
mongo.db.user.insert({'username': "aaa"})
File "C:Python27libsite-packagespymongocollection.py", line 2203, in insert
with self._socket_for_writes() as sock_info:
File "C:Python27libcontextlib.py", line 17, in __enter__
return self.gen.next()
File "C:Python27libsite-packagespymongomongo_client.py", line 718, in _get_socket
with server.get_socket(self.__all_credentials) as sock_info:
File "C:Python27libcontextlib.py", line 17, in __enter__
return self.gen.next()
File "C:Python27libsite-packagespymongoserver.py", line 152, in get_socket
with self.pool.get_socket(all_credentials, checkout) as sock_info:
File "C:Python27libcontextlib.py", line 17, in __enter__
return self.gen.next()
File "C:Python27libsite-packagespymongopool.py", line 541, in get_socket
sock_info.check_auth(all_credentials)
File "C:Python27libsite-packagespymongopool.py", line 306, in check_auth
auth.authenticate(credentials, self)
File "C:Python27libsite-packagespymongoauth.py", line 436, in authenticate
auth_func(credentials, sock_info)
File "C:Python27libsite-packagespymongoauth.py", line 416, in _authenticate_default
return _authenticate_scram_sha1(credentials, sock_info)
File "C:Python27libsite-packagespymongoauth.py", line 188, in _authenticate_scram_sha1
res = sock_info.command(source, cmd)
File "C:Python27libsite-packagespymongopool.py", line 213, in command
read_concern)
File "C:Python27libsite-packagespymongonetwork.py", line 99, in command
helpers._check_command_response(response_doc, None, allowable_errors)
File "C:Python27libsite-packagespymongohelpers.py", line 196, in _check_command_response
raise OperationFailure(msg % errmsg, code, response)
OperationFailure: Authentication failed.
Answers:
The problem is if you use the MONGO_URI
config parameter then pymongo attempts to authenticate against the db name included in the string. You should break up the config parameters into the following so you can specify a db name and an auth source.
app.config['MONGO_HOST'] = 'localhost'
app.config['MONGO_PORT'] = '27017'
app.config['MONGO_DBNAME'] = 'mongo_test'
app.config['MONGO_USERNAME'] = 'root'
app.config['MONGO_PASSWORD'] = 'aaa2016'
app.config['MONGO_AUTH_SOURCE'] = 'admin' . # root user is typically defined in admin db
This question may be old, but I was experiencing the same issue and found another solution that might work for others.
Appending ?authSource=admin
to the end of your MONGO_URI
variable will authenticate your credentials against the admin database, rather than the one you’re connecting to.
Example:
app.config["MONGO_URI"] = "mongodb://username:password@host:port/db_name?authSource=admin"
If you are using Flask-MongoEngine and setting mongo config using app.config['MONGODB_*']
then, your uri will be generated from those variables e.g.
app.config['MONGODB_DB'] = 'project1'
app.config['MONGODB_HOST'] = '192.168.1.35'
app.config['MONGODB_PORT'] = 12345
app.config['MONGODB_USERNAME'] = 'webapp'
app.config['MONGODB_PASSWORD'] = 'pwd123'
However, if you need to add some additional paramters (such query parameter authSource=admin
) to uri then, you will have to pass mongo config through app.config['MONGODB_SETTINGS']
app.config['MONGODB_SETTINGS'] = {
'connect': False,
'host': 'mongodb://webapp:[email protected]:12345/project1?authSource=admin'
}
This is pretty much what it worked for me using flask_pymongo:
from flask import Flask
from flask_pymongo import PyMongo
app = Flask(__name__)
app.config['MONGO_URI']='mongodb://appUser:passwordForAppUser@localhost/app_db?authSource=admin'
mongo=PyMongo(app)
Or you can also try this other example using MongoEngine instead:
from flask import Flask
from flask_mongoengine import MongoEngine
app = Flask(__name__)
app.config['MONGODB_SETTINGS'] = {
'db': 'app_db',
'host': 'localhost',
'port': 27017,
'username': 'appUser',
'password': 'passwordForAppUser',
'authentication_source': 'admin'
}
db = MongoEngine(app)
I’m sure that the MONGO_URI is correct because it works well in pymongo.
but when using flask_pymongo, it doesn’t work…
here is my test code:
from flask import Flask
from flask_pymongo import PyMongo
app = Flask(__name__)
app.config['MONGO_URI'] ='mongodb://root:aaa2016@localhost:27017/mongo_test'
mongo = PyMongo(app, config_prefix='MONGO')
@app.route('/')
def hello_world():
mongo.db.user.insert({'username': "aaa"})
return 'Hello World!'
if __name__ == '__main__':
app.run()
run it and visit 127.0.0.1:5000, a response of 500 is given..
OperationFailure: Authentication failed.
127.0.0.1 - - [21/Jun/2016 20:40:25] "GET / HTTP/1.1" 500 -
any help will be appreciated.
update:
here is the traceback:
File "C:Python27libsite-packagesflaskapp.py", line 2000, in __call__
return self.wsgi_app(environ, start_response)
File "C:Python27libsite-packagesflaskapp.py", line 1991, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "C:Python27libsite-packagesflaskapp.py", line 1567, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:Python27libsite-packagesflaskapp.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "C:Python27libsite-packagesflaskapp.py", line 1641, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:Python27libsite-packagesflaskapp.py", line 1544, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:Python27libsite-packagesflaskapp.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "C:Python27libsite-packagesflaskapp.py", line 1625, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "F:PycharmProjectsflask_flask_.py", line 12, in hello_world
mongo.db.user.insert({'username': "aaa"})
File "C:Python27libsite-packagespymongocollection.py", line 2203, in insert
with self._socket_for_writes() as sock_info:
File "C:Python27libcontextlib.py", line 17, in __enter__
return self.gen.next()
File "C:Python27libsite-packagespymongomongo_client.py", line 718, in _get_socket
with server.get_socket(self.__all_credentials) as sock_info:
File "C:Python27libcontextlib.py", line 17, in __enter__
return self.gen.next()
File "C:Python27libsite-packagespymongoserver.py", line 152, in get_socket
with self.pool.get_socket(all_credentials, checkout) as sock_info:
File "C:Python27libcontextlib.py", line 17, in __enter__
return self.gen.next()
File "C:Python27libsite-packagespymongopool.py", line 541, in get_socket
sock_info.check_auth(all_credentials)
File "C:Python27libsite-packagespymongopool.py", line 306, in check_auth
auth.authenticate(credentials, self)
File "C:Python27libsite-packagespymongoauth.py", line 436, in authenticate
auth_func(credentials, sock_info)
File "C:Python27libsite-packagespymongoauth.py", line 416, in _authenticate_default
return _authenticate_scram_sha1(credentials, sock_info)
File "C:Python27libsite-packagespymongoauth.py", line 188, in _authenticate_scram_sha1
res = sock_info.command(source, cmd)
File "C:Python27libsite-packagespymongopool.py", line 213, in command
read_concern)
File "C:Python27libsite-packagespymongonetwork.py", line 99, in command
helpers._check_command_response(response_doc, None, allowable_errors)
File "C:Python27libsite-packagespymongohelpers.py", line 196, in _check_command_response
raise OperationFailure(msg % errmsg, code, response)
OperationFailure: Authentication failed.
The problem is if you use the MONGO_URI
config parameter then pymongo attempts to authenticate against the db name included in the string. You should break up the config parameters into the following so you can specify a db name and an auth source.
app.config['MONGO_HOST'] = 'localhost'
app.config['MONGO_PORT'] = '27017'
app.config['MONGO_DBNAME'] = 'mongo_test'
app.config['MONGO_USERNAME'] = 'root'
app.config['MONGO_PASSWORD'] = 'aaa2016'
app.config['MONGO_AUTH_SOURCE'] = 'admin' . # root user is typically defined in admin db
This question may be old, but I was experiencing the same issue and found another solution that might work for others.
Appending ?authSource=admin
to the end of your MONGO_URI
variable will authenticate your credentials against the admin database, rather than the one you’re connecting to.
Example:
app.config["MONGO_URI"] = "mongodb://username:password@host:port/db_name?authSource=admin"
If you are using Flask-MongoEngine and setting mongo config using app.config['MONGODB_*']
then, your uri will be generated from those variables e.g.
app.config['MONGODB_DB'] = 'project1'
app.config['MONGODB_HOST'] = '192.168.1.35'
app.config['MONGODB_PORT'] = 12345
app.config['MONGODB_USERNAME'] = 'webapp'
app.config['MONGODB_PASSWORD'] = 'pwd123'
However, if you need to add some additional paramters (such query parameter authSource=admin
) to uri then, you will have to pass mongo config through app.config['MONGODB_SETTINGS']
app.config['MONGODB_SETTINGS'] = {
'connect': False,
'host': 'mongodb://webapp:[email protected]:12345/project1?authSource=admin'
}
This is pretty much what it worked for me using flask_pymongo:
from flask import Flask
from flask_pymongo import PyMongo
app = Flask(__name__)
app.config['MONGO_URI']='mongodb://appUser:passwordForAppUser@localhost/app_db?authSource=admin'
mongo=PyMongo(app)
Or you can also try this other example using MongoEngine instead:
from flask import Flask
from flask_mongoengine import MongoEngine
app = Flask(__name__)
app.config['MONGODB_SETTINGS'] = {
'db': 'app_db',
'host': 'localhost',
'port': 27017,
'username': 'appUser',
'password': 'passwordForAppUser',
'authentication_source': 'admin'
}
db = MongoEngine(app)