Dart服務器端 shelf_auth包

Dart Shelf的認證和受權中間件html

介紹

提供Shelf中間件,用於驗證用戶(或系統)和創建會話,以及受權訪問資源。java

用法

認證

注意:有關構建身份驗證中間件的替代方法,請參閱下面的「身份驗證生成器」部分。數據庫

var authMiddleware = authenticate([
          new BasicAuthenticator(new TestLookup()),
          new RandomAuthenticator()]));

Shelf Auth提供了一個authenicate函數,它接受一個Authenticators列表和一個可選的SessionHandler(見下文)並建立Shelf Middleware。安全

而後,您能夠在shelf pipeline中的適當位置添加此Middleware.服務器

var handler = const Pipeline()
      .addMiddleware(exceptionHandler())
      .addMiddleware(authMiddleware)
      .addHandler((Request request) => new Response.ok("I'm in with "
          "${getAuthenticatedContext(request).map((ac) => ac.principal.name)}\n"));

  io.serve(handler, 'localhost', 8080);

調用身份驗證中間件時,它會按順序經過身份驗證器。 每一個Authenticator都執行如下操做之一cookie

  • 返回表示身份驗證成功的結果(帶有上下文)
  • 返回一個代表身份驗證者沒有找到任何與之相關的憑據結果
  • 拋出一個異常,代表驗證器確實找到了相關的憑據,但認爲用戶不該該登陸

第一個Authenticator返回成功身份驗證或拋出異常。 若是Authenticator指示它未找到相關憑據,則調用列表中的下一個驗證器。session

若是沒有拋出異常,那麼將調用傳遞給中間件的innerHandler。若是身份驗證成功,則請求將在請求上下文中包含與身份驗證相關的數據。這能夠經過getAuthenticatedContext函數從當前請求中檢索,也能夠經過authenticatedContext從當前區域中檢索。app

成功的認證會建立新區域(將通過身份驗證的上下文設置爲區域變量)。 可使用authenticatedContext函數訪問它。dom

若是沒有任何驗證器處理請求,則調用innerHandler而不使用任何驗證上下文。下游處理程序應該將其視爲未經身份驗證的(來賓)用戶訪問。您能夠經過使用allowAnonymousAccess:false調用authenticate函數來拒絕匿名訪問。ssh

在登陸時創建會話

若是沒有爲authenticate函數提供SesionHandler,則不會創建任何會話。 這意味着每一個請求都須要進行身份驗證。 這適用於系統到系統調用以及基自己份驗證等身份驗證機制。

要在成功登陸時建立會話,還包括SessionHandler

var authMiddleware = authenticate([new RandomAuthenticator()],
      new JwtSessionHandler('super app', 'shhh secret', testLookup));

若是生成的AuthenticatedContext支持會話,則將在成功驗證時調用SessionHandler

請注意,除了指示身份驗證是否成功以外,Authenticators還指示是否容許建立會話。對於某些認證機制(例如服務器到服務器調用),可能不但願建立會話。

SessionHandlers提供了一個Authenticator,它始終是第一個爲請求調用的身份驗證器。只有在沒有活動會話時纔會調用其餘身份驗證器。

請注意,Shelf Auth不會涵蓋session屬性的存儲(添加/檢索)。這超出了範圍。 只有會話處理的身份驗證相關部分纔在範圍內。任何支持Shelf Auth標頭或可與其集成的會話存儲庫均可以使用Shelf Auth。

驗證器

Shelf Auth提供如下開箱即用的驗證器:

BasicAuthenticator

