电竞比分网-中国电竞赛事及体育赛事平台

分享

Java EE 8 Security API 入門(mén),第 1 部分: 針對(duì)云和微服務(wù)平臺(tái)的 Java 企業(yè)安全性

 阿青哥Joe 2018-06-30

期盼已久的新 Java EE Security API (JSR 375) 推動(dòng) Java 企業(yè)安全性進(jìn)入了云和微服務(wù)計(jì)算時(shí)代。本系列將展示新安全機(jī)制如何簡(jiǎn)化和標(biāo)準(zhǔn)化各種 Java EE 容器實(shí)現(xiàn)之間的安全處理,然后幫助您開(kāi)始在受云支持的項(xiàng)目中使用它們。

經(jīng)驗(yàn)豐富的 Java? 開(kāi)發(fā)人員都知道,Java 從不缺乏 Java 安全機(jī)制。各種安全機(jī)制選項(xiàng)包括 Java Authorization for Container Contracts 規(guī)范 (JACC)、Java Authentication Service Provider Interface for Containers (JASPIC),以及大量特定于第三方容器的安全 API 和配置管理解決方案。

我們面對(duì)的麻煩不是缺少選項(xiàng),而是缺少一種企業(yè)標(biāo)準(zhǔn)。沒(méi)有標(biāo)準(zhǔn),就無(wú)法激勵(lì)供應(yīng)商一致地實(shí)現(xiàn)身份驗(yàn)證等核心特性,并針對(duì)上下文和依賴(lài)注入 (CDI) 及 Expression Language (EL) 等新技術(shù)來(lái)升級(jí)專(zhuān)用解決方案,或者時(shí)刻跟上云和微服務(wù)架構(gòu)的安全發(fā)展趨勢(shì)。

本系列將介紹新的 Java EE Security API,首先將概述該 API 及其 3 個(gè)主要接口:HttpAuthenticationMechanismIdentityStoreSecurityContext。

獲取代碼

一個(gè)針對(duì) Java EE 安全性的新標(biāo)準(zhǔn)

開(kāi)發(fā) Java EE 安全規(guī)范的運(yùn)動(dòng)源自 2014 年 Java EE 8 調(diào)查中的社區(qū)反饋。簡(jiǎn)化和標(biāo)準(zhǔn)化 Java 企業(yè)安全是許多調(diào)查對(duì)象的優(yōu)先選項(xiàng)。JSR 375 專(zhuān)家小組在組建之后確定了以下問(wèn)題:

  • 組成 Java EE 的各種 EJB 和 servlet 容器定義了類(lèi)似的安全相關(guān) API,但采用了稍微不同的語(yǔ)法。例如,一個(gè)檢查用戶(hù)角色的 servlet 會(huì)調(diào)用 HttpServletRequest.isUserInRole(String role),而一個(gè) EJB 會(huì)調(diào)用 EJBContext.isCallerInRole(String roleName)。
  • 諸如 JACC 之類(lèi)的現(xiàn)有安全機(jī)制很難實(shí)現(xiàn),而且 JASPIC 可能很難正確使用。
  • 現(xiàn)有機(jī)制沒(méi)有充分利用現(xiàn)代 Java EE 編程的特性,比如上下文和依賴(lài)注入 (CDI)。
  • 沒(méi)有一種可在容器間移植的方式來(lái)控制如何在后端執(zhí)行身份驗(yàn)證。
  • 對(duì)于身份存儲(chǔ)的管理或角色和權(quán)限的配置,沒(méi)有標(biāo)準(zhǔn)的支持。
  • 對(duì)于自定義身份驗(yàn)證規(guī)則的部署,也沒(méi)有標(biāo)準(zhǔn)的支持。

這些是 JSR 375 打算解決的主要問(wèn)題。同時(shí),該規(guī)范通過(guò)定義可移植的 API 在容器之間執(zhí)行身份驗(yàn)證、身份存儲(chǔ)、角色和權(quán)限及授權(quán),希望使開(kāi)發(fā)人員能夠自行管理和控制安全性。

Java EE Security API 的美妙之處在于,它提供了一種配置身份存儲(chǔ)和身份驗(yàn)證機(jī)制的備選方法,但沒(méi)有取代現(xiàn)有安全機(jī)制。Java EE Security API 使開(kāi)發(fā)人員能夠以一致、可移植的方式在 Java EE Web 應(yīng)用程序中啟用安全性 — 無(wú)論是否使用特定于供應(yīng)商的或?qū)S玫慕鉀Q方案。

