From 982aeecccd1f695da56e6b536ae420fb493d1a8f Mon Sep 17 00:00:00 2001 From: lingenj Date: Mon, 23 Dec 2024 15:50:29 +0100 Subject: [PATCH] Keep annotations for merged classes --- .../WebSecurityConfigurerAdapter.java | 65 +++---- .../WebSecurityConfigurerAdapterTest.java | 171 +++++++++--------- 2 files changed, 113 insertions(+), 123 deletions(-) diff --git a/src/main/java/org/openrewrite/java/spring/security5/WebSecurityConfigurerAdapter.java b/src/main/java/org/openrewrite/java/spring/security5/WebSecurityConfigurerAdapter.java index 793b91542..c8149ec5c 100644 --- a/src/main/java/org/openrewrite/java/spring/security5/WebSecurityConfigurerAdapter.java +++ b/src/main/java/org/openrewrite/java/spring/security5/WebSecurityConfigurerAdapter.java @@ -32,6 +32,7 @@ import java.util.stream.Collectors; import static java.util.Collections.emptyList; +import static java.util.stream.Collectors.toList; /** * @author Alex Boyko @@ -54,10 +55,8 @@ public class WebSecurityConfigurerAdapter extends Recipe { private static final String FQN_USER = "org.springframework.security.core.userdetails.User"; private static final String FQN_USER_DETAILS_BUILDER = "org.springframework.security.core.userdetails.User$UserBuilder"; private static final String FQN_USER_DETAILS = "org.springframework.security.core.userdetails.UserDetails"; - private static final String BEAN_PKG = "org.springframework.context.annotation"; - private static final String BEAN_SIMPLE_NAME = "Bean"; - private static final String FQN_BEAN = BEAN_PKG + "." + BEAN_SIMPLE_NAME; - private static final String BEAN_ANNOTATION = "@" + BEAN_SIMPLE_NAME; + private static final String FQN_BEAN = "org.springframework.context.annotation.Bean"; + private static final String BEAN_ANNOTATION = "@Bean"; private static final MethodMatcher CONFIGURE_HTTP_SECURITY_METHOD_MATCHER = new MethodMatcher("org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)", true); @@ -144,15 +143,7 @@ public TreeVisitor getVisitor() { } // only applicable to former subclasses of WebSecurityConfigurerAdapter - other classes won't be flattened classesToFlatten.add(classDecl); - // Remove imports for annotations being removed together with class declaration - // It is impossible in the general case to tell whether some of these annotations might apply to the bean methods - // However, a set of hardcoded annotations can be moved in the future - for (J.Annotation a : classDecl.getLeadingAnnotations()) { - JavaType.FullyQualified type = TypeUtils.asFullyQualified(a.getType()); - if (type != null) { - maybeRemoveImport(type); - } - } + maybeRemoveImport(FQN_CONFIGURATION); classDecl = null; // remove class } } @@ -217,9 +208,11 @@ private J.ClassDeclaration processAnyClass(J.ClassDeclaration classDecl, Executi continue; } String uniqueName = computeBeanNameFromClassName(fc.getSimpleName(), beanType.getClassName()); + List fcLeadingAnnotations = fc.getLeadingAnnotations().stream().filter(it -> !TypeUtils.isOfClassType(it.getType(), FQN_CONFIGURATION)).collect(toList()); s = m .withName(m.getName().withSimpleName(uniqueName)) - .withMethodType(m.getMethodType().withName(uniqueName)); + .withMethodType(m.getMethodType().withName(uniqueName)) + .withLeadingAnnotations(ListUtils.concatAll(m.getLeadingAnnotations(), fcLeadingAnnotations)); s = autoFormat(s, ctx, new Cursor(getCursor(), classDecl.getBody())); } } @@ -285,18 +278,12 @@ private J.MethodDeclaration changeToBeanMethod(J.MethodDeclaration m, J.ClassDec if (type != null) { type = type.withName(newMethodName).withReturnType(inmemoryAuthConfigType); if (!keepParams) { - type = type - .withParameterTypes(Collections.emptyList()) - .withParameterNames(Collections.emptyList()); for (JavaType pt : type.getParameterTypes()) { - JavaType.FullyQualified fqt = TypeUtils.asFullyQualified(pt); - if (fqt != null) { - maybeRemoveImport(fqt); - } + maybeRemoveImport(TypeUtils.asFullyQualified(pt)); } + type = type.withParameterTypes(Collections.emptyList()).withParameterNames(Collections.emptyList()); } } - Space returnPrefix = m.getReturnTypeExpression() == null ? Space.EMPTY : m.getReturnTypeExpression().getPrefix(); m = m.withLeadingAnnotations(ListUtils.map(m.getLeadingAnnotations(), anno -> { if (TypeUtils.isOfClassType(anno.getType(), FQN_OVERRIDE)) { @@ -315,9 +302,20 @@ private J.MethodDeclaration changeToBeanMethod(J.MethodDeclaration m, J.ClassDec } maybeAddImport(inmemoryAuthConfigType); - // not calling `updateCursor()` here because `visitBlock()` currently requires - // the original to be stored in the cursor - return addBeanAnnotation(m, new Cursor(getCursor().getParentOrThrow(), m)); + maybeAddImport(FQN_BEAN); + + return JavaTemplate.builder(BEAN_ANNOTATION) + .imports(FQN_BEAN) + .javaParser(JavaParser.fromJavaVersion() + .dependsOn( + "package org.springframework.context.annotation;\n" + + "public @interface Bean {}")) + .build() + .apply( + // not calling `updateCursor()` here because `visitBlock()` currently requires the original to be stored in the cursor + new Cursor(getCursor().getParentOrThrow(), m), + m.getCoordinates().addAnnotation(Comparator.comparing(J.Annotation::getSimpleName)) + ); } @Override @@ -392,7 +390,6 @@ private J.Block handleWebSecurity(J.Block b, J.MethodDeclaration parentMethod) { private J.Block handleAuthInMemory(J.Block b, J.MethodDeclaration parentMethod) { Expression userExpr = findUserParameterExpression(b.getStatements().get(b.getStatements().size() - 1)); - JavaType.FullyQualified type = userExpr == null ? null : TypeUtils.asFullyQualified(userExpr.getType()); String typeStr = ""; if (userExpr != null) { if (userExpr.getType() instanceof JavaType.Primitive) { @@ -452,19 +449,6 @@ private J.Block handleAuthInMemory(J.Block b, J.MethodDeclaration parentMethod) maybeRemoveImport(FQN_AUTH_MANAGER_BUILDER); return b; } - - private J.MethodDeclaration addBeanAnnotation(J.MethodDeclaration m, Cursor c) { - maybeAddImport(FQN_BEAN); - return JavaTemplate.builder(BEAN_ANNOTATION) - .imports(FQN_BEAN) - .javaParser(JavaParser.fromJavaVersion() - .dependsOn("package " + BEAN_PKG + "; public @interface " + BEAN_SIMPLE_NAME + " {}")) - .build() - .apply( - c, - m.getCoordinates().addAnnotation(Comparator.comparing(J.Annotation::getSimpleName)) - ); - } }); } @@ -535,7 +519,7 @@ private static AuthType getAuthType(J.MethodDeclaration m) { } private @Nullable Expression findUserParameterExpression(Statement s) { - AtomicReference context = new AtomicReference<>(); + AtomicReference<@Nullable Expression> context = new AtomicReference<>(); new JavaIsoVisitor>() { @Override public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, AtomicReference ref) { @@ -548,5 +532,4 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Atomi }.visit(s, context); return context.get(); } - } diff --git a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/WebSecurityConfigurerAdapterTest.java b/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/WebSecurityConfigurerAdapterTest.java index 2c928e095..aa07fcee3 100644 --- a/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/WebSecurityConfigurerAdapterTest.java +++ b/src/testWithSpringSecurity_5_7/java/org/openrewrite/spring/security5/WebSecurityConfigurerAdapterTest.java @@ -24,10 +24,7 @@ import static org.openrewrite.java.Assertions.java; -/** - * @author Alex Boyko - */ -@SuppressWarnings({"RedundantThrows", "SpringJavaInjectionPointsAutowiringInspection", "UnnecessaryLocalVariable"}) +@SuppressWarnings({"RedundantThrows", "UnnecessaryLocalVariable"}) class WebSecurityConfigurerAdapterTest implements RewriteTest { @Override @@ -45,15 +42,15 @@ void configureHttpSecurityMethod() { java( """ package com.example.websecuritydemo; - + import static org.springframework.security.config.Customizer.withDefaults; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; - + @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - + @Override protected void configure(HttpSecurity http) throws Exception { http @@ -62,24 +59,24 @@ protected void configure(HttpSecurity http) throws Exception { ) .httpBasic(withDefaults()); } - + void someMethod() {} - + } """, """ package com.example.websecuritydemo; - + import static org.springframework.security.config.Customizer.withDefaults; - + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; - + @Configuration public class SecurityConfiguration { - + @Bean SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http @@ -89,9 +86,9 @@ SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .httpBasic(withDefaults()); return http.build(); } - + void someMethod() {} - + } """ ) @@ -105,13 +102,13 @@ void noConfigurationAnnotation() { java( """ package com.example.websecuritydemo; - + import static org.springframework.security.config.Customizer.withDefaults; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; - + public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - + @Override protected void configure(HttpSecurity http) throws Exception { http @@ -120,7 +117,7 @@ protected void configure(HttpSecurity http) throws Exception { ) .httpBasic(withDefaults()); } - + } """ ) @@ -136,10 +133,10 @@ void configureWebSecurityMethod() { import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.WebSecurity; - + @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - + @Override public void configure(WebSecurity web) { web.ignoring().antMatchers("/ignore1", "/ignore2"); @@ -151,10 +148,10 @@ public void configure(WebSecurity web) { import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; - + @Configuration public class SecurityConfiguration { - + @Bean WebSecurityCustomizer webSecurityCustomizer() { return (web) -> { @@ -177,10 +174,10 @@ void configureAuthManagerMethod() { import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.ldap.userdetails.PersonContextMapper; - + @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - + @Override protected void configure(AuthenticationManagerBuilder auth) { auth @@ -197,10 +194,10 @@ protected void configure(AuthenticationManagerBuilder auth) { import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.ldap.userdetails.PersonContextMapper; - + @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - + /*~~(Migrate manually based on https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter)~~>*/@Override protected void configure(AuthenticationManagerBuilder auth) { auth @@ -217,22 +214,22 @@ protected void configure(AuthenticationManagerBuilder auth) { } @Test - void overrideUnapplicableMethod() { + void overrideInapplicableMethod() { //language=java rewriteRun( java( """ import static org.springframework.security.config.Customizer.withDefaults; - + import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.userdetails.UserDetailsService; - + @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - + @Override protected void configure(HttpSecurity http) throws Exception { http @@ -241,12 +238,12 @@ protected void configure(HttpSecurity http) throws Exception { ) .httpBasic(withDefaults()); } - + @Override public UserDetailsService userDetailsServiceBean() throws Exception { return null; } - + @Override public AuthenticationManager authenticationManagerBean() throws Exception { return null; @@ -255,16 +252,16 @@ public AuthenticationManager authenticationManagerBean() throws Exception { """, """ import static org.springframework.security.config.Customizer.withDefaults; - + import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.userdetails.UserDetailsService; - + @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - + @Override protected void configure(HttpSecurity http) throws Exception { http @@ -273,12 +270,12 @@ protected void configure(HttpSecurity http) throws Exception { ) .httpBasic(withDefaults()); } - + /*~~(Migrate manually based on https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter)~~>*/@Override public UserDetailsService userDetailsServiceBean() throws Exception { return null; } - + /*~~(Migrate manually based on https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter)~~>*/@Override public AuthenticationManager authenticationManagerBean() throws Exception { return null; @@ -290,7 +287,7 @@ public AuthenticationManager authenticationManagerBean() throws Exception { } @Test - void unapplicableMethodInvocation() { + void inapplicableMethodInvocation() { //language=java rewriteRun( java( @@ -299,10 +296,10 @@ void unapplicableMethodInvocation() { import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; - + @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - + @Override protected void configure(HttpSecurity http) { System.out.println(getApplicationContext()); @@ -312,21 +309,21 @@ protected void configure(HttpSecurity http) { ) .httpBasic(withDefaults()); } - + public void someMethod() {} } """, """ import static org.springframework.security.config.Customizer.withDefaults; - + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; - + @Configuration public class SecurityConfiguration { - + @Bean SecurityFilterChain filterChain(HttpSecurity http) { System.out.println(getApplicationContext()); @@ -337,7 +334,7 @@ SecurityFilterChain filterChain(HttpSecurity http) { .httpBasic(withDefaults()); return http.build(); } - + public void someMethod() {} } """ @@ -355,10 +352,10 @@ void configureHttpSecurityMethodWithNotApplicableMethodInNonStaticInnerClass() { import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; - + @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - + @Override protected void configure(HttpSecurity http) throws Exception { http @@ -367,7 +364,7 @@ protected void configure(HttpSecurity http) throws Exception { ) .httpBasic(withDefaults()); } - + @Configuration public class InnerSecurityConfiguration { protected void configure() throws Exception { @@ -378,15 +375,15 @@ protected void configure() throws Exception { """, """ import static org.springframework.security.config.Customizer.withDefaults; - + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; - + @Configuration public class SecurityConfiguration { - + @Bean SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http @@ -396,7 +393,7 @@ SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .httpBasic(withDefaults()); return http.build(); } - + @Configuration public class InnerSecurityConfiguration { protected void configure() throws Exception { @@ -416,6 +413,7 @@ void multipleClasses() { java( """ import org.springframework.context.annotation.Bean; + import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -423,7 +421,7 @@ void multipleClasses() { import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; - + @EnableWebSecurity public class MultiHttpSecurityConfig { @Bean @@ -431,7 +429,7 @@ public UserDetailsService userDetailsService() throws Exception { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); return manager; } - + @Configuration @Order(1) public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { @@ -444,10 +442,11 @@ protected void configure(HttpSecurity http) throws Exception { .httpBasic(); } } - + @Configuration + @ConditionalOnProperty(prefix = "x.y", value = "enabled", havingValue = "true", matchIfMissing = true) public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { - + @Override protected void configure(HttpSecurity http) throws Exception { http @@ -461,12 +460,14 @@ protected void configure(HttpSecurity http) throws Exception { """, """ import org.springframework.context.annotation.Bean; + import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; + import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; - + @EnableWebSecurity public class MultiHttpSecurityConfig { @Bean @@ -474,8 +475,9 @@ public UserDetailsService userDetailsService() throws Exception { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); return manager; } - + @Bean + @Order(1) SecurityFilterChain apiWebSecurityConfigurationSecurityFilterChain(HttpSecurity http) throws Exception { http .antMatcher("/api/**") @@ -485,8 +487,9 @@ SecurityFilterChain apiWebSecurityConfigurationSecurityFilterChain(HttpSecurity .httpBasic(); return http.build(); } - + @Bean + @ConditionalOnProperty(prefix = "x.y", value = "enabled", havingValue = "true", matchIfMissing = true) SecurityFilterChain formLoginSecurityFilterChain(HttpSecurity http) throws Exception { http .authorizeRequests() @@ -508,6 +511,7 @@ void multipleClassesNoFlattening() { java( """ import org.springframework.context.annotation.Bean; + import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -515,19 +519,20 @@ void multipleClassesNoFlattening() { import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; - + @EnableWebSecurity public class MultiHttpSecurityConfig { private int a; - + @Bean public UserDetailsService userDetailsService() throws Exception { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); return manager; } - + @Configuration @Order(1) + @ConditionalOnProperty(prefix = "x.y", value = "enabled", havingValue = "true", matchIfMissing = true) public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { private String a; protected void configure(HttpSecurity http) throws Exception { @@ -539,10 +544,10 @@ protected void configure(HttpSecurity http) throws Exception { .httpBasic(); } } - + @Configuration public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { - + @Override protected void configure(HttpSecurity http) throws Exception { http @@ -556,6 +561,7 @@ protected void configure(HttpSecurity http) throws Exception { """, """ import org.springframework.context.annotation.Bean; + import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -563,22 +569,23 @@ protected void configure(HttpSecurity http) throws Exception { import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; - + @EnableWebSecurity public class MultiHttpSecurityConfig { private int a; - + @Bean public UserDetailsService userDetailsService() throws Exception { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); return manager; } - + @Configuration @Order(1) + @ConditionalOnProperty(prefix = "x.y", value = "enabled", havingValue = "true", matchIfMissing = true) public static class ApiWebSecurityConfigurationAdapter { private String a; - + @Bean SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http @@ -590,7 +597,7 @@ SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http.build(); } } - + @Bean SecurityFilterChain formLoginSecurityFilterChain(HttpSecurity http) throws Exception { http @@ -613,13 +620,13 @@ void inMemoryConfig() { java( """ package com.example.websecuritydemo; - + import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; - + @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override @@ -632,13 +639,13 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception { """, """ package com.example.websecuritydemo; - + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.provisioning.InMemoryUserDetailsManager; - + @Configuration public class SecurityConfiguration { @Bean @@ -660,13 +667,13 @@ void inMemoryConfigWithUserBuilder() { java( """ package com.example.websecuritydemo; - + import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User.UserBuilder; - + @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override @@ -678,13 +685,13 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception { """, """ package com.example.websecuritydemo; - + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User.UserBuilder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; - + @Configuration public class SecurityConfiguration { @Bean @@ -705,11 +712,11 @@ void inMemoryConfigWithUserString() { java( """ package com.example.websecuritydemo; - + import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - + @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override @@ -720,12 +727,12 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception { """, """ package com.example.websecuritydemo; - + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.userdetails.User; import org.springframework.security.provisioning.InMemoryUserDetailsManager; - + @Configuration public class SecurityConfiguration { @Bean