python 认证 国际_python-eve 认证和授权

验证类型

全局验证

要实现安全认证,只需要在Eve实例化的时候传入验证类即可,这样就创建了一个全局的验证类

from eve.auth import BasicAuth

class MybasicAuth(BasicAuth):

def check_auth(self, username, password, allowed_roles, resource, method):

return username == 'admin' and password == 'admin'

app = Eve(auth=MybasicAuth)

只有用户名和密码满足条件才允许访问

如果要做到对某一资源公开,其他资源安全,可以用下面的写法

if resource in ('people','countries'):

return True

else:

return username == 'admin' and password == 'secret'

同样,你可以控制method,以在某个方法上启用或者关闭验证

资源级验证

有时候要对某些资源进行特别的权限控制,这时候全局验证就不太好用了

可以重写某个资源的验证类

people = {

'authentication':MyEndpointAuth,

}

其中MyEndpointAuth和上面的MybaseAuth一样继承自BasicAuth并且重写了check_auth方法,可以为每一个资源设置不同的验证方法

全局资源安全方法

在setting中加入下面的内容,可以使所有资源的GET方法都是公开的

PUBLIC_METHODS = ['GET']

PUBLIC_ITEM_METHODS = ['GET']

PUBLIC_METHODS 引用资源端点,例如/ people ,而PUBLIC_ITEM_METHODS引用像/people/这样的单个项目。

自定义资源安全方法

可以为资源设置public_methods,public_item_methods来设置资源的访问控制,资源中的这两个属性会覆盖全局设定,利用这一特点可以设置全部资源公开但某一资源私有

DOMAIN = {

'invoices': {

'public_methods': [],

'public_item_methods': [],

}

}

这样invoices这个资源就被隐藏了

验证方法

使用SHA1 / HMAC进行身份验证

假设用户名和密码都存储在MongoDB中,并且密码存储为SHA1 / HMAC哈希值,我们可以用下面的方法验证用户名和密码

from eve.auth import BasicAuth

from werkzeug.security import check_password_hash

from flask import current_app as app

class Sha1Auth(BasicAuth):

def check_auth(self, username, password, allowed_roles, resource, method):

# use Eve's own db driver; no additional connections/resources are used

accounts = app.data.driver.db['accounts']

account = accounts.find_one({'username': username})

return account and \

check_password_hash(account['password'], password)

为了要测试用户名和密码,我们要事先往mongodb的accounts表中插入一条记录

use eve

db.createCollection("accounts")

db.accounts.insert({username:"test1",passowrd:"pbkdf2:sha1:1000$v86Nv0hS$817921c0a065c4289416f559a2d8da3010b66727"})

密码为admin

tips:更新密码请用db.accounts.update({"username":"test1"},{$set:{"password":"new password"}})

之后测试登录即可

使用TOKEN验证

token验证可以看作只有用户名没有密码的验证方式,使用Token作为验证,Token本身必须具备足够的强度并且有合理的失效机制

class TokenAuthS(TokenAuth):

def check_auth(self, token, allowed_roles, resource, method):

accounts = app.data.driver.db['accounts']

return accounts.find_one({'token': token})

和SHA1/HMAC验证一样,我们要事先在数据库里存放一个token,方法类似

db.accounts.insert({toke:"86Nv0h817921c0a065c4289416f559a2d8da3010b66727"})

HMAC认证

eve.auth.HMACAuth类允许自定义的类似于Amazon S3的HMAC(哈希消息认证码)认证,这基本上是一个非常安全的定制认证方案,围绕Authorization头部而构建。

要使用HMAC验证,需要通过一些外部技术(例如,向客户发送包含用户ID和秘密密钥的电子邮件)向客户端提供用户ID和密钥。 客户端将使用提供的密钥来签署所有请求。

当客户想要发送一个请求时,先建立完整的请求,然后使用密钥,在整个消息体上计算一个散列(如果需要的话还可以包含一些消息头),接下来,客户端将计算出的散列和他的用户ID添加到授权标头中的消息中,下面是一个例子:

Authorization: johndoe:uCMfSzkjue+HSDygYB5aEg==

如果要实现类似的效果,可以这样做:

1.先往mongodb中插入一条记录,记录userid和secret_key

2.用secret_key计算出我们需要的散列值,添加到头中,eve中写法如下

class HMACAuths(HMACAuth):

def check_auth(self, userid, hmac_hash, headers, data, allowed_roles,

resource, method):

accounts = app.data.driver.db['accounts']

user = accounts.find_one({'userid': userid})

if user:

secret_key = user['secret_key']

return user and hmac.new(bytes(secret_key.encode()), data, sha1).hexdigest() == hmac_hash

访问控制

基于角色的访问控制

在上面的内容中被故意忽略的参数allowed_roles,作用是利用角色来控制对资源的访问,要想要预览这效果,需要修改之前存在mongodb中的用户名密码,为其增加roles属性

db.accounts.update({username:"test1"},{$set:{"roles":"admin"}})

setting中添加全局资源允许的操作角色,也可以在资源中设置覆盖全角的ALLOWED_ROLES设定

ALLOWED_ROLES = ['superadmin','admin']

之后修改check_auth方法

def check_auth(self, username, password, allowed_roles, resource, method):

accounts = app.data.driver.db['accounts']

lookup = {'username': username}

if allowed_roles:

# 只有角色符合才允许后续操作

lookup['roles'] = {'$in': allowed_roles}

account = accounts.find_one(lookup)

return account and check_password_hash(account['password'], password)

之后用test1这个角色登录即可看到内容

用户对资源控制

这是一个仅允许资源创建者对资源进行控制的功能,需要在setting中设置AUTH_FIELD并且在资源中设置auth_field属性,我们假设添加到字段为user_id

1.首先setting.py中添加 AUTH_FIELD = []

2.然后people中添加'auth_field':'user_id'

3.最后将check_auth方法修改为

def check_auth(self, username, password, allowed_roles, resource, method):

accounts = app.data.driver.db['accounts']

account = accounts.find_one({'username': username})

if account and '_id' in account:

self.set_request_auth_value(account['_id'])

return account and check_password_hash(account['password'], password)

之后我们插入新的用户test2,用test2创建新的people资源,再用test1去查看,会发现无法获取到内容test2创建的内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值