(window.webpackJsonp=window.webpackJsonp||[]).push([[263],{689:function(t,e,r){"use strict";r.r(e);var a=r(56),n=Object(a.a)({},(function(){var t=this,e=t.$createElement,r=t._self._c||e;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h1",{attrs:{id:"kotlin-configuration"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#kotlin-configuration"}},[t._v("#")]),t._v(" Kotlin Configuration")]),t._v(" "),r("table",[r("thead",[r("tr",[r("th"),t._v(" "),r("th",[t._v("Spring Security provides "),r("a",{attrs:{href:"https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/kotlin/hello-security",target:"_blank",rel:"noopener noreferrer"}},[t._v("a sample application"),r("OutboundLink")],1),t._v(" which demonstrates the use of Spring Security Kotlin Configuration.")])])]),t._v(" "),r("tbody")]),t._v(" "),r("h2",{attrs:{id:"httpsecurity"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#httpsecurity"}},[t._v("#")]),t._v(" HttpSecurity")]),t._v(" "),r("p",[t._v("How does Spring Security know that we want to require all users to be authenticated?\nHow does Spring Security know we want to support form based authentication?\nThere is a configuration class that is being invoked behind the scenes called "),r("code",[t._v("WebSecurityConfigurerAdapter")]),t._v(".\nIt has a method called "),r("code",[t._v("configure")]),t._v(" with the following default implementation:")]),t._v(" "),r("div",{staticClass:"language- extra-class"},[r("pre",{pre:!0,attrs:{class:"language-text"}},[r("code",[t._v("fun configure(http: HttpSecurity) {\n http {\n authorizeRequests {\n authorize(anyRequest, authenticated)\n }\n formLogin { }\n httpBasic { }\n }\n}\n")])])]),r("p",[t._v("The default configuration above:")]),t._v(" "),r("ul",[r("li",[r("p",[t._v("Ensures that any request to our application requires the user to be authenticated")])]),t._v(" "),r("li",[r("p",[t._v("Allows users to authenticate with form based login")])]),t._v(" "),r("li",[r("p",[t._v("Allows users to authenticate with HTTP Basic authentication")])])]),t._v(" "),r("p",[t._v("You will notice that this configuration is quite similar the XML Namespace configuration:")]),t._v(" "),r("div",{staticClass:"language- extra-class"},[r("pre",{pre:!0,attrs:{class:"language-text"}},[r("code",[t._v('\n\t\n\t\n\t\n\n')])])]),r("h2",{attrs:{id:"multiple-httpsecurity"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#multiple-httpsecurity"}},[t._v("#")]),t._v(" Multiple HttpSecurity")]),t._v(" "),r("p",[t._v("We can configure multiple HttpSecurity instances just as we can have multiple "),r("code",[t._v("")]),t._v(" blocks.\nThe key is to extend the "),r("code",[t._v("WebSecurityConfigurerAdapter")]),t._v(" multiple times.\nFor example, the following is an example of having a different configuration for URL’s that start with "),r("code",[t._v("/api/")]),t._v(".")]),t._v(" "),r("div",{staticClass:"language- extra-class"},[r("pre",{pre:!0,attrs:{class:"language-text"}},[r("code",[t._v('@EnableWebSecurity\nclass MultiHttpSecurityConfig {\n @Bean (1)\n public fun userDetailsService(): UserDetailsService {\n val users: User.UserBuilder = User.withDefaultPasswordEncoder()\n val manager = InMemoryUserDetailsManager()\n manager.createUser(users.username("user").password("password").roles("USER").build())\n manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build())\n return manager\n }\n\n @Configuration\n @Order(1) (2)\n class ApiWebSecurityConfigurationAdapter: WebSecurityConfigurerAdapter() {\n override fun configure(http: HttpSecurity) {\n http {\n securityMatcher("/api/**") (3)\n authorizeRequests {\n authorize(anyRequest, hasRole("ADMIN"))\n }\n httpBasic { }\n }\n }\n }\n\n @Configuration (4)\n class FormLoginWebSecurityConfigurerAdapter: WebSecurityConfigurerAdapter() {\n override fun configure(http: HttpSecurity) {\n http {\n authorizeRequests {\n authorize(anyRequest, authenticated)\n }\n formLogin { }\n }\n }\n }\n}\n')])])]),r("table",[r("thead",[r("tr",[r("th",[r("strong",[t._v("1")])]),t._v(" "),r("th",[t._v("Configure Authentication as normal")])])]),t._v(" "),r("tbody",[r("tr",[r("td",[r("strong",[t._v("2")])]),t._v(" "),r("td",[t._v("Create an instance of "),r("code",[t._v("WebSecurityConfigurerAdapter")]),t._v(" that contains "),r("code",[t._v("@Order")]),t._v(" to specify which "),r("code",[t._v("WebSecurityConfigurerAdapter")]),t._v(" should be considered first.")])]),t._v(" "),r("tr",[r("td",[r("strong",[t._v("3")])]),t._v(" "),r("td",[t._v("The "),r("code",[t._v("http.antMatcher")]),t._v(" states that this "),r("code",[t._v("HttpSecurity")]),t._v(" will only be applicable to URLs that start with "),r("code",[t._v("/api/")])])]),t._v(" "),r("tr",[r("td",[r("strong",[t._v("4")])]),t._v(" "),r("td",[t._v("Create another instance of "),r("code",[t._v("WebSecurityConfigurerAdapter")]),t._v("."),r("br"),t._v("If the URL does not start with "),r("code",[t._v("/api/")]),t._v(" this configuration will be used."),r("br"),t._v("This configuration is considered after "),r("code",[t._v("ApiWebSecurityConfigurationAdapter")]),t._v(" since it has an "),r("code",[t._v("@Order")]),t._v(" value after "),r("code",[t._v("1")]),t._v(" (no "),r("code",[t._v("@Order")]),t._v(" defaults to last).")])])])]),t._v(" "),r("p",[r("RouterLink",{attrs:{to:"/en/spring-security/java.html"}},[t._v("Java Configuration")]),r("RouterLink",{attrs:{to:"/en/spring-security/xml-namespace.html"}},[t._v("Namespace Configuration")])],1)])}),[],!1,null,null,null);e.default=n.exports}}]);