EveでREST APIを構築し、特定のエンドポイントを保護するためにロールを使用していますが、それ以上の場合、特定のフィールドレベルのアクセスルールを適用する必要もあります。Eveでフィールドレベルのセキュリティを実装するにはどうすればよいですか?
users = {
'schema': {
Schema.NAME: {
'type': 'string',
'minlength': 1,
'maxlength': 32,
'required': True,
'unique': True
},
Schema.PASSWORD: {
'type': 'string',
'required': True
},
Schema.ROLE: {
'type': 'string',
'allowed': ['end user', 'manager', 'admin'],
'required': True
}
},
エンドポイントがパブリックPOST
アクセス権を持っているので、誰でも(すなわち、新しいユーザーが自分のアカウントを作成することができます)ユーザを作成することができます:私は、次のスキーマの基本的なusers
エンドポイントを持っています。エンドユーザは自分のパスワードを変更でき、マネージャはエンドユーザのパスワードを変更でき、管理者はエンドユーザの役割を変更できます。
標準のスキーマ定義でこれを行う方法はありませんでした。私はCerberusの検証についても見ていたが、それは複数の文書にわたるロジックをサポートするようには見えなかった(すなわち、クライアントがuser
として認証されたことを確認してエンドユーザのuser
文書の変更を検証する)。
app.on_insert += all_users_created_equal
app.on_pre_PATCH_users += restrict_role_updates_to_admins
...
def all_users_created_equal(resource, docs):
"""Ensure that all users are created as end users.
Managers and Admins must be granted these roles by an existing
manager or admin."""
if resource == 'users':
for doc in docs:
doc['role'] = 'user'
def restrict_role_updates_to_admins(request, lookup):
if 'role' in request.json:
users = app.data.driver.db['users']
user = users.find_one({'name': request.authorization.username})
if user and user['role'] != 'admin':
# Non-admins cannot update roles. Break the lookup to fail the request.
lookup['_id'] = None
しかし、それは要求を失敗させるために要求内容をマックするハックです。フィールドレベルのセキュリティを強化するより良い方法はありますか?そうでない場合は、イベントフックを使用してサーバーに要求を失敗させるより良い方法がありますか?フックから例外を発生させると、要求は失敗しましたが、例外はサーバーの上に伝播され、理想的でもありませんでした。
リクエストを失敗させるより良い方法は、フラスコのアボート機能を呼び出すことです。次に、ドキュメントの例を示します(http://flask.pocoo.org/docs/0.12/quickstart/#redirects-and-errors)。 – gcw