Java EE Security API 中包含的特性

Java EE Security API V1.0 包含原始建議草案的一個(gè)子集,專(zhuān)注于與云原生應(yīng)用程序相關(guān)的技術(shù)。這些特性包括:

  • 一個(gè)用于身份驗(yàn)證的 API
  • 一個(gè)身份存儲(chǔ) API
  • 一個(gè)安全上下文 API

這些特性通過(guò)新的標(biāo)準(zhǔn)化術(shù)語(yǔ)一起引入到所有 Java EE 安全實(shí)現(xiàn)中。Java EE Security 規(guī)范的下一個(gè)版本中即將包含的剩余特性包括:

  • 一個(gè)密碼混淆 API
  • 一個(gè)角色/權(quán)限分配 API
  • 一個(gè)授權(quán)攔截器 API

安全的 Web 身份驗(yàn)證

Java EE 平臺(tái)已為 Web 應(yīng)用程序用戶(hù)的身份驗(yàn)證指定了兩種機(jī)制:Servlet 4.0 (JSR 369) 提供了一種聲明性機(jī)制,適合一般應(yīng)用程序配置。為了滿(mǎn)足執(zhí)行更可靠身份驗(yàn)證的需求,JASPIC 定義了一個(gè)名為 ServerAuthModule 的服務(wù)提供程序接口,該接口支持開(kāi)發(fā)身份驗(yàn)證模塊來(lái)處理任何憑證類(lèi)型。此外,Servlet Container Profile 指定了 JASPIC 應(yīng)如何與 servlet 容器相集成。

這兩種機(jī)制都很有意義很有效,但對(duì) Web 應(yīng)用程序開(kāi)發(fā)人員而言,每種機(jī)制都有其局限性。

servlet 容器機(jī)制被限定為僅支持 Servlet 4.0 定義的小范圍的憑證類(lèi)型,而且它無(wú)法支持與調(diào)用方的復(fù)雜交互。它也無(wú)法讓?xiě)?yīng)用程序確定調(diào)用方是否已針對(duì)預(yù)期身份存儲(chǔ)進(jìn)行了身份驗(yàn)證。

相反,JASPIC 非常強(qiáng)大,可塑性很強(qiáng),但使用起來(lái)也非常復(fù)雜。對(duì) AuthModule 進(jìn)行編碼并針對(duì) Web 容器來(lái)調(diào)整它,以便將它用于身份驗(yàn)證,這可能很復(fù)雜。除此之外,JASPIC 沒(méi)有聲明性配置,沒(méi)有明確的方法來(lái)覆蓋通過(guò)編程方式注冊(cè)的 AuthModule。

Java EE Security API 通過(guò)新接口 HttpAuthenticationMechanism 解決了這些問(wèn)題中的一部分。這個(gè)新接口實(shí)際上是 JASPIC ServerAuthModule 接口的一個(gè)簡(jiǎn)化的 servlet 容器變體,它在減少現(xiàn)有機(jī)制的局限性的同時(shí)充分利用了現(xiàn)有機(jī)制。

HttpAuthenticationMechanism 實(shí)例是一個(gè) CDI bean,由容器負(fù)責(zé)使其可用于注入。應(yīng)用程序或 servlet 容器可以提供 HttpAuthenticationMechanism 接口的更多實(shí)現(xiàn)。請(qǐng)注意,HttpAuthenticationMechanism 僅指定用于 servlet 容器。

對(duì) Servlet 4.0 身份驗(yàn)證的支持

一個(gè) Java EE 容器必須為 Servlet 4.0 規(guī)范中定義的 3 種身份驗(yàn)證機(jī)制提供 HttpAuthenticationMechanism 實(shí)現(xiàn)。這 3 種實(shí)現(xiàn)是:

  • 基本 HTTP 身份驗(yàn)證(13.6.1 小節(jié))
  • 基于表單的身份驗(yàn)證(13.6.3 小節(jié))
  • 自定義表單身份驗(yàn)證(13.6.3.1 小節(jié))

每種實(shí)現(xiàn)都由與其相關(guān)的注解的存在而觸發(fā):

  • @BasicAuthenticationMechanismDefinition
  • @FormAuthenticationMechanismDefinition
  • @CustomFormAuthenticationMechanismDefinition

