2
0

config.adoc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  1. = Configuration Migrations
  2. The following steps relate to changes around how to configure `HttpSecurity`, `WebSecurity`, and `AuthenticationManager`.
  3. [[add-configuration-annotation]]
  4. == Add `@Configuration` annotation
  5. In 6.0, `@Configuration` is removed from `@EnableWebSecurity`, `@EnableMethodSecurity`, `@EnableGlobalMethodSecurity`, and `@EnableGlobalAuthentication`.
  6. To prepare for this, wherever you are using one of these annotations, you may need to add `@Configuration`.
  7. For example, `@EnableMethodSecurity` changes from:
  8. ====
  9. .Java
  10. [source,java,role="primary"]
  11. ----
  12. @EnableMethodSecurity
  13. public class MyConfiguration {
  14. // ...
  15. }
  16. ----
  17. .Kotlin
  18. [source,java,role="primary"]
  19. ----
  20. @EnableMethodSecurity
  21. open class MyConfiguration {
  22. // ...
  23. }
  24. ----
  25. ====
  26. to:
  27. ====
  28. .Java
  29. [source,java,role="primary"]
  30. ----
  31. @Configuration
  32. @EnableMethodSecurity
  33. public class MyConfiguration {
  34. // ...
  35. }
  36. ----
  37. .Kotlin
  38. [source,java,role="primary"]
  39. ----
  40. @Configuration
  41. @EnableMethodSecurity
  42. open class MyConfiguration {
  43. // ...
  44. }
  45. ----
  46. ====
  47. [[use-new-requestmatchers]]
  48. == Use the new `requestMatchers` methods
  49. In Spring Security 5.8, the {security-api-url}org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistry.html#antMatchers(java.lang.String...)[`antMatchers`], {security-api-url}org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistry.html#mvcMatchers(java.lang.String...)[`mvcMatchers`], and {security-api-url}org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistry.html#regexMatchers(java.lang.String...)[`regexMatchers`] methods were deprecated in favor of new xref:servlet/authorization/authorize-http-requests.adoc#_request_matchers[`requestMatchers` methods].
  50. The new `requestMatchers` methods were added xref:servlet/authorization/authorize-http-requests.adoc[to `authorizeHttpRequests`], `authorizeRequests`, CSRF configuration, `WebSecurityCustomizer` and any other places that had the specialized `RequestMatcher` methods.
  51. The deprecated methods are removed in Spring Security 6.
  52. These new methods have more secure defaults since they choose the most appropriate `RequestMatcher` implementation for your application.
  53. In summary, the new methods choose the `MvcRequestMatcher` implementation if your application has Spring MVC in the classpath, falling back to the `AntPathRequestMatcher` implementation if Spring MVC is not present (aligning the behavior with the Kotlin equivalent methods).
  54. To start using the new methods, you can replace the deprecated methods with the new ones. For example, the following application configuration:
  55. ====
  56. .Java
  57. [source,java,role="primary"]
  58. ----
  59. @Configuration
  60. @EnableWebSecurity
  61. public class SecurityConfig {
  62. @Bean
  63. public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
  64. http
  65. .authorizeHttpRequests((authz) -> authz
  66. .antMatchers("/api/admin/**").hasRole("ADMIN")
  67. .antMatchers("/api/user/**").hasRole("USER")
  68. .anyRequest().authenticated()
  69. );
  70. return http.build();
  71. }
  72. }
  73. ----
  74. ====
  75. can be changed to:
  76. ====
  77. .Java
  78. [source,java,role="primary"]
  79. ----
  80. @Configuration
  81. @EnableWebSecurity
  82. public class SecurityConfig {
  83. @Bean
  84. public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
  85. http
  86. .authorizeHttpRequests((authz) -> authz
  87. .requestMatchers("/api/admin/**").hasRole("ADMIN")
  88. .requestMatchers("/api/user/**").hasRole("USER")
  89. .anyRequest().authenticated()
  90. );
  91. return http.build();
  92. }
  93. }
  94. ----
  95. ====
  96. If you have Spring MVC in the classpath and are using the `mvcMatchers` methods, you can replace it with the new methods and Spring Security will choose the `MvcRequestMatcher` implementation for you.
  97. The following configuration:
  98. ====
  99. .Java
  100. [source,java,role="primary"]
  101. ----
  102. @Configuration
  103. @EnableWebSecurity
  104. @EnableWebMvc
  105. public class SecurityConfig {
  106. @Bean
  107. SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
  108. http
  109. .authorizeHttpRequests((authz) -> authz
  110. .mvcMatchers("/admin/**").hasRole("ADMIN")
  111. .anyRequest().authenticated()
  112. );
  113. return http.build();
  114. }
  115. }
  116. ----
  117. ====
  118. is equivalent to:
  119. ====
  120. .Java
  121. [source,java,role="primary"]
  122. ----
  123. @Configuration
  124. @EnableWebSecurity
  125. @EnableWebMvc
  126. public class SecurityConfig {
  127. @Bean
  128. SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
  129. http
  130. .authorizeHttpRequests((authz) -> authz
  131. .requestMatchers("/admin/**").hasRole("ADMIN")
  132. .anyRequest().authenticated()
  133. );
  134. return http.build();
  135. }
  136. }
  137. ----
  138. ====
  139. If you are customizing the `servletPath` property of the `MvcRequestMatcher`, you can now use the `MvcRequestMatcher.Builder` to create `MvcRequestMatcher` instances that share the same servlet path:
  140. ====
  141. .Java
  142. [source,java,role="primary"]
  143. ----
  144. @Configuration
  145. @EnableWebSecurity
  146. @EnableWebMvc
  147. public class SecurityConfig {
  148. @Bean
  149. SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
  150. http
  151. .authorizeHttpRequests((authz) -> authz
  152. .mvcMatchers("/admin").servletPath("/path").hasRole("ADMIN")
  153. .mvcMatchers("/user").servletPath("/path").hasRole("USER")
  154. .anyRequest().authenticated()
  155. );
  156. return http.build();
  157. }
  158. }
  159. ----
  160. ====
  161. The code above can be rewritten using the `MvcRequestMatcher.Builder` and the `requestMatchers` method:
  162. ====
  163. .Java
  164. [source,java,role="primary"]
  165. ----
  166. @Configuration
  167. @EnableWebSecurity
  168. @EnableWebMvc
  169. public class SecurityConfig {
  170. @Bean
  171. SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
  172. MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector).servletPath("/path");
  173. http
  174. .authorizeHttpRequests((authz) -> authz
  175. .requestMatchers(mvcMatcherBuilder.pattern("/admin")).hasRole("ADMIN")
  176. .requestMatchers(mvcMatcherBuilder.pattern("/user")).hasRole("USER")
  177. .anyRequest().authenticated()
  178. );
  179. return http.build();
  180. }
  181. }
  182. ----
  183. ====
  184. If you are having problem with the new `requestMatchers` methods, you can always switch back to the `RequestMatcher` implementation that you were using.
  185. For example, if you still want to use `AntPathRequestMatcher` and `RegexRequestMatcher` implementations, you can use the `requestMatchers` method that accepts a `RequestMatcher` instance:
  186. ====
  187. .Java
  188. [source,java,role="primary"]
  189. ----
  190. import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
  191. import static org.springframework.security.web.util.matcher.RegexRequestMatcher.regexMatcher;
  192. @Configuration
  193. @EnableWebSecurity
  194. public class SecurityConfig {
  195. @Bean
  196. SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
  197. http
  198. .authorizeHttpRequests((authz) -> authz
  199. .requestMatchers(antMatcher("/user/**")).hasRole("USER")
  200. .requestMatchers(antMatcher(HttpMethod.POST, "/user/**")).hasRole("ADMIN")
  201. .requestMatchers(regexMatcher(".*\\?x=y")).hasRole("SPECIAL") // matches /any/path?x=y
  202. .anyRequest().authenticated()
  203. );
  204. return http.build();
  205. }
  206. }
  207. ----
  208. ====
  209. Note that the above sample uses static factory methods from {security-api-url}org/springframework/security/web/util/matcher/AntPathRequestMatcher.html[`AntPathRequestMatcher`] and {security-api-url}org/springframework/security/web/util/matcher/RegexRequestMatcher.html[`RegexRequestMatcher`] to improve readability.
  210. If you are using the `WebSecurityCustomizer` interface, you can replace the deprecated `antMatchers` methods:
  211. ====
  212. .Java
  213. [source,java,role="primary"]
  214. ----
  215. @Bean
  216. public WebSecurityCustomizer webSecurityCustomizer() {
  217. return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
  218. }
  219. ----
  220. ====
  221. with their `requestMatchers` counterparts:
  222. ====
  223. .Java
  224. [source,java,role="primary"]
  225. ----
  226. @Bean
  227. public WebSecurityCustomizer webSecurityCustomizer() {
  228. return (web) -> web.ignoring().requestMatchers("/ignore1", "/ignore2");
  229. }
  230. ----
  231. ====
  232. The same way, if you are customizing the CSRF configuration to ignore some paths, you can replace the deprecated methods with the `requestMatchers` methods:
  233. ====
  234. .Java
  235. [source,java,role="primary"]
  236. ----
  237. @Bean
  238. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  239. http
  240. .csrf((csrf) -> csrf
  241. .ignoringAntMatchers("/no-csrf")
  242. );
  243. return http.build();
  244. }
  245. ----
  246. ====
  247. can be changed to:
  248. ====
  249. .Java
  250. [source,java,role="primary"]
  251. ----
  252. @Bean
  253. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  254. http
  255. .csrf((csrf) -> csrf
  256. .ignoringRequestMatchers("/no-csrf")
  257. );
  258. return http.build();
  259. }
  260. ----
  261. ====
  262. [[use-new-security-matchers]]
  263. == Use the new `securityMatchers` methods
  264. In Spring Security 5.8, the `antMatchers`, `mvcMatchers` and `requestMatchers` methods from `HttpSecurity` were deprecated in favor of new `securityMatchers` methods.
  265. Note that these methods are not the same from `authorizeHttpRequests` methods <<use-new-requestmatchers,which were deprecated>> in favor of the `requestMatchers` methods.
  266. However, the `securityMatchers` methods are similar to the `requestMatchers` methods in the sense that they will choose the most appropriate `RequestMatcher` implementation for your application.
  267. In summary, the new methods choose the `MvcRequestMatcher` implementation if your application has Spring MVC in the classpath, falling back to the `AntPathRequestMatcher` implementation if Spring MVC is not present (aligning the behavior with the Kotlin equivalent methods).
  268. Another reason for adding the `securityMatchers` methods is to avoid confusion with the `requestMatchers` methods from `authorizeHttpRequests`.
  269. The following configuration:
  270. ====
  271. .Java
  272. [source,java,role="primary"]
  273. ----
  274. @Bean
  275. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  276. http
  277. .antMatcher("/api/**", "/app/**")
  278. .authorizeHttpRequests((authz) -> authz
  279. .requestMatchers("/api/admin/**").hasRole("ADMIN")
  280. .anyRequest().authenticated()
  281. );
  282. return http.build();
  283. }
  284. ----
  285. ====
  286. can be rewritten using the `securityMatchers` methods:
  287. ====
  288. .Java
  289. [source,java,role="primary"]
  290. ----
  291. @Bean
  292. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  293. http
  294. .securityMatcher("/api/**", "/app/**")
  295. .authorizeHttpRequests((authz) -> authz
  296. .requestMatchers("/api/admin/**").hasRole("ADMIN")
  297. .anyRequest().authenticated()
  298. );
  299. return http.build();
  300. }
  301. ----
  302. ====
  303. If you are using a custom `RequestMatcher` in your `HttpSecurity` configuration:
  304. ====
  305. .Java
  306. [source,java,role="primary"]
  307. ----
  308. @Bean
  309. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  310. http
  311. .requestMatcher(new MyCustomRequestMatcher())
  312. .authorizeHttpRequests((authz) -> authz
  313. .requestMatchers("/api/admin/**").hasRole("ADMIN")
  314. .anyRequest().authenticated()
  315. );
  316. return http.build();
  317. }
  318. public class MyCustomRequestMatcher implements RequestMatcher {
  319. // ...
  320. }
  321. ----
  322. ====
  323. you can do the same using `securityMatcher`:
  324. ====
  325. .Java
  326. [source,java,role="primary"]
  327. ----
  328. @Bean
  329. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  330. http
  331. .securityMatcher(new MyCustomRequestMatcher())
  332. .authorizeHttpRequests((authz) -> authz
  333. .requestMatchers("/api/admin/**").hasRole("ADMIN")
  334. .anyRequest().authenticated()
  335. );
  336. return http.build();
  337. }
  338. public class MyCustomRequestMatcher implements RequestMatcher {
  339. // ...
  340. }
  341. ----
  342. ====
  343. If you are combining multiple `RequestMatcher` implementations in your `HttpSecurity` configuration:
  344. ====
  345. .Java
  346. [source,java,role="primary"]
  347. ----
  348. @Bean
  349. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  350. http
  351. .requestMatchers((matchers) -> matchers
  352. .antMatchers("/api/**", "/app/**")
  353. .mvcMatchers("/admin/**")
  354. .requestMatchers(new MyCustomRequestMatcher())
  355. )
  356. .authorizeHttpRequests((authz) -> authz
  357. .requestMatchers("/admin/**").hasRole("ADMIN")
  358. .anyRequest().authenticated()
  359. );
  360. return http.build();
  361. }
  362. ----
  363. ====
  364. you can change it by using `securityMatchers`:
  365. ====
  366. .Java
  367. [source,java,role="primary"]
  368. ----
  369. @Bean
  370. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  371. http
  372. .securityMatchers((matchers) -> matchers
  373. .requestMatchers("/api/**", "/app/**", "/admin/**")
  374. .requestMatchers(new MyCustomRequestMatcher())
  375. )
  376. .authorizeHttpRequests((authz) -> authz
  377. .requestMatchers("/admin/**").hasRole("ADMIN")
  378. .anyRequest().authenticated()
  379. );
  380. return http.build();
  381. }
  382. ----
  383. ====
  384. If you are having problems with the `securityMatchers` methods choosing the `RequestMatcher` implementation for you, you can always choose the `RequestMatcher` implementation yourself:
  385. ====
  386. .Java
  387. [source,java,role="primary"]
  388. ----
  389. import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
  390. @Bean
  391. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  392. http
  393. .securityMatchers((matchers) -> matchers
  394. .requestMatchers(antMatcher("/api/**"), antMatcher("/app/**"))
  395. )
  396. .authorizeHttpRequests((authz) -> authz
  397. .requestMatchers(antMatcher("/api/admin/**")).hasRole("ADMIN")
  398. .anyRequest().authenticated()
  399. );
  400. return http.build();
  401. }
  402. ----
  403. ====
  404. == Stop Using `WebSecurityConfigurerAdapter`
  405. === Publish a `SecurityFilterChain` Bean
  406. Spring Security 5.4 introduced the capability to publish a `SecurityFilterChain` bean instead of extending `WebSecurityConfigurerAdapter`.
  407. In 6.0, `WebSecurityConfigurerAdapter` is removed.
  408. To prepare for this change, you can replace constructs like:
  409. ====
  410. .Java
  411. [source,java,role="primary"]
  412. ----
  413. @Configuration
  414. public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  415. @Override
  416. protected void configure(HttpSecurity http) throws Exception {
  417. http
  418. .authorizeHttpRequests((authorize) -> authorize
  419. .anyRequest().authenticated()
  420. )
  421. .httpBasic(withDefaults());
  422. }
  423. }
  424. ----
  425. .Kotlin
  426. [source,kotlin,role="secondary"]
  427. ----
  428. @Configuration
  429. open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
  430. @Override
  431. override fun configure(val http: HttpSecurity) {
  432. http {
  433. authorizeHttpRequests {
  434. authorize(anyRequest, authenticated)
  435. }
  436. httpBasic {}
  437. }
  438. }
  439. }
  440. ----
  441. ====
  442. with:
  443. ====
  444. .Java
  445. [source,java,role="primary"]
  446. ----
  447. @Configuration
  448. public class SecurityConfiguration {
  449. @Bean
  450. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  451. http
  452. .authorizeHttpRequests((authorize) -> authorize
  453. .anyRequest().authenticated()
  454. )
  455. .httpBasic(withDefaults());
  456. return http.build();
  457. }
  458. }
  459. ----
  460. .Kotlin
  461. [source,kotlin,role="secondary"]
  462. ----
  463. @Configuration
  464. open class SecurityConfiguration {
  465. @Bean
  466. fun filterChain(http: HttpSecurity): SecurityFilterChain {
  467. http {
  468. authorizeHttpRequests {
  469. authorize(anyRequest, authenticated)
  470. }
  471. httpBasic {}
  472. }
  473. return http.build()
  474. }
  475. }
  476. ----
  477. ====
  478. === Publish a `WebSecurityCustomizer` Bean
  479. Spring Security 5.4 https://github.com/spring-projects/spring-security/issues/8978[introduced `WebSecurityCustomizer`] to replace `configure(WebSecurity web)` in `WebSecurityConfigurerAdapter`.
  480. To prepare for its removal, you can replace code like the following:
  481. ====
  482. .Java
  483. [source,java,role="primary"]
  484. ----
  485. @Configuration
  486. public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  487. @Override
  488. public void configure(WebSecurity web) {
  489. web.ignoring().antMatchers("/ignore1", "/ignore2");
  490. }
  491. }
  492. ----
  493. .Kotlin
  494. [source,kotlin,role="secondary"]
  495. ----
  496. @Configuration
  497. open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
  498. override fun configure(val web: WebSecurity) {
  499. web.ignoring().antMatchers("/ignore1", "/ignore2")
  500. }
  501. }
  502. ----
  503. ====
  504. with:
  505. ====
  506. .Java
  507. [source,java,role="primary"]
  508. ----
  509. @Configuration
  510. public class SecurityConfiguration {
  511. @Bean
  512. public WebSecurityCustomizer webSecurityCustomizer() {
  513. return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
  514. }
  515. }
  516. ----
  517. .Kotlin
  518. [source,kotlin,role="secondary"]
  519. ----
  520. @Configuration
  521. open class SecurityConfiguration {
  522. @Bean
  523. fun webSecurityCustomizer(): WebSecurityCustomizer {
  524. return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2")
  525. }
  526. }
  527. ----
  528. ====
  529. === Publish an `AuthenticationManager` Bean
  530. As part of `WebSecurityConfigurerAdapeter` removal, `configure(AuthenticationManagerBuilder)` is also removed.
  531. Preparing for its removal will differ based on your reason for using it.
  532. ==== LDAP Authentication
  533. If you are using `auth.ldapAuthentication()` for xref:servlet/authentication/passwords/ldap.adoc[LDAP authentication support], you can replace:
  534. ====
  535. .Java
  536. [source,java,role="primary"]
  537. ----
  538. @Configuration
  539. public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  540. @Override
  541. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  542. auth
  543. .ldapAuthentication()
  544. .userDetailsContextMapper(new PersonContextMapper())
  545. .userDnPatterns("uid={0},ou=people")
  546. .contextSource()
  547. .port(0);
  548. }
  549. }
  550. ----
  551. .Kotlin
  552. [source,kotlin,role="secondary"]
  553. ----
  554. @Configuration
  555. open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
  556. override fun configure(auth: AuthenticationManagerBuilder) {
  557. auth
  558. .ldapAuthentication()
  559. .userDetailsContextMapper(PersonContextMapper())
  560. .userDnPatterns("uid={0},ou=people")
  561. .contextSource()
  562. .port(0)
  563. }
  564. }
  565. ----
  566. ====
  567. with:
  568. ====
  569. .Java
  570. [source,java,role="primary"]
  571. ----
  572. @Configuration
  573. public class SecurityConfiguration {
  574. @Bean
  575. public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
  576. EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean =
  577. EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
  578. contextSourceFactoryBean.setPort(0);
  579. return contextSourceFactoryBean;
  580. }
  581. @Bean
  582. AuthenticationManager ldapAuthenticationManager(BaseLdapPathContextSource contextSource) {
  583. LdapBindAuthenticationManagerFactory factory =
  584. new LdapBindAuthenticationManagerFactory(contextSource);
  585. factory.setUserDnPatterns("uid={0},ou=people");
  586. factory.setUserDetailsContextMapper(new PersonContextMapper());
  587. return factory.createAuthenticationManager();
  588. }
  589. }
  590. ----
  591. .Kotlin
  592. [source,kotlin,role="secondary"]
  593. ----
  594. @Configuration
  595. open class SecurityConfiguration {
  596. @Bean
  597. fun contextSourceFactoryBean(): EmbeddedLdapServerContextSourceFactoryBean {
  598. val contextSourceFactoryBean: EmbeddedLdapServerContextSourceFactoryBean =
  599. EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer()
  600. contextSourceFactoryBean.setPort(0)
  601. return contextSourceFactoryBean
  602. }
  603. @Bean
  604. fun ldapAuthenticationManager(val contextSource: BaseLdapPathContextSource): AuthenticationManager {
  605. val factory = LdapBindAuthenticationManagerFactory(contextSource)
  606. factory.setUserDnPatterns("uid={0},ou=people")
  607. factory.setUserDetailsContextMapper(PersonContextMapper())
  608. return factory.createAuthenticationManager()
  609. }
  610. }
  611. ----
  612. ====
  613. ==== JDBC Authentication
  614. If you are using `auth.jdbcAuthentication()` for xref:servlet/authentication/passwords/jdbc.adoc[JDBC Authentication support], you can replace:
  615. ====
  616. .Java
  617. [source,java,role="primary"]
  618. ----
  619. @Configuration
  620. public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  621. @Bean
  622. public DataSource dataSource() {
  623. return new EmbeddedDatabaseBuilder()
  624. .setType(EmbeddedDatabaseType.H2)
  625. .build();
  626. }
  627. @Override
  628. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  629. UserDetails user = User.withDefaultPasswordEncoder()
  630. .username("user")
  631. .password("password")
  632. .roles("USER")
  633. .build();
  634. auth.jdbcAuthentication()
  635. .withDefaultSchema()
  636. .dataSource(this.dataSource)
  637. .withUser(user);
  638. }
  639. }
  640. ----
  641. .Kotlin
  642. [source,kotlin,role="secondary"]
  643. ----
  644. @Configuration
  645. open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
  646. @Bean
  647. fun dataSource(): DataSource {
  648. return EmbeddedDatabaseBuilder()
  649. .setType(EmbeddedDatabaseType.H2)
  650. .build()
  651. }
  652. override fun configure(val auth: AuthenticationManagerBuilder) {
  653. UserDetails user = User.withDefaultPasswordEncoder()
  654. .username("user")
  655. .password("password")
  656. .roles("USER")
  657. .build()
  658. auth.jdbcAuthentication()
  659. .withDefaultSchema()
  660. .dataSource(this.dataSource)
  661. .withUser(user)
  662. }
  663. }
  664. ----
  665. ====
  666. with:
  667. ====
  668. .Java
  669. [source,java,role="primary"]
  670. ----
  671. @Configuration
  672. public class SecurityConfiguration {
  673. @Bean
  674. public DataSource dataSource() {
  675. return new EmbeddedDatabaseBuilder()
  676. .setType(EmbeddedDatabaseType.H2)
  677. .addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
  678. .build();
  679. }
  680. @Bean
  681. public UserDetailsManager users(DataSource dataSource) {
  682. UserDetails user = User.withDefaultPasswordEncoder()
  683. .username("user")
  684. .password("password")
  685. .roles("USER")
  686. .build();
  687. JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);
  688. users.createUser(user);
  689. return users;
  690. }
  691. }
  692. ----
  693. .Kotlin
  694. [source,kotlin,role="secondary"]
  695. ----
  696. @Configuration
  697. open class SecurityConfiguration {
  698. @Bean
  699. fun dataSource(): DataSource {
  700. return EmbeddedDatabaseBuilder()
  701. .setType(EmbeddedDatabaseType.H2)
  702. .addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
  703. .build()
  704. }
  705. @Bean
  706. fun users(val dataSource: DataSource): UserDetailsManager {
  707. val user = User.withDefaultPasswordEncoder()
  708. .username("user")
  709. .password("password")
  710. .roles("USER")
  711. .build()
  712. val users = JdbcUserDetailsManager(dataSource)
  713. users.createUser(user)
  714. return users
  715. }
  716. }
  717. ----
  718. ====
  719. ==== In-Memory Authentication
  720. If you are using `auth.inMemoryAuthentication()` for xref:servlet/authentication/passwords/in-memory.adoc[In-Memory Authentication support], you can replace:
  721. ====
  722. .Java
  723. [source,java,role="primary"]
  724. ----
  725. @Configuration
  726. public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  727. @Override
  728. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  729. UserDetails user = User.withDefaultPasswordEncoder()
  730. .username("user")
  731. .password("password")
  732. .roles("USER")
  733. .build();
  734. auth.inMemoryAuthentication()
  735. .withUser(user);
  736. }
  737. }
  738. ----
  739. .Kotlin
  740. [source,kotlin,role="secondary"]
  741. ----
  742. @Configuration
  743. open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
  744. override fun configure(val auth: AuthenticationManagerBuilder) {
  745. val user = User.withDefaultPasswordEncoder()
  746. .username("user")
  747. .password("password")
  748. .roles("USER")
  749. .build()
  750. auth.inMemoryAuthentication()
  751. .withUser(user)
  752. }
  753. }
  754. ----
  755. ====
  756. with:
  757. ====
  758. .Java
  759. [source,java,role="primary"]
  760. ----
  761. @Configuration
  762. public class SecurityConfiguration {
  763. @Bean
  764. public InMemoryUserDetailsManager userDetailsService() {
  765. UserDetails user = User.withDefaultPasswordEncoder()
  766. .username("user")
  767. .password("password")
  768. .roles("USER")
  769. .build();
  770. return new InMemoryUserDetailsManager(user);
  771. }
  772. }
  773. ----
  774. .Kotlin
  775. [source,kotlin,role="secondary"]
  776. ----
  777. @Configuration
  778. open class SecurityConfiguration {
  779. @Bean
  780. fun userDetailsService(): InMemoryUserDetailsManager {
  781. UserDetails user = User.withDefaultPasswordEncoder()
  782. .username("user")
  783. .password("password")
  784. .roles("USER")
  785. .build()
  786. return InMemoryUserDetailsManager(user)
  787. }
  788. }
  789. ----
  790. ====
  791. == Add `@Configuration` to `@Enable*` annotations
  792. In 6.0, all Spring Security's `@Enable*` annotations had their `@Configuration` removed.
  793. While convenient, it was not consistent with the rest of the Spring projects and most notably Spring Framework's `@Enable*` annotations.
  794. Additionally, the introduction of support for `@Configuration(proxyBeanMethods=false)` in Spring Framework provides another reason to remove `@Configuration` meta-annotation from Spring Security's `@Enable*` annotations and allow users to opt into their preferred configuration mode.
  795. The following annotations had their `@Configuration` removed:
  796. - `@EnableGlobalAuthentication`
  797. - `@EnableGlobalMethodSecurity`
  798. - `@EnableMethodSecurity`
  799. - `@EnableReactiveMethodSecurity`
  800. - `@EnableWebSecurity`
  801. - `@EnableWebFluxSecurity`
  802. For example, if you are using `@EnableWebSecurity`, you will need to change:
  803. ====
  804. .Java
  805. [source,java,role="primary"]
  806. ----
  807. @EnableWebSecurity
  808. public class SecurityConfig {
  809. // ...
  810. }
  811. ----
  812. ====
  813. to:
  814. ====
  815. .Java
  816. [source,java,role="primary"]
  817. ----
  818. @Configuration
  819. @EnableWebSecurity
  820. public class SecurityConfig {
  821. // ...
  822. }
  823. ----
  824. ====
  825. And the same applies to every other annotation listed above.
  826. ==== Other Scenarios
  827. If you are using `AuthenticationManagerBuilder` for something more sophisticated, you can xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationmanager[publish your own `AuthenticationManager` `@Bean`] or wire an `AuthenticationManager` instance into the `HttpSecurity` DSL with {security-api-url}org/springframework/security/config/annotation/web/builders/HttpSecurity.html#authenticationManager(org.springframework.security.authentication.AuthenticationManager)[`HttpSecurity#authenticationManager`].