config.adoc 24 KB

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