遇到其中一個(gè)注解時(shí),容器會(huì)實(shí)例化關(guān)聯(lián)機(jī)制的一個(gè)實(shí)例并立即提供該實(shí)例。

在新規(guī)范中,不再需要在 web.xml 文件中的 <login-config> 元素之間指定身份驗(yàn)證機(jī)制,而 Servlet 4.0 需要這么做。實(shí)際上,如果存在這些 web.xml 配置,同時(shí)還存在一個(gè)基于 HttpAuthenticationMechanism 的注解,部署流程可能會(huì)失敗,或者至少會(huì)忽略這些配置。

讓我們看看可以如何使用每種機(jī)制的一些示例。

基本 HTTP 身份驗(yàn)證

@BasicAuthenticationMechanismDefinition 注解觸發(fā) Servlet 4.0 所定義的基本 HTTP 身份驗(yàn)證。清單 1 給出了一個(gè)示例。唯一的配置參數(shù)是可選的,而且允許指定一個(gè)范圍。

清單 1. 基本 HTTP 身份驗(yàn)證
1
2
3
4
5
@BasicAuthenticationMechanismDefinition(realmName="${'user-realm'}")
@WebServlet("/user")
@DeclareRoles({ "admin", "user", "demo" })
@ServletSecurity(@HttpConstraint(rolesAllowed = "user"))
public class UserServlet extends HttpServlet { … }

范圍是什么?
一種服務(wù)器資源可劃分為不同的受保護(hù)空間。在本例中,每個(gè)空間都有自己的身份驗(yàn)證模式和授權(quán)數(shù)據(jù)庫(kù),并包含由相同策略控制的用戶(hù)和組。這個(gè)由用戶(hù)和組構(gòu)成的數(shù)據(jù)庫(kù)就稱(chēng)為一個(gè)范圍

基于表單的身份驗(yàn)證

@FormAuthenticationMechanismDefinition 注解用于基于表單的身份驗(yàn)證。它有一個(gè)必要參數(shù) loginToContinue,該參數(shù)用于配置 Web 應(yīng)用程序的登錄頁(yè)、錯(cuò)誤頁(yè),以及重定向或轉(zhuǎn)發(fā)特征。在清單 2 中,可以看到登錄頁(yè)使用了一個(gè) URI 定義,useForwardToLoginExpression 是使用一個(gè) Expression Language (EL) 表達(dá)式來(lái)配置的。不需要向 @LoginToContinue 注解傳遞任何參數(shù),因?yàn)樵搶?shí)現(xiàn)已提供了合理的默認(rèn)參數(shù)。

清單 2. 基于表單的身份驗(yàn)證
1
2
3
4
5
6
7
8
9
@FormAuthenticationMechanismDefinition(
   loginToContinue = @LoginToContinue(
       loginPage="/login-servlet",
       errorPage="/error",
       useForwardToLoginExpression="${appConfig.forward}"
   )
)
@ApplicationScoped
public class ApplicationConfig { ...}

自定義表單身份驗(yàn)證

@CustomFormAuthenticationMechanismDefinition 注解觸發(fā)內(nèi)置的自定義表單身份驗(yàn)證。清單 3 給出了一個(gè)示例。

清單 3. 自定義表單身份驗(yàn)證
1
2
3
4
5
6
7
8
9
@CustomFormAuthenticationMechanismDefinition(
   loginToContinue = @LoginToContinue(
       loginPage="/login.do"
   )
)
@WebServlet("/admin")
@DeclareRoles({ "admin", "user", "demo" })
@ServletSecurity(@HttpConstraint(rolesAllowed = "admin"))
public class AdminServlet extends HttpServlet { ...}

自定義表單身份驗(yàn)證旨在與 JavaServer Pages (JSF) 和相關(guān)的 Java EE 技術(shù)更加一致。login.do 頁(yè)被呈現(xiàn)出來(lái),然后通過(guò)登錄頁(yè)的支持性 bean 輸入并處理用戶(hù)名和密碼。

IdentityStore API

身份存儲(chǔ)是一個(gè)數(shù)據(jù)庫(kù),用于存儲(chǔ)用戶(hù)身份數(shù)據(jù),比如用戶(hù)名、組成員關(guān)系,以及用于驗(yàn)證憑證的信息。Java EE Security API 提供了一個(gè)名為 IdentityStore 的身份存儲(chǔ)抽象。類(lèi)似于 JAAS LoginModule 接口,IdentityStore 用于與身份存儲(chǔ)交互,以便驗(yàn)證用戶(hù)和檢索組成員關(guān)系。

