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提供如下開箱即用的驗證器:
支持基自己份驗證(http://tools.ietf.org/html/rfc2617)
默認狀況下,BasicAuthenticator不支持會話建立。 這能夠在建立驗證器時重寫,以下所示
new BasicAuthenticator(new TestLookup(), sessionCreationAllowed: true)
用於專用登陸路由的Authenticator。 默認狀況下,假定基於表單的POST使用名爲username和password的表單字段,例如。
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開頭的全部路由都須要有效的會話。
認證人員名單預計會隨着時間的推移而增加。
此外,您能夠輕鬆建立本身的自定義身份驗證器。
Shelf Auth提供如下開箱即用的SessionHandler:
這使用JWT建立在響應的Authorization標頭中返回的身份驗證令牌。後續請求必須在Authorization標頭中傳回令牌。這是一種承載風格的令牌機制。注意:與HTTP消息中傳遞的全部安全憑證同樣,若是有人可以攔截請求或響應,則他們能夠竊取令牌並模擬用戶。確保使用HTTPS。
特徵
其餘會話處理程序(如基於cookie的機制)可能會在將來添加
爲了簡化建立身份驗證中間件的過程,特別是在使用捆綁的身份驗證器和會話處理程序時,會提供構建器。例如
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)拒絕訪問,則:
Shelf Auth提供如下受權商:
僅容許訪問通過身份驗證的用戶。 若是請求中沒有當前的AuthenticatedContext,則拒絕訪問。
經過拒絕訪問引用不是來自與請求URL相同的主機的請求來幫助防止XSRF攻擊。
容許訪問做爲給定PrincipalWhiteList一部分的任何主體的受權者。
PrincipalWhiteList能夠以多種方式實現。 例如,它根據名稱中的靜態內存列表檢查主體名稱。
final whitelist = [ 'fredlintstone@stone.age' ]; final whitelistAuthoriser = new PrincipalWhitelistAuthoriser( (Principal p) => whitelist.contains(p.name));
或者它可能會針對數據庫檢查用戶組。