支持基自己份驗證(http://tools.ietf.org/html/rfc2617)

默認狀況下,BasicAuthenticator不支持會話建立。 這能夠在建立驗證器時重寫,以下所示

new BasicAuthenticator(new TestLookup(), sessionCreationAllowed: true)

UsernamePasswordAuthenticator

用於專用登陸路由的Authenticator。 默認狀況下,假定基於表單的POST使用名爲usernamepassword的表單字段,例如。

curl -i  -H 'contentType: application/x-www-form-urlencoded' -X POST -d 'username=fred&password=blah' http://localhost:8080/login

這種身份驗證方式幾乎老是與創建會話相關聯。

var loginMiddleware = authenticate(
  [new UsernamePasswordAuthenticator(lookupByUsernamePassword)],
  sessionHandler: sessionHandler);

您能夠設置登陸路由(在此示例中使用shelf_route)並傳入此中間件。

rootRouter.post('/login', (Request request) => new Response.ok(
    "I'm now logged in as ${loggedInUsername(request)}\n"),
    middleware: loginMiddleware);

如今,您一般會設置經過登陸時創建的會話訪問的其餘路由。

var defaultAuthMiddleware = authenticate([],
    sessionHandler: sessionHandler, allowHttp: true,
    allowAnonymousAccess: false);
      
rootRouter.child('/authenticated', middleware: defaultAuthMiddleware)
    ..get('/foo', (Request request) => new Response.ok(
        "Doing foo as ${loggedInUsername(request)}\n"));

在此示例中,以/ authenticated開頭的全部路由都須要有效的會話。

認證人員名單預計會隨着時間的推移而增加。

此外,您能夠輕鬆建立本身的自定義身份驗證器。

Session Handlers

Shelf Auth提供如下開箱即用的SessionHandler:

JwtSessionHandler

這使用JWT建立在響應的Authorization標頭中返回的身份驗證令牌。後續請求必須在Authorization標頭中傳回令牌。這是一種承載風格的令牌機制。注意:與HTTP消息中傳遞的全部安全憑證同樣,若是有人可以攔截請求或響應,則他們能夠竊取令牌並模擬用戶。確保使用HTTPS。

特徵

  • 不須要在服務器上存儲任何東西來支持會話。 任何有權訪問用於建立令牌的祕密的服務器進程均可以對其進行驗證。
  • 支持非活動超時和總會話超時

其餘會話處理程序(如基於cookie的機制)可能會在將來添加

Authentication Builder

爲了簡化建立身份驗證中間件的過程,特別是在使用捆綁的身份驗證器和會話處理程序時,會提供構建器。例如

var authMiddleware = (builder()
    .basic(userNamePasswordLookup, 
      sessionCreationAllowed: true)
    .jwtSession('me', 'sshh', usernameLookup)
    ..allowHttp=true)
  .build();

注意:此示例有點複雜,由於您一般不但願使用基自己份驗證建立會話

受權

var authorisationMiddleware = authorise([new SameOriginAuthoriser()]);

Shelf Auth提供authorise函數,該功能獲取Authoriser列表並建立Shelf Middleware

此外,authorisationBuilder還提供了一個用於建立受權中間件的構建器,包括開箱即用的受權者

var authorisationMiddleware = (authorisationBuilder()
    .sameOrigin()
    .principalWhitelist((Principal p) => p.name == 'fred'))
  .build();

若是任何受權人(Authoriser)拒絕訪問,則:

  • 若是有通過身份驗證的用戶,則拋出ForbiddenException
  • 不然拋出UnauthorizedException。

Authorisers

Shelf Auth提供如下受權商:

AuthenticatedOnlyAuthoriser

僅容許訪問通過身份驗證的用戶。 若是請求中沒有當前的AuthenticatedContext,則拒絕訪問。

SameOriginAuthoriser

經過拒絕訪問引用不是來自與請求URL相同的主機的請求來幫助防止XSRF攻擊。

PrincipalWhitelistAuthoriser

容許訪問做爲給定PrincipalWhiteList一部分的任何主體的受權者。

PrincipalWhiteList能夠以多種方式實現。 例如,它根據名稱中的靜態內存列表檢查主體名稱。

final whitelist = [ 'fredlintstone@stone.age' ];
  
final whitelistAuthoriser = new PrincipalWhitelistAuthoriser(
    (Principal p) => whitelist.contains(p.name));

或者它可能會針對數據庫檢查用戶組。

相關文章
相關標籤/搜索