正如規(guī)范中所寫(xiě),IdentityStore 的意圖是供 HttpAuthenticationMechanism 實(shí)現(xiàn)使用,但這不是必須的。IdentityStore 可以獨(dú)立存在,并被其他任何身份驗(yàn)證機(jī)制使用。但是,通過(guò)結(jié)合使用 IdentityStoreHttpAuthenticationMechanism,應(yīng)用程序能以一種便攜的標(biāo)準(zhǔn)方式來(lái)控制其用于身份驗(yàn)證的身份存儲(chǔ),建議將此方式用于大多數(shù)用例場(chǎng)景。

IdentityStore API 包含一個(gè) IdentityStoreHandler 接口,HttpAuthenticationMechanism 必須委托給該接口才能驗(yàn)證用戶(hù)憑證。然后,IdentityStoreHandler 調(diào)用 IdentityStore 實(shí)例。Identity 存儲(chǔ)實(shí)現(xiàn)不會(huì)被直接使用,而是通過(guò)專(zhuān)用處理函數(shù)來(lái)交互。

IdentityStoreHandler 可以針對(duì)多個(gè) IdentityStore 來(lái)執(zhí)行身份驗(yàn)證,并以 CredentialValidationResult 實(shí)例的形式返回一個(gè)聚合結(jié)果。這個(gè)對(duì)象可以做的事情只是傳遞證書(shū)是否有效,或者它可能是一個(gè)包含以下任何信息的豐富對(duì)象:

  • CallerPrincipal
  • 主體所屬的組的集合
  • 調(diào)用方的名稱(chēng)或 LDAP 可識(shí)別的名稱(chēng)
  • 來(lái)自身份存儲(chǔ)的調(diào)用方唯一標(biāo)識(shí)符

按每個(gè) IdentityStore 實(shí)現(xiàn)的優(yōu)先級(jí)確定的順序來(lái)查詢(xún)身份存儲(chǔ)。存儲(chǔ)列表被解析了兩次:第一次用于身份驗(yàn)證,然后用于授權(quán)。

作為開(kāi)發(fā)人員,您可以通過(guò)實(shí)現(xiàn) IdentityStore 接口來(lái)實(shí)現(xiàn)自己的輕量型身份存儲(chǔ),也可以使用用于 LDAP 和 RDBMS 的內(nèi)置 IdentityStore 之一來(lái)實(shí)現(xiàn)。這些 IdentityStore 通過(guò)向合適的注解(@LdapIdentityStoreDefinition@DataBaseIdentityStoreDefinition)傳遞配置細(xì)節(jié)來(lái)實(shí)現(xiàn)初始化。

配置內(nèi)置 IdentityStore

最簡(jiǎn)單的身份存儲(chǔ)是數(shù)據(jù)庫(kù)存儲(chǔ)。它通過(guò) @DataBaseIdentityStoreDefinition 注解來(lái)配置,如清單 4 所示。兩個(gè)內(nèi)置的數(shù)據(jù)庫(kù)注解基于 Java EE 7 中已提供的 @DataStoreDefinition 注解。

清單 4 展示了如何配置一個(gè)數(shù)據(jù)庫(kù)身份存儲(chǔ)。這些配置選項(xiàng)是一目了然的,如果您配置過(guò)數(shù)據(jù)庫(kù)定義,應(yīng)該很熟悉它們。

清單 4. 配置一個(gè)數(shù)據(jù)庫(kù)身份存儲(chǔ)
1
2
3
4
5
6
7
8
9
10
@DatabaseIdentityStoreDefinition(
   dataSourceLookup = "${'java:global/permissions_db'}",
   callerQuery = "#{'select password from caller where name = ?'}",
   groupsQuery = "select group_name from caller_groups where caller_name = ?",
   hashAlgorithm = PasswordHash.class,
   priority = 10
)
@ApplicationScoped
@Named
public class ApplicationConfig { ...}

請(qǐng)注意,清單 4 中將優(yōu)先級(jí)設(shè)置為 10。此設(shè)置在找到多個(gè)身份存儲(chǔ)時(shí)使用,用于確定相對(duì)于其他存儲(chǔ)的迭代順序。數(shù)字越小,優(yōu)先級(jí)越高。

