(window.webpackJsonp=window.webpackJsonp||[]).push([[232],{658:function(t,e,a){"use strict";a.r(e);var n=a(56),i=Object(n.a)({},(function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"java-authentication-and-authorization-service-jaas-provider"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#java-authentication-and-authorization-service-jaas-provider"}},[t._v("#")]),t._v(" Java Authentication and Authorization Service (JAAS) Provider")]),t._v(" "),a("h2",{attrs:{id:"overview"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#overview"}},[t._v("#")]),t._v(" Overview")]),t._v(" "),a("p",[t._v("Spring Security provides a package able to delegate authentication requests to the Java Authentication and Authorization Service (JAAS).\nThis package is discussed in detail below.")]),t._v(" "),a("h2",{attrs:{id:"abstractjaasauthenticationprovider"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#abstractjaasauthenticationprovider"}},[t._v("#")]),t._v(" AbstractJaasAuthenticationProvider")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("AbstractJaasAuthenticationProvider")]),t._v(" is the basis for the provided JAAS "),a("code",[t._v("AuthenticationProvider")]),t._v(" implementations.\nSubclasses must implement a method that creates the "),a("code",[t._v("LoginContext")]),t._v(".\nThe "),a("code",[t._v("AbstractJaasAuthenticationProvider")]),t._v(" has a number of dependencies that can be injected into it that are discussed below.")]),t._v(" "),a("h3",{attrs:{id:"jaas-callbackhandler"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#jaas-callbackhandler"}},[t._v("#")]),t._v(" JAAS CallbackHandler")]),t._v(" "),a("p",[t._v("Most JAAS "),a("code",[t._v("LoginModule")]),t._v("s require a callback of some sort.\nThese callbacks are usually used to obtain the username and password from the user.")]),t._v(" "),a("p",[t._v("In a Spring Security deployment, Spring Security is responsible for this user interaction (via the authentication mechanism).\nThus, by the time the authentication request is delegated through to JAAS, Spring Security’s authentication mechanism will already have fully-populated an "),a("code",[t._v("Authentication")]),t._v(" object containing all the information required by the JAAS "),a("code",[t._v("LoginModule")]),t._v(".")]),t._v(" "),a("p",[t._v("Therefore, the JAAS package for Spring Security provides two default callback handlers, "),a("code",[t._v("JaasNameCallbackHandler")]),t._v(" and "),a("code",[t._v("JaasPasswordCallbackHandler")]),t._v(".\nEach of these callback handlers implement "),a("code",[t._v("JaasAuthenticationCallbackHandler")]),t._v(".\nIn most cases these callback handlers can simply be used without understanding the internal mechanics.")]),t._v(" "),a("p",[t._v("For those needing full control over the callback behavior, internally "),a("code",[t._v("AbstractJaasAuthenticationProvider")]),t._v(" wraps these "),a("code",[t._v("JaasAuthenticationCallbackHandler")]),t._v("s with an "),a("code",[t._v("InternalCallbackHandler")]),t._v(".\nThe "),a("code",[t._v("InternalCallbackHandler")]),t._v(" is the class that actually implements JAAS normal "),a("code",[t._v("CallbackHandler")]),t._v(" interface.\nAny time that the JAAS "),a("code",[t._v("LoginModule")]),t._v(" is used, it is passed a list of application context configured "),a("code",[t._v("InternalCallbackHandler")]),t._v("s.\nIf the "),a("code",[t._v("LoginModule")]),t._v(" requests a callback against the "),a("code",[t._v("InternalCallbackHandler")]),t._v("s, the callback is in-turn passed to the "),a("code",[t._v("JaasAuthenticationCallbackHandler")]),t._v("s being wrapped.")]),t._v(" "),a("h3",{attrs:{id:"jaas-authoritygranter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#jaas-authoritygranter"}},[t._v("#")]),t._v(" JAAS AuthorityGranter")]),t._v(" "),a("p",[t._v('JAAS works with principals.\nEven "roles" are represented as principals in JAAS.\nSpring Security, on the other hand, works with '),a("code",[t._v("Authentication")]),t._v(" objects.\nEach "),a("code",[t._v("Authentication")]),t._v(" object contains a single principal, and multiple "),a("code",[t._v("GrantedAuthority")]),t._v("s.\nTo facilitate mapping between these different concepts, Spring Security’s JAAS package includes an "),a("code",[t._v("AuthorityGranter")]),t._v(" interface.")]),t._v(" "),a("p",[t._v("An "),a("code",[t._v("AuthorityGranter")]),t._v(" is responsible for inspecting a JAAS principal and returning a set of "),a("code",[t._v("String")]),t._v("s, representing the authorities assigned to the principal.\nFor each returned authority string, the "),a("code",[t._v("AbstractJaasAuthenticationProvider")]),t._v(" creates a "),a("code",[t._v("JaasGrantedAuthority")]),t._v(" (which implements Spring Security’s "),a("code",[t._v("GrantedAuthority")]),t._v(" interface) containing the authority string and the JAAS principal that the "),a("code",[t._v("AuthorityGranter")]),t._v(" was passed.\nThe "),a("code",[t._v("AbstractJaasAuthenticationProvider")]),t._v(" obtains the JAAS principals by firstly successfully authenticating the user’s credentials using the JAAS "),a("code",[t._v("LoginModule")]),t._v(", and then accessing the "),a("code",[t._v("LoginContext")]),t._v(" it returns.\nA call to "),a("code",[t._v("LoginContext.getSubject().getPrincipals()")]),t._v(" is made, with each resulting principal passed to each "),a("code",[t._v("AuthorityGranter")]),t._v(" defined against the "),a("code",[t._v("AbstractJaasAuthenticationProvider.setAuthorityGranters(List)")]),t._v(" property.")]),t._v(" "),a("p",[t._v("Spring Security does not include any production "),a("code",[t._v("AuthorityGranter")]),t._v("s given that every JAAS principal has an implementation-specific meaning.\nHowever, there is a "),a("code",[t._v("TestAuthorityGranter")]),t._v(" in the unit tests that demonstrates a simple "),a("code",[t._v("AuthorityGranter")]),t._v(" implementation.")]),t._v(" "),a("h2",{attrs:{id:"defaultjaasauthenticationprovider"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#defaultjaasauthenticationprovider"}},[t._v("#")]),t._v(" DefaultJaasAuthenticationProvider")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v(" allows a JAAS "),a("code",[t._v("Configuration")]),t._v(" object to be injected into it as a dependency.\nIt then creates a "),a("code",[t._v("LoginContext")]),t._v(" using the injected JAAS "),a("code",[t._v("Configuration")]),t._v(".\nThis means that "),a("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v(" is not bound any particular implementation of "),a("code",[t._v("Configuration")]),t._v(" as "),a("code",[t._v("JaasAuthenticationProvider")]),t._v(" is.")]),t._v(" "),a("h3",{attrs:{id:"inmemoryconfiguration"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#inmemoryconfiguration"}},[t._v("#")]),t._v(" InMemoryConfiguration")]),t._v(" "),a("p",[t._v("In order to make it easy to inject a "),a("code",[t._v("Configuration")]),t._v(" into "),a("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v(", a default in-memory implementation named "),a("code",[t._v("InMemoryConfiguration")]),t._v(" is provided.\nThe implementation constructor accepts a "),a("code",[t._v("Map")]),t._v(" where each key represents a login configuration name and the value represents an "),a("code",[t._v("Array")]),t._v(" of "),a("code",[t._v("AppConfigurationEntry")]),t._v("s."),a("code",[t._v("InMemoryConfiguration")]),t._v(" also supports a default "),a("code",[t._v("Array")]),t._v(" of "),a("code",[t._v("AppConfigurationEntry")]),t._v(" objects that will be used if no mapping is found within the provided "),a("code",[t._v("Map")]),t._v(".\nFor details, refer to the class level javadoc of "),a("code",[t._v("InMemoryConfiguration")]),t._v(".")]),t._v(" "),a("h3",{attrs:{id:"defaultjaasauthenticationprovider-example-configuration"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#defaultjaasauthenticationprovider-example-configuration"}},[t._v("#")]),t._v(" DefaultJaasAuthenticationProvider Example Configuration")]),t._v(" "),a("p",[t._v("While the Spring configuration for "),a("code",[t._v("InMemoryConfiguration")]),t._v(" can be more verbose than the standard JAAS configuration files, using it in conjunction with "),a("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v(" is more flexible than "),a("code",[t._v("JaasAuthenticationProvider")]),t._v(" since it not dependant on the default "),a("code",[t._v("Configuration")]),t._v(" implementation.")]),t._v(" "),a("p",[t._v("An example configuration of "),a("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v(" using "),a("code",[t._v("InMemoryConfiguration")]),t._v(" is provided below.\nNote that custom implementations of "),a("code",[t._v("Configuration")]),t._v(" can easily be injected into "),a("code",[t._v("DefaultJaasAuthenticationProvider")]),t._v(" as well.")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("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')])])]),a("h2",{attrs:{id:"jaasauthenticationprovider"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#jaasauthenticationprovider"}},[t._v("#")]),t._v(" JaasAuthenticationProvider")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("JaasAuthenticationProvider")]),t._v(" assumes the default "),a("code",[t._v("Configuration")]),t._v(" is an instance of "),a("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(" ConfigFile"),a("OutboundLink")],1),t._v(".\nThis assumption is made in order to attempt to update the "),a("code",[t._v("Configuration")]),t._v(".\nThe "),a("code",[t._v("JaasAuthenticationProvider")]),t._v(" then uses the default "),a("code",[t._v("Configuration")]),t._v(" to create the "),a("code",[t._v("LoginContext")]),t._v(".")]),t._v(" "),a("p",[t._v("Let’s assume we have a JAAS login configuration file, "),a("code",[t._v("/WEB-INF/login.conf")]),t._v(", with the following contents:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("JAASTest {\n\tsample.SampleLoginModule required;\n};\n")])])]),a("p",[t._v("Like all Spring Security beans, the "),a("code",[t._v("JaasAuthenticationProvider")]),t._v(" is configured via the application context.\nThe following definitions would correspond to the above JAAS login configuration file:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('\n\n\n\n\n\n\n\n\n\n\t\n\t\n\t\n\n\n')])])]),a("h2",{attrs:{id:"running-as-a-subject"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#running-as-a-subject"}},[t._v("#")]),t._v(" Running as a Subject")]),t._v(" "),a("p",[t._v("If configured, the "),a("code",[t._v("JaasApiIntegrationFilter")]),t._v(" will attempt to run as the "),a("code",[t._v("Subject")]),t._v(" on the "),a("code",[t._v("JaasAuthenticationToken")]),t._v(".\nThis means that the "),a("code",[t._v("Subject")]),t._v(" can be accessed using:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("Subject subject = Subject.getSubject(AccessController.getContext());\n")])])]),a("p",[t._v("This integration can easily be configured using the "),a("RouterLink",{attrs:{to:"/en/appendix/namespace/http.html#nsa-http-jaas-api-provision"}},[t._v("jaas-api-provision")]),t._v(" attribute.\nThis feature is useful when integrating with legacy or external API’s that rely on the JAAS Subject being populated.")],1),t._v(" "),a("p",[a("RouterLink",{attrs:{to:"/en/spring-security/preauth.html"}},[t._v("Pre-Authentication")]),a("RouterLink",{attrs:{to:"/en/spring-security/cas.html"}},[t._v("CAS")])],1)])}),[],!1,null,null,null);e.default=i.exports}}]);