Pyramid 安全性

2023-03-30 17:58 更新

Pyramid的聲明式安全系統(tǒng)確定了當前用戶的身份,并驗證了用戶是否可以訪問某些資源。安全策略可以阻止用戶調(diào)用某個視圖。在任何視圖被調(diào)用之前,授權(quán)系統(tǒng)使用請求中的憑證來確定是否允許訪問。

安全策略被定義為一個類,在 pyramid.security 模塊中定義的以下方法的幫助下控制用戶訪問

  • forget(request) – 該方法返回適合于 “忘記 “當前認證用戶所擁有的憑證集的頭元。它通常在視圖函數(shù)的主體中使用。
  • remember(request, userid) – 這個方法在請求的響應中返回一連串的頭圖元。它們適合于 “記住 “一組憑證,如使用當前安全策略的userid。在一個視圖函數(shù)的主體中,常見的用法可能是這樣的。

認證用戶的訪問由本模塊中的 Allowed 和 Denied 類的對象來控制。

為了實現(xiàn)身份、記憶和遺忘機制的功能,Pyramid提供了以下定義在pyramid.authentication模塊中的helper類 ?

  • SessionAuthenticationHelper – 在會話中存儲用戶ID。
  • AuthTktCookieHelper – 用 “auth ticket “cookie存儲用戶名。

我們還可以使用 extract_http_basic_credentials() 函數(shù)來檢索使用HTTP Basic Auth的用戶憑證。

要從WSGI環(huán)境中的REMOTE_USER檢索用戶ID,可以使用 request.environ.get(‘REMOTE_USER’) 。

例子

現(xiàn)在讓我們學習如何在以下例子的幫助下實現(xiàn)安全策略。這個例子的 “development.ini “如下所示

[app:main]
use = egg:tutorial
pyramid.reload_templates = true
pyramid.includes = pyramid_debugtoolbar
hello.secret = a12b

[server:main]
use = egg:waitress#main
listen = localhost:6543

然后我們在下面的Python代碼中編寫安全策略類,保存為 security.py --

from pyramid.authentication import AuthTktCookieHelper
USERS = {'admin': 'admin', 'manager': 'manager'}
class SecurityPolicy:
   def __init__(self, secret):
      self.authtkt = AuthTktCookieHelper(secret=secret)
   def identity(self, request):
      identity = self.authtkt.identify(request)
      if identity is not None and identity['userid'] in USERS:
      return identity
   def authenticated_userid(self, request):
      identity = self.identity(request)
      if identity is not None:
         return identity['userid']
   def remember(self, request, userid, **kw):
      return self.authtkt.remember(request, userid, **kw)
   def forget(self, request, **kw):
      return self.authtkt.forget(request, **kw)

我們的軟件包文件夾中的 __init__.py 文件定義了以下配置。上面定義的安全策略類通過配置器類的 set_security_policy() 方法被添加到配置中。三個路由–home、login和logout–被添加到配置中。

from pyramid.config import Configurator
from .security import SecurityPolicy

def main(global_config, **settings):
   config = Configurator(settings=settings)
   config.include('pyramid_chameleon')
   config.set_security_policy(
      SecurityPolicy(
         secret=settings['hello.secret'],
      ),
   )
   config.add_route('home', '/')
   config.add_route('login', '/login')
   config.add_route('logout', '/logout')
   config.scan('.views')
   return config.make_wsgi_app()

在views.py中定義了與上述路線對應的三個視圖。

from pyramid.httpexceptions import HTTPFound
from pyramid.security import remember, forget

from pyramid.view import view_config, view_defaults
from .security import USERS

@view_defaults(renderer='home.pt')
class HelloViews:
   def __init__(self, request):
      self.request = request
      self.logged_in = request.authenticated_userid
   @view_config(route_name='home')
   def home(self):
      return {'name': 'Welcome'}
   @view_config(route_name='login', renderer='login.pt')
   def login(self):
      request = self.request
      login_url = request.route_url('login')
      referrer = request.url
      if referrer == login_url:
         referrer = '/'
      came_from = request.params.get('came_from', referrer)
      message = ''
      login = ''
      password = ''
      if 'form.submitted' in request.params:
         login = request.params['login']
         password = request.params['password']
         pw = USERS.get(login)
         if pw == password:
            headers = remember(request, login)
            return HTTPFound(location=came_from, headers=headers)
         message = 'Failed login'
         return dict(
            name='Login', message=message,
            url=request.application_url + '/login',
            came_from=came_from,
            login=login, password=password,)

   @view_config(route_name='logout')
   def logout(self):
      request = self.request
      headers = forget(request)
      url = request.route_url('home')
      return HTTPFound(location=url, headers=headers)

登錄視圖顯示了登錄表單。當用戶輸入的用戶身份和密碼與用戶列表進行核對時,這些細節(jié)會被 “記住”。另一方面,注銷視圖通過 “遺忘 “釋放這些細節(jié)。

主頁視圖顯示了以下變色龍模板 – home.pt

<!DOCTYPE html>
<html lang="en">
<body>
   <div>
      <a tal:condition="view.logged_in is None" href="${request.application_url}/login">Log In</a>
      <a tal:condition="view.logged_in is not None" href="${request.application_url}/logout">Logout</a>
   </div>
   <h1>Hello. ${name}</h1>
</body>
</html>

以下是變色龍模板 login.pt ,用于登錄查看。

<!DOCTYPE html>
<html lang="en">
<body>
   <h1>Login</h1>
   <span tal:replace="message"/>

   <form action="${url}" method="post">
      <input type="hidden" name="came_from" value="${came_from}"/>
      <label for="login">Username</label>
      <input type="text" id="login" name="login" value="${login}"/><br/>
      <label for="password">Password</label>
      <input type="password" id="password" name="password" value="${password}"/><br/>
      <input type="submit" name="form.submitted" value="Log In"/>
   </form>
</body>
</html>

development.ini和setup.py放在外部項目文件夾中,而 __init__.py、views.py、security.py 和模板 home.pt 以及 login.pt 應該保存在名為hello的軟件包文件夾中。

用下面的命令安裝該軟件包

Env\hello>pip3 install -e.

用 pserve 工具啟動服務(wù)器。

pserve development.ini

輸出

打開瀏覽器,訪問 http://localhost:6543/ 鏈接 。

Python Pyramid - 安全性

點擊 “登錄 “鏈接,打開登錄表格—-。

Python Pyramid - 安全性

主視圖頁面回來時,鏈接改為注銷,因為憑證被記住了。

Python Pyramid - 安全性

點擊 “注銷 “鏈接將導致忘記憑證,并將顯示默認的主頁。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號