LDAP 配置很簡(jiǎn)單,如清單 5 所示。如果您擁有使用 LDAP 配置語(yǔ)義的經(jīng)驗(yàn),將會(huì)發(fā)現(xiàn)這里的選項(xiàng)很熟悉。

清單 5. 配置一個(gè) LDAP 身份存儲(chǔ)
1
2
3
4
5
6
7
8
@LdapIdentityStoreDefinition(
   url = "ldap://localhost:33389/",
   callerBaseDn = "ou=caller,dc=jsr375,dc=net",
   groupSearchBase = "ou=group,dc=jsr375,dc=net"
)
@DeclareRoles({ "admin", "user", "demo" })
@WebServlet("/admin")
public class AdminServlet extends HttpServlet { ...}

自定義 IdentityStore

設(shè)計(jì)您自己的輕量型身份存儲(chǔ)非常簡(jiǎn)單。您需要實(shí)現(xiàn) IdentityStore 接口,而且至少需要 validate() 方法。該接口上有 4 個(gè)方法,所有方法都具有默認(rèn)的方法實(shí)現(xiàn)。有效的身份存儲(chǔ)至少需要 validate() 方法。該方法接受一個(gè) Credential 實(shí)例并返回一個(gè) CredentialValidationResults 實(shí)例。

在清單 6 中,validate() 方法接收一個(gè)包含要驗(yàn)證的登錄憑證的 UsernamePasswordCredential 實(shí)例。然后,它返回一個(gè) CredentialValidationResults 實(shí)例。如果簡(jiǎn)單的配置邏輯得到了成功的身份驗(yàn)證,則會(huì)為此對(duì)象配置用戶(hù)名和用戶(hù)所屬的組集合。如果身份驗(yàn)證失敗,那么 CredentialValidationResults 實(shí)例將會(huì)僅包含狀態(tài)標(biāo)志 INVALID。

清單 6. 一個(gè)自定義的輕量型身份存儲(chǔ)
1
2
3
4
5
6
7
8
9
10
@ApplicationScoped
public class LiteWeightIdentityStore implements IdentityStore {
   public CredentialValidationResult validate(UsernamePasswordCredential userCredential) {
       if (userCredential.compareTo("admin", "pwd1")) {
           return new CredentialValidationResult("admin",
               new HashSet<>(asList("admin", "user", "demo")));
       }
       return INVALID_RESULT;
   }
}

請(qǐng)注意,該實(shí)現(xiàn)由 @ApplicationScope 注解。 這是必需的,因?yàn)? IdentityStoreHandler 包含對(duì) CDI 容器所管理的所有 IdentityStore bean 實(shí)例的引用。@ApplicationScope 注解可以確保該實(shí)例是一個(gè) CDI 管理的 bean,可用于整個(gè)應(yīng)用程序。

要使用您的輕量型身份存儲(chǔ),可以將 IdentityStoreHandler 注入到一個(gè)自定義 HttpAuthenticationMechanism 中,如清單 7 所示。

清單 7. 將 LiteWeightIdentityStore 注入到一個(gè)自定義 HttpAuthenticationMechanism 中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@ApplicationScoped
public class LiteAuthenticationMechanism implements HttpAuthenticationMechanism {
   @Inject
   private IdentityStoreHandler idStoreHandler;
   @Override
   public AuthenticationStatus validateRequest(HttpServletRequest req,
                                               HttpServletResponse res,
                                               HttpMessageContext context) {
       CredentialValidationResult result = idStoreHandler.validate(
               new UsernamePasswordCredential(
                       req.getParameter("name"), req.getParameter("password")));
       if (result.getStatus() == VALID) {
           return context.notifyContainerAboutLogin(result);
       } else {
           return context.responseUnauthorized();
       }
   }
}

SecurityContext API

IdentityStoreHttpAuthenticationMechanism 相結(jié)合,提供了非常強(qiáng)大的用戶(hù)身份驗(yàn)證和授權(quán)功能,但聲明性模型本身并不夠。編程性安全使 Web 應(yīng)用程序能執(zhí)行必要的檢查,以授權(quán)或拒絕對(duì)應(yīng)用程序資源的訪問(wèn),SecurityContext API 提供了這一功能。

