(window.webpackJsonp=window.webpackJsonp||[]).push([[583],{1013:function(t,a,e){"use strict";e.r(a);var r=e(56),n=Object(r.a)({},(function(){var t=this,a=t.$createElement,e=t._self._c||a;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"java-身份验证和授权服务提供者"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#java-身份验证和授权服务提供者"}},[t._v("#")]),t._v(" Java 身份验证和授权服务提供者")]),t._v(" "),e("h2",{attrs:{id:"概述"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),e("p",[t._v("Spring 安全性提供了一种包,能够将身份验证请求委托给 Java 身份验证和授权服务。下面将详细讨论这个包。")]),t._v(" "),e("h2",{attrs:{id:"抽象-jaasauthenticationprovider"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#抽象-jaasauthenticationprovider"}},[t._v("#")]),t._v(" 抽象 JaasAuthenticationProvider")]),t._v(" "),e("p",[e("code",[t._v("AbstractJaasAuthenticationProvider")]),t._v("是所提供的 JAAS"),e("code",[t._v("AuthenticationProvider")]),t._v("实现的基础。子类必须实现创建"),e("code",[t._v("LoginContext")]),t._v("的方法。"),e("code",[t._v("AbstractJaasAuthenticationProvider")]),t._v("具有许多可以注入其中的依赖项,这些依赖项将在下面讨论。")]),t._v(" "),e("h3",{attrs:{id:"jaas-callbackhandler"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#jaas-callbackhandler"}},[t._v("#")]),t._v(" JAAS CallbackHandler")]),t._v(" "),e("p",[t._v("大多数 JAAS"),e("code",[t._v("LoginModule")]),t._v("s 都需要某种类型的回调。这些回调通常用于从用户获得用户名和密码。")]),t._v(" "),e("p",[t._v("在 Spring 安全性部署中, Spring 安全性负责此用户交互(通过身份验证机制)。因此,在将身份验证请求委托给 JAAS 时, Spring Security 的身份验证机制将已经完全填充了一个"),e("code",[t._v("Authentication")]),t._v("对象,该对象包含 JAAS"),e("code",[t._v("LoginModule")]),t._v("所需的所有信息。")]),t._v(" "),e("p",[t._v("因此, Spring Security 的 JAAS 包提供了两个默认的回调处理程序,"),e("code",[t._v("JaasNameCallbackHandler")]),t._v("和"),e("code",[t._v("JaasPasswordCallbackHandler")]),t._v("。这些回调处理程序中的每一个都实现"),e("code",[t._v("JaasAuthenticationCallbackHandler")]),t._v("。在大多数情况下,这些回调处理程序可以在不了解内部机制的情况下简单地使用。")]),t._v(" "),e("p",[t._v("对于那些需要完全控制回调行为的人,内部"),e("code",[t._v("AbstractJaasAuthenticationProvider")]),t._v("将这些"),e("code",[t._v("JaasAuthenticationCallbackHandler")]),t._v("s 包装成"),e("code",[t._v("InternalCallbackHandler")]),t._v("。"),e("code",[t._v("InternalCallbackHandler")]),t._v("是实际实现 JAASNormal"),e("code",[t._v("CallbackHandler")]),t._v("接口的类。每当使用 JAAS"),e("code",[t._v("LoginModule")]),t._v("时,都会传递一个配置"),e("code",[t._v("InternalCallbackHandler")]),t._v("s 的应用程序上下文列表。如果"),e("code",[t._v("LoginModule")]),t._v("对"),e("code",[t._v("InternalCallbackHandler")]),t._v("s 请求回调,则回调依次传递给正在打包的"),e("code",[t._v("JaasAuthenticationCallbackHandler")]),t._v("s。")]),t._v(" "),e("h3",{attrs:{id:"jaas-authoritygranter"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#jaas-authoritygranter"}},[t._v("#")]),t._v(" Jaas AuthorityGranter")]),t._v(" "),e("p",[t._v("JAAS 与校长一起工作。在 JAAS 中,甚至连“角色”也被表示为主体。 Spring 另一方面,安全性适用于"),e("code",[t._v("Authentication")]),t._v("对象。每个"),e("code",[t._v("Authentication")]),t._v("对象包含一个主体,以及多个"),e("code",[t._v("GrantedAuthority")]),t._v("s。为了便于在这些不同概念之间进行映射, Spring Security 的 JAAS 包包括一个"),e("code",[t._v("AuthorityGranter")]),t._v("接口。")]),t._v(" "),e("p",[t._v("一个"),e("code",[t._v("AuthorityGranter")]),t._v("负责检查一个 JAAS 主体,并返回一组"),e("code",[t._v("String")]),t._v("s,代表分配给主体的权限。对于每个返回的权限字符串,"),e("code",[t._v("AbstractJaasAuthenticationProvider")]),t._v("创建一个"),e("code",[t._v("JaasGrantedAuthority")]),t._v("(它实现 Spring Security 的"),e("code",[t._v("GrantedAuthority")]),t._v("接口),其中包含权限字符串和传递"),e("code",[t._v("AuthorityGranter")]),t._v("的 JAAS 主体。"),e("code",[t._v("AbstractJaasAuthenticationProvider")]),t._v("首先通过使用 JAAS"),e("code",[t._v("LoginModule")]),t._v("成功验证用户的凭据来获得 JAAS 主体,然后访问它返回的"),e("code",[t._v("LoginContext")]),t._v("。对"),e("code",[t._v("LoginContext.getSubject().getPrincipals()")]),t._v("进行了调用,将每个生成的主体传递给根据"),e("code",[t._v("AbstractJaasAuthenticationProvider.setAuthorityGranters(List)")]),t._v("属性定义的每个"),e("code",[t._v("AuthorityGranter")]),t._v("。")]),t._v(" "),e("p",[t._v("Spring 考虑到每个 JAAS 主体都具有特定于实现的含义,安全性不包括任何"),e("code",[t._v("AuthorityGranter")]),t._v("s 的产品。然而,在单元测试中有一个"),e("code",[t._v("TestAuthorityGranter")]),t._v("演示了一个简单的"),e("code",[t._v("AuthorityGranter")]),t._v("实现。")]),t._v(" "),e("h2",{attrs:{id:"defaultjaasauthenticationprovider"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#defaultjaasauthenticationprovider"}},[t._v("#")]),t._v(" DefaultJaasAuthenticationProvider")]),t._v(" "),e("p",[e("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v("允许将 JAAS"),e("code",[t._v("Configuration")]),t._v("对象作为依赖项注入其中。然后,它使用注入的 JAAS创建。这意味着"),e("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v("不绑定"),e("code",[t._v("Configuration")]),t._v("作为"),e("code",[t._v("JaasAuthenticationProvider")]),t._v("的任何特定实现。")]),t._v(" "),e("h3",{attrs:{id:"记忆组态"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#记忆组态"}},[t._v("#")]),t._v(" 记忆组态")]),t._v(" "),e("p",[t._v("为了方便地将"),e("code",[t._v("Configuration")]),t._v("注入"),e("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v(",提供了一个名为"),e("code",[t._v("InMemoryConfiguration")]),t._v("的默认内存中实现。实现构造函数接受一个"),e("code",[t._v("Map")]),t._v(",其中每个键表示一个登录配置名,该值表示"),e("code",[t._v("Array")]),t._v("的"),e("code",[t._v("AppConfigurationEntry")]),t._v("s。"),e("code",[t._v("InMemoryConfiguration")]),t._v("还支持一个"),e("code",[t._v("Array")]),t._v("的缺省"),e("code",[t._v("Array")]),t._v("的"),e("code",[t._v("AppConfigurationEntry")]),t._v("对象,如果在提供的"),e("code",[t._v("Map")]),t._v("中找不到映射,则将使用该对象。有关详细信息,请参阅"),e("code",[t._v("InMemoryConfiguration")]),t._v("的类级别 Javadoc。")]),t._v(" "),e("h3",{attrs:{id:"defaultjaasauthenticationprovider-示例配置"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#defaultjaasauthenticationprovider-示例配置"}},[t._v("#")]),t._v(" DefaultJaasAuthenticationProvider 示例配置")]),t._v(" "),e("p",[t._v("虽然"),e("code",[t._v("InMemoryConfiguration")]),t._v("的 Spring 配置可以比标准的 JAAS 配置文件更详细,但与"),e("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v("一起使用它比"),e("code",[t._v("JaasAuthenticationProvider")]),t._v("更灵活,因为它不依赖于默认的"),e("code",[t._v("Configuration")]),t._v("实现。")]),t._v(" "),e("p",[t._v("下面提供了使用"),e("code",[t._v("InMemoryConfiguration")]),t._v("的"),e("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v("的配置示例。请注意,"),e("code",[t._v("Configuration")]),t._v("的自定义实现也可以很容易地注入到"),e("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v("中。")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('\n\n\n\n\t\n\t\x3c!--\n\tSPRINGSECURITY is the default loginContextName\n\tfor AbstractJaasAuthenticationProvider\n\t--\x3e\n\t\n\t\n\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\n\t\n\t\n\t\n\n\n\n\n\t\x3c!-- You will need to write your own implementation of AuthorityGranter --\x3e\n\t\n\n\n\n')])])]),e("h2",{attrs:{id:"jaasauthenticationprovider"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#jaasauthenticationprovider"}},[t._v("#")]),t._v(" JaasAuthenticationProvider")]),t._v(" "),e("p",[e("code",[t._v("JaasAuthenticationProvider")]),t._v("假设默认的"),e("code",[t._v("Configuration")]),t._v("是"),e("a",{attrs:{href:"https://docs.oracle.com/javase/8/docs/jre/api/security/jaas/spec/com/sun/security/auth/login/ConfigFile.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("配置文件"),e("OutboundLink")],1),t._v("的实例。这个假设是为了尝试更新"),e("code",[t._v("Configuration")]),t._v("。然后"),e("code",[t._v("JaasAuthenticationProvider")]),t._v("使用默认的"),e("code",[t._v("Configuration")]),t._v("来创建"),e("code",[t._v("LoginContext")]),t._v("。")]),t._v(" "),e("p",[t._v("假设我们有一个 JAAS 登录配置文件"),e("code",[t._v("/WEB-INF/login.conf")]),t._v(",其内容如下:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("JAASTest {\n\tsample.SampleLoginModule required;\n};\n")])])]),e("p",[t._v("与所有 Spring 安全 bean 一样,"),e("code",[t._v("JaasAuthenticationProvider")]),t._v("也是通过应用程序上下文配置的。以下定义对应于上面的 JAAS 登录配置文件:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('\n\n\n\n\n\n\n\n\n\n\t\n\t\n\t\n\n\n')])])]),e("h2",{attrs:{id:"以跑步为主题"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#以跑步为主题"}},[t._v("#")]),t._v(" 以跑步为主题")]),t._v(" "),e("p",[t._v("如果进行了配置,"),e("code",[t._v("JaasApiIntegrationFilter")]),t._v("将尝试在"),e("code",[t._v("JaasAuthenticationToken")]),t._v("上以"),e("code",[t._v("Subject")]),t._v("的形式运行。这意味着"),e("code",[t._v("Subject")]),t._v("可以通过以下方式访问:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Subject subject = Subject.getSubject(AccessController.getContext());\n")])])]),e("p",[t._v("可以使用"),e("RouterLink",{attrs:{to:"/appendix/namespace/http.html#nsa-http-jaas-api-provision"}},[t._v("JAAS-API-供应")]),t._v("属性轻松配置此集成。当与依赖于填充的 JAAS 主题的遗留或外部 API 集成时,此功能非常有用。")],1),t._v(" "),e("p",[e("RouterLink",{attrs:{to:"/spring-security/preauth.html"}},[t._v("预先认证")]),e("RouterLink",{attrs:{to:"/spring-security/cas.html"}},[t._v("CAS")])],1)])}),[],!1,null,null,null);a.default=n.exports}}]);