目前,Java EE 容器采用了不一致的方式來(lái)實(shí)現(xiàn)安全上下文對(duì)象。例如,servlet 容器提供一個(gè) HttpServletRequest 實(shí)例,可以在該實(shí)例上調(diào)用 getUserPrincipal() 方法來(lái)獲取表示用戶(hù)身份的 UserPrincipal。然后,EJB 容器提供一個(gè)具有不同名稱(chēng)的 EJBContext 實(shí)例,在該實(shí)例上調(diào)用同名的方法。類(lèi)似地,如果您想測(cè)試用戶(hù)是否屬于某個(gè)角色,必須在 HttpServletRequest 實(shí)例上調(diào)用 isUserRole() 方法,然后在 EJBContext 實(shí)例上調(diào)用 isCallerInRole()。

安全上下文是什么?
在 Java 企業(yè)應(yīng)用程序中,安全上下文提供與當(dāng)前驗(yàn)證的用戶(hù)有關(guān)聯(lián)的安全相關(guān)信息的訪問(wèn)能力。SecurityContext API 的目的是在所有 servlet 和 EJB 容器中實(shí)現(xiàn)對(duì)應(yīng)用程序的安全上下文的一致訪問(wèn)。

SecurityContext 在所有 Java EE 容器中提供了一種獲取身份驗(yàn)證和授權(quán)信息的一致機(jī)制。新 Java EE Security 規(guī)范要求至少在 servlet 和 EJB 容器中提供 SecurityContext。服務(wù)器供應(yīng)商也可以在其他容器中提供它。

SecurityContext 接口的方法

SecurityContext 接口為編程性安全提供了一個(gè)入口點(diǎn),而且是一種可注入的類(lèi)型。它有 5 個(gè)方法,所有方法都沒(méi)有默認(rèn)實(shí)現(xiàn)。下面列出了這些方法和它們的用途:

  • Principal getCallerPrincipal(); 返回表示當(dāng)前驗(yàn)證的用戶(hù)名的特定于平臺(tái)的主體,或者,如果當(dāng)前調(diào)用方未經(jīng)驗(yàn)證,則返回 null。
  • <T extends Principal> Set<T> getPrincipalsByType(Class<T> pType); 返回來(lái)自經(jīng)過(guò)驗(yàn)證的調(diào)用方的主題中所有給定類(lèi)型的主體;如果既未找到 pType 類(lèi)型,當(dāng)前用戶(hù)也未經(jīng)驗(yàn)證,則返回一個(gè)空集合。
  • boolean isCallerInRole(String role); 確定調(diào)用方是否包含在指定的角色中;如果用戶(hù)未經(jīng)授權(quán),則返回 false。
  • boolean hasAccessToWebResource(String resource, String... methods); 確定調(diào)用方是否有權(quán)通過(guò)所提供的方法訪問(wèn)給定 Web 資源。
  • AuthenticationStatus authenticate(HttpServletRequest req, HttpServletResponse res, AuthenticationParameters param);:告知容器,它應(yīng)該開(kāi)始或繼續(xù)執(zhí)行與調(diào)用方的基于 HTTP 的身份驗(yàn)證對(duì)話(huà)。由于依賴(lài)于 HttpServletRequestHttpServletResponse 實(shí)例,此方法僅適用于 servlet 容器。

最后,我們將快速查看如何使用這些方法之一來(lái)檢查用戶(hù)對(duì) Web 資源的訪問(wèn)。

使用 SecurityContext:一個(gè)示例

清單 8 展示了如何使用 hasAccessToWebResource() 方法來(lái)測(cè)試調(diào)用方使用指定的 HTTP 方法對(duì)給定 Web 資源的訪問(wèn)。在本例中,SecurityContext 實(shí)例被注入到 servlet 中,并用在 doGet() 方法中,后一個(gè)方法中測(cè)試了調(diào)用方對(duì)位于 URI /secretServlet 的 servlet 的 GET 方法的訪問(wèn)。

清單 8. 測(cè)試調(diào)用方對(duì) Web 資源的訪問(wèn)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@DeclareRoles({"admin", "user", "demo"})
@WebServlet("/hasAccessServlet")
public class HasAccessServlet extends HttpServlet {
   
   @Inject
   private SecurityContext securityContext;
   @Override
   public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
       boolean hasAccess = securityContext.hasAccessToWebResource("/secretServlet", "GET");
       if (hasAccess) {
           req.getRequestDispatcher("/secretServlet").forward(req, res);
       } else {
           req.getRequestDispatcher("/logout").forward(req, res);
       }
   }
}

第 1 部分小結(jié)

新 Java EE Security API 成功地結(jié)合使用了現(xiàn)有身份驗(yàn)證和授權(quán)機(jī)制的強(qiáng)大功能,以及開(kāi)發(fā)人員期望從現(xiàn)代 Java EE 特性和技術(shù)獲得的輕松開(kāi)發(fā)能力。

盡管此 API 的原動(dòng)力源自對(duì)以一致、可移植方式來(lái)解決安全相關(guān)問(wèn)題的需求,但許多改進(jìn)即將推出。在未來(lái)的版本中,JSR 375 專(zhuān)家小組打算集成 API 來(lái)實(shí)現(xiàn)密碼混淆、角色和權(quán)限分類(lèi),以及授權(quán)攔截 — 規(guī)范的 v1.0 中未包含的所有特性。

專(zhuān)家小組還希望集成密鑰管理和加密等特性,這些特性對(duì)于云原生和微服務(wù)應(yīng)用程序中的常見(jiàn)用例至關(guān)重要。2016 年的 Java EE 社區(qū)調(diào)查還表明,在希望包含在 Java EE 8 中的特性中,OAuth2 和 OpenID 的重要性排第三。盡管由于時(shí)間限制,v1.0 中無(wú)法包含這些特性,但在即將推出的版本中,將會(huì)提供包含這些特性的充分理由和動(dòng)機(jī)。

您已大致了解了新 Java EE Security API 的基本特性和組件,可以通過(guò)下面的快速測(cè)驗(yàn)測(cè)試一下您學(xué)到的知識(shí)。下一篇文章將深入剖析 HttpAuthenticationMechanism 接口和它的 3 種支持 Servlet 4.0 的身份驗(yàn)證機(jī)制。

測(cè)試您的了解情況

  1. 3 種默認(rèn)的 HttpAuthenticationMechanism 實(shí)現(xiàn)是哪些?
    1. @BasicFormAuthenticationMechanismDefinition
    2. @FormAuthenticationMechanismDefinition
    3. @LoginFormAuthenticationMechanismDefinition
    4. @CustomFormAuthenticationMechanismDefinition
    5. @BasicAuthenticationMechanismDefinition
  2. 以下哪兩個(gè)注解將會(huì)觸發(fā)內(nèi)置的 LDAP 和 RDBMS 身份存儲(chǔ)?
    1. @LdapIdentityStore
    2. @DataBaseIdentityStore
    3. @DataBaseIdentityStoreDefinition
    4. @LdapIdentityStoreDefinition
    5. @RdbmsBaseIdentityStoreDefinition
  3. 以下哪句陳述是正確的?
    1. IdentityStore 只能被 HttpAuthenticationMechanism 的實(shí)現(xiàn)使用。
    2. IdentityStore 能被任何內(nèi)置或定制的安全選項(xiàng)使用。
    3. IdentityStore 只能通過(guò)注入的 IdentityStoreHandler 實(shí)現(xiàn)進(jìn)行訪問(wèn)。
    4. IdentityStore 不能被 HttpAuthenticationMechanism 的實(shí)現(xiàn)使用。
  4. SecurityContext 的目標(biāo)是什么?
    1. 在 servlet 和 EJB 容器之間提供對(duì)安全上下文的一致訪問(wèn)。
    2. 僅向 EJB 容器提供對(duì)安全上下文的一致訪問(wèn)。
    3. 在所有容器之間提供對(duì)安全上下文的一致訪問(wèn)。
    4. 向 servlet 容器提供對(duì)安全上下文的一致訪問(wèn)。
    5. 在 EJB 容器之間提供對(duì)安全上下文的一致訪問(wèn)。
  5. 為什么 HttpAuthenticationMechanism 實(shí)現(xiàn)必須是 @ApplicationScoped?
    1. 為了確保它是一個(gè) CDI 管理的 bean,而且可用于整個(gè)應(yīng)用程序。
    2. 以便 HttpAuthenticationMechanism 能在所有應(yīng)用程序級(jí)別上使用。
    3. 以便每個(gè)用戶(hù)有一個(gè)對(duì)應(yīng)的 HttpAuthenticationMechanism 實(shí)例。
    4. JsonAdapter。 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多