[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6XDSEPAMHPYAFFEN1B5WTAH":3,"skill-same:01M6XDSEPAMHPYAFFEN1B5WTAH":60},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":34,"linkOnly":35,"markdownContent":36,"markdownBody":37,"frontMatter":38,"refName":39,"commitSha":40,"skillDirectory":41,"forksCount":13,"repositoryHtmlUrl":42,"repositoryHomepageUrl":6,"ownerHtmlUrl":43,"ownerBlogUrl":6,"ownerDescription":44,"updatedAt":45,"install":46,"resources":59},"01M6XDSEPAMHPYAFFEN1B5WTAH","spring-security-6",null,"Migrate Spring Security 5 to Spring Security 6 configuration. Use when removing WebSecurityConfigurerAdapter, replacing @EnableGlobalMethodSecurity with @EnableMethodSecurity, converting antMatchers to requestMatchers, or updating to lambda DSL configuration style. Covers SecurityFilterChain beans and authentication manager changes.","Waaaalnut\u002Fskillsbench","Waaaalnut","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F103995656?v=4","01M6XCS9K1V51EY3JMB7DGMX24","01M6XCS9Q4WPW88W62C55G1H44",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks-no-skills\u002Fspring-boot-jakarta-migration\u002Fenvironment\u002Fskills\u002Fspring-security-6\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],"security","spring","spring security","spring security 6","authentication","lambda","migrate","use","configuration","style","with","manager","changes","beans","dsl","when","2026-11-10 10:12:30",false,"---\nname: spring-security-6\ndescription: Migrate Spring Security 5 to Spring Security 6 configuration. Use when removing WebSecurityConfigurerAdapter, replacing @EnableGlobalMethodSecurity with @EnableMethodSecurity, converting antMatchers to requestMatchers, or updating to lambda DSL configuration style. Covers SecurityFilterChain beans and authentication manager changes.\n---\n\n# Spring Security 6 Migration Skill\n\n## Overview\n\nSpring Security 6 (included in Spring Boot 3) removes the deprecated `WebSecurityConfigurerAdapter` and introduces a component-based configuration approach using `SecurityFilterChain` beans.\n\n## Key Changes\n\n### 1. Remove WebSecurityConfigurerAdapter\n\nThe biggest change is moving from class extension to bean configuration.\n\n#### Before (Spring Security 5 \u002F Spring Boot 2)\n\n```java\n@Configuration\n@EnableWebSecurity\n@EnableGlobalMethodSecurity(prePostEnabled = true)\npublic class SecurityConfig extends WebSecurityConfigurerAdapter {\n\n    @Autowired\n    private UserDetailsService userDetailsService;\n\n    @Override\n    protected void configure(AuthenticationManagerBuilder auth) throws Exception {\n        auth.userDetailsService(userDetailsService)\n            .passwordEncoder(passwordEncoder());\n    }\n\n    @Override\n    protected void configure(HttpSecurity http) throws Exception {\n        http\n            .csrf().disable()\n            .sessionManagement()\n                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)\n            .and()\n            .authorizeRequests()\n                .antMatchers(\"\u002Fapi\u002Fpublic\u002F**\").permitAll()\n                .anyRequest().authenticated();\n    }\n\n    @Bean\n    @Override\n    public AuthenticationManager authenticationManagerBean() throws Exception {\n        return super.authenticationManagerBean();\n    }\n}\n```\n\n#### After (Spring Security 6 \u002F Spring Boot 3)\n\n```java\n@Configuration\n@EnableWebSecurity\n@EnableMethodSecurity(prePostEnabled = true)\npublic class SecurityConfig {\n\n    @Bean\n    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {\n        http\n            .csrf(csrf -> csrf.disable())\n            .sessionManagement(session ->\n                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))\n            .authorizeHttpRequests(auth -> auth\n                .requestMatchers(\"\u002Fapi\u002Fpublic\u002F**\").permitAll()\n                .anyRequest().authenticated()\n            );\n        return http.build();\n    }\n\n    @Bean\n    public AuthenticationManager authenticationManager(\n            AuthenticationConfiguration authConfig) throws Exception {\n        return authConfig.getAuthenticationManager();\n    }\n\n    @Bean\n    public PasswordEncoder passwordEncoder() {\n        return new BCryptPasswordEncoder();\n    }\n}\n```\n\n### 2. Method Security Annotation Change (CRITICAL)\n\n**This is a required change.** The `@EnableGlobalMethodSecurity` annotation is **removed** in Spring Security 6 and must be replaced with `@EnableMethodSecurity`.\n\n```java\n\u002F\u002F BEFORE (Spring Security 5 \u002F Spring Boot 2) - WILL NOT COMPILE in Spring Boot 3\n@EnableGlobalMethodSecurity(prePostEnabled = true)\n\n\u002F\u002F AFTER (Spring Security 6 \u002F Spring Boot 3) - REQUIRED\n@EnableMethodSecurity(prePostEnabled = true)\n```\n\n#### Import Change\n\n```java\n\u002F\u002F BEFORE\nimport org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;\n\n\u002F\u002F AFTER\nimport org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;\n```\n\n#### Quick Migration Command\n\n```bash\n# Replace the annotation in all Java files\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F@EnableGlobalMethodSecurity\u002F@EnableMethodSecurity\u002Fg' {} +\n\n# Also update the import statement\nfind . -name \"*.java\" -type f -exec sed -i 's\u002FEnableGlobalMethodSecurity\u002FEnableMethodSecurity\u002Fg' {} +\n```\n\n#### Verify @EnableMethodSecurity Is Present\n\nAfter migration, confirm the new annotation exists:\n\n```bash\n# This should return results showing your security config class\ngrep -r \"@EnableMethodSecurity\" --include=\"*.java\" .\n```\n\nIf this returns no results but you're using method-level security (`@PreAuthorize`, `@PostAuthorize`, etc.), the migration is incomplete.\n\n### 3. Lambda DSL Configuration\n\nSpring Security 6 uses lambda-based configuration:\n\n```java\n\u002F\u002F Before (chained methods)\nhttp\n    .csrf().disable()\n    .cors().and()\n    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)\n    .and()\n    .authorizeRequests()\n        .antMatchers(\"\u002Fpublic\u002F**\").permitAll()\n        .anyRequest().authenticated();\n\n\u002F\u002F After (lambda DSL)\nhttp\n    .csrf(csrf -> csrf.disable())\n    .cors(cors -> cors.configurationSource(corsConfigurationSource()))\n    .sessionManagement(session ->\n        session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))\n    .authorizeHttpRequests(auth -> auth\n        .requestMatchers(\"\u002Fpublic\u002F**\").permitAll()\n        .anyRequest().authenticated()\n    );\n```\n\n### 4. URL Matching Changes\n\n`antMatchers()` is replaced with `requestMatchers()`:\n\n```java\n\u002F\u002F Before\n.antMatchers(\"\u002Fapi\u002F**\").authenticated()\n.antMatchers(HttpMethod.POST, \"\u002Fapi\u002Fusers\").permitAll()\n\n\u002F\u002F After\n.requestMatchers(\"\u002Fapi\u002F**\").authenticated()\n.requestMatchers(HttpMethod.POST, \"\u002Fapi\u002Fusers\").permitAll()\n```\n\n### 5. Exception Handling\n\n```java\n\u002F\u002F Before\n.exceptionHandling()\n    .authenticationEntryPoint((request, response, ex) -> {\n        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);\n    })\n.and()\n\n\u002F\u002F After\n.exceptionHandling(ex -> ex\n    .authenticationEntryPoint((request, response, authException) -> {\n        response.sendError(HttpServletResponse.SC_UNAUTHORIZED,\n            authException.getMessage());\n    })\n)\n```\n\n### 6. Headers Configuration\n\n```java\n\u002F\u002F Before\n.headers().frameOptions().disable()\n\n\u002F\u002F After\n.headers(headers -> headers\n    .frameOptions(frame -> frame.disable())\n)\n```\n\n### 7. UserDetailsService Configuration\n\n```java\n\u002F\u002F The UserDetailsService bean is auto-detected\n\u002F\u002F No need to explicitly configure in AuthenticationManagerBuilder\n\n@Service\npublic class CustomUserDetailsService implements UserDetailsService {\n\n    @Override\n    public UserDetails loadUserByUsername(String username) {\n        \u002F\u002F Implementation\n    }\n}\n```\n\n## Complete Migration Example\n\n### Before (Spring Boot 2.x)\n\n```java\n@Configuration\n@EnableWebSecurity\n@EnableGlobalMethodSecurity(prePostEnabled = true)\npublic class SecurityConfig extends WebSecurityConfigurerAdapter {\n\n    @Autowired\n    private UserDetailsService userDetailsService;\n\n    @Bean\n    public PasswordEncoder passwordEncoder() {\n        return new BCryptPasswordEncoder();\n    }\n\n    @Override\n    protected void configure(AuthenticationManagerBuilder auth) throws Exception {\n        auth.userDetailsService(userDetailsService)\n            .passwordEncoder(passwordEncoder());\n    }\n\n    @Override\n    @Bean\n    public AuthenticationManager authenticationManagerBean() throws Exception {\n        return super.authenticationManagerBean();\n    }\n\n    @Override\n    protected void configure(HttpSecurity http) throws Exception {\n        http\n            .csrf().disable()\n            .sessionManagement()\n                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)\n            .and()\n            .exceptionHandling()\n                .authenticationEntryPoint((request, response, ex) -> {\n                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, ex.getMessage());\n                })\n            .and()\n            .authorizeRequests()\n                .antMatchers(HttpMethod.POST, \"\u002Fapi\u002Fusers\").permitAll()\n                .antMatchers(\"\u002Fapi\u002Fauth\u002F**\").permitAll()\n                .antMatchers(\"\u002Fh2-console\u002F**\").permitAll()\n                .antMatchers(\"\u002Factuator\u002Fhealth\").permitAll()\n                .anyRequest().authenticated()\n            .and()\n            .headers().frameOptions().disable();\n    }\n}\n```\n\n### After (Spring Boot 3.x)\n\n```java\n@Configuration\n@EnableWebSecurity\n@EnableMethodSecurity(prePostEnabled = true)\npublic class SecurityConfig {\n\n    @Bean\n    public PasswordEncoder passwordEncoder() {\n        return new BCryptPasswordEncoder();\n    }\n\n    @Bean\n    public AuthenticationManager authenticationManager(\n            AuthenticationConfiguration authConfig) throws Exception {\n        return authConfig.getAuthenticationManager();\n    }\n\n    @Bean\n    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {\n        http\n            .csrf(csrf -> csrf.disable())\n            .sessionManagement(session ->\n                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))\n            .exceptionHandling(ex -> ex\n                .authenticationEntryPoint((request, response, authException) -> {\n                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED,\n                        authException.getMessage());\n                })\n            )\n            .authorizeHttpRequests(auth -> auth\n                .requestMatchers(HttpMethod.POST, \"\u002Fapi\u002Fusers\").permitAll()\n                .requestMatchers(\"\u002Fapi\u002Fauth\u002F**\").permitAll()\n                .requestMatchers(\"\u002Fh2-console\u002F**\").permitAll()\n                .requestMatchers(\"\u002Factuator\u002Fhealth\").permitAll()\n                .anyRequest().authenticated()\n            )\n            .headers(headers -> headers\n                .frameOptions(frame -> frame.disable())\n            );\n\n        return http.build();\n    }\n}\n```\n\n## Servlet Namespace Change\n\nDon't forget the servlet import change:\n\n```java\n\u002F\u002F Before\nimport javax.servlet.http.HttpServletResponse;\n\n\u002F\u002F After\nimport jakarta.servlet.http.HttpServletResponse;\n```\n\n## Testing Security\n\nUpdate security test annotations if needed:\n\n```java\n@SpringBootTest\n@AutoConfigureMockMvc\nclass SecurityTests {\n\n    @Test\n    @WithMockUser(roles = \"ADMIN\")\n    void adminEndpoint_withAdminUser_shouldSucceed() {\n        \u002F\u002F Test implementation\n    }\n}\n```\n\n## Migration Commands Summary\n\n### Step 1: Remove WebSecurityConfigurerAdapter\n\n```bash\n# Find classes extending WebSecurityConfigurerAdapter\ngrep -r \"extends WebSecurityConfigurerAdapter\" --include=\"*.java\" .\n\n# The class must be refactored - cannot be automated with sed\n```\n\n### Step 2: Replace Method Security Annotation\n\n```bash\n# Replace @EnableGlobalMethodSecurity with @EnableMethodSecurity\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F@EnableGlobalMethodSecurity\u002F@EnableMethodSecurity\u002Fg' {} +\n\n# Update import\nfind . -name \"*.java\" -type f -exec sed -i 's\u002Fimport org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity\u002Fimport org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity\u002Fg' {} +\n```\n\n### Step 3: Replace antMatchers with requestMatchers\n\n```bash\n# Replace antMatchers\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F\\.antMatchers(\u002F.requestMatchers(\u002Fg' {} +\n\n# Replace mvcMatchers\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F\\.mvcMatchers(\u002F.requestMatchers(\u002Fg' {} +\n\n# Replace regexMatchers\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F\\.regexMatchers(\u002F.requestMatchers(\u002Fg' {} +\n```\n\n### Step 4: Replace authorizeRequests with authorizeHttpRequests\n\n```bash\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F\\.authorizeRequests(\u002F.authorizeHttpRequests(\u002Fg' {} +\n```\n\n## Verification Commands\n\n### Verify No Deprecated Patterns Remain\n\n```bash\n# Should return NO results\ngrep -r \"WebSecurityConfigurerAdapter\" --include=\"*.java\" .\ngrep -r \"@EnableGlobalMethodSecurity\" --include=\"*.java\" .\ngrep -r \"\\.antMatchers(\" --include=\"*.java\" .\ngrep -r \"\\.authorizeRequests(\" --include=\"*.java\" .\n```\n\n### Verify New Patterns Are Present\n\n```bash\n# Should return results\ngrep -r \"@EnableMethodSecurity\" --include=\"*.java\" .\ngrep -r \"SecurityFilterChain\" --include=\"*.java\" .\ngrep -r \"\\.requestMatchers(\" --include=\"*.java\" .\ngrep -r \"\\.authorizeHttpRequests(\" --include=\"*.java\" .\n```\n\n## Common Migration Pitfalls\n\n1. **@Configuration is now required separately** - Before Spring Security 6, `@Configuration` was part of `@EnableWebSecurity`. Now you must add it explicitly.\n\n2. **Lambda DSL is mandatory** - The old chained method style (`http.csrf().disable().and()...`) is deprecated and must be converted to lambda style.\n\n3. **AuthenticationManager injection changed** - Use `AuthenticationConfiguration.getAuthenticationManager()` instead of overriding `authenticationManagerBean()`.\n\n4. **UserDetailsService auto-detection** - Spring Security 6 automatically detects `UserDetailsService` beans; no need for explicit configuration.\n\n5. **Method security default changes** - `@EnableMethodSecurity` enables `@PreAuthorize` and `@PostAuthorize` by default (unlike the old annotation).\n\n## Sources\n\n- [Baeldung - Migrate from Spring Security 5 to 6](https:\u002F\u002Fwww.baeldung.com\u002Fspring-security-migrate-5-to-6)\n- [Baeldung - Upgrading Deprecated WebSecurityConfigurerAdapter](https:\u002F\u002Fwww.baeldung.com\u002Fspring-deprecated-websecurityconfigureradapter)\n- [Spring Security 6 Reference](https:\u002F\u002Fdocs.spring.io\u002Fspring-security\u002Freference\u002F)\n","# Spring Security 6 Migration Skill\n\n## Overview\n\nSpring Security 6 (included in Spring Boot 3) removes the deprecated `WebSecurityConfigurerAdapter` and introduces a component-based configuration approach using `SecurityFilterChain` beans.\n\n## Key Changes\n\n### 1. Remove WebSecurityConfigurerAdapter\n\nThe biggest change is moving from class extension to bean configuration.\n\n#### Before (Spring Security 5 \u002F Spring Boot 2)\n\n```java\n@Configuration\n@EnableWebSecurity\n@EnableGlobalMethodSecurity(prePostEnabled = true)\npublic class SecurityConfig extends WebSecurityConfigurerAdapter {\n\n    @Autowired\n    private UserDetailsService userDetailsService;\n\n    @Override\n    protected void configure(AuthenticationManagerBuilder auth) throws Exception {\n        auth.userDetailsService(userDetailsService)\n            .passwordEncoder(passwordEncoder());\n    }\n\n    @Override\n    protected void configure(HttpSecurity http) throws Exception {\n        http\n            .csrf().disable()\n            .sessionManagement()\n                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)\n            .and()\n            .authorizeRequests()\n                .antMatchers(\"\u002Fapi\u002Fpublic\u002F**\").permitAll()\n                .anyRequest().authenticated();\n    }\n\n    @Bean\n    @Override\n    public AuthenticationManager authenticationManagerBean() throws Exception {\n        return super.authenticationManagerBean();\n    }\n}\n```\n\n#### After (Spring Security 6 \u002F Spring Boot 3)\n\n```java\n@Configuration\n@EnableWebSecurity\n@EnableMethodSecurity(prePostEnabled = true)\npublic class SecurityConfig {\n\n    @Bean\n    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {\n        http\n            .csrf(csrf -> csrf.disable())\n            .sessionManagement(session ->\n                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))\n            .authorizeHttpRequests(auth -> auth\n                .requestMatchers(\"\u002Fapi\u002Fpublic\u002F**\").permitAll()\n                .anyRequest().authenticated()\n            );\n        return http.build();\n    }\n\n    @Bean\n    public AuthenticationManager authenticationManager(\n            AuthenticationConfiguration authConfig) throws Exception {\n        return authConfig.getAuthenticationManager();\n    }\n\n    @Bean\n    public PasswordEncoder passwordEncoder() {\n        return new BCryptPasswordEncoder();\n    }\n}\n```\n\n### 2. Method Security Annotation Change (CRITICAL)\n\n**This is a required change.** The `@EnableGlobalMethodSecurity` annotation is **removed** in Spring Security 6 and must be replaced with `@EnableMethodSecurity`.\n\n```java\n\u002F\u002F BEFORE (Spring Security 5 \u002F Spring Boot 2) - WILL NOT COMPILE in Spring Boot 3\n@EnableGlobalMethodSecurity(prePostEnabled = true)\n\n\u002F\u002F AFTER (Spring Security 6 \u002F Spring Boot 3) - REQUIRED\n@EnableMethodSecurity(prePostEnabled = true)\n```\n\n#### Import Change\n\n```java\n\u002F\u002F BEFORE\nimport org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;\n\n\u002F\u002F AFTER\nimport org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;\n```\n\n#### Quick Migration Command\n\n```bash\n# Replace the annotation in all Java files\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F@EnableGlobalMethodSecurity\u002F@EnableMethodSecurity\u002Fg' {} +\n\n# Also update the import statement\nfind . -name \"*.java\" -type f -exec sed -i 's\u002FEnableGlobalMethodSecurity\u002FEnableMethodSecurity\u002Fg' {} +\n```\n\n#### Verify @EnableMethodSecurity Is Present\n\nAfter migration, confirm the new annotation exists:\n\n```bash\n# This should return results showing your security config class\ngrep -r \"@EnableMethodSecurity\" --include=\"*.java\" .\n```\n\nIf this returns no results but you're using method-level security (`@PreAuthorize`, `@PostAuthorize`, etc.), the migration is incomplete.\n\n### 3. Lambda DSL Configuration\n\nSpring Security 6 uses lambda-based configuration:\n\n```java\n\u002F\u002F Before (chained methods)\nhttp\n    .csrf().disable()\n    .cors().and()\n    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)\n    .and()\n    .authorizeRequests()\n        .antMatchers(\"\u002Fpublic\u002F**\").permitAll()\n        .anyRequest().authenticated();\n\n\u002F\u002F After (lambda DSL)\nhttp\n    .csrf(csrf -> csrf.disable())\n    .cors(cors -> cors.configurationSource(corsConfigurationSource()))\n    .sessionManagement(session ->\n        session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))\n    .authorizeHttpRequests(auth -> auth\n        .requestMatchers(\"\u002Fpublic\u002F**\").permitAll()\n        .anyRequest().authenticated()\n    );\n```\n\n### 4. URL Matching Changes\n\n`antMatchers()` is replaced with `requestMatchers()`:\n\n```java\n\u002F\u002F Before\n.antMatchers(\"\u002Fapi\u002F**\").authenticated()\n.antMatchers(HttpMethod.POST, \"\u002Fapi\u002Fusers\").permitAll()\n\n\u002F\u002F After\n.requestMatchers(\"\u002Fapi\u002F**\").authenticated()\n.requestMatchers(HttpMethod.POST, \"\u002Fapi\u002Fusers\").permitAll()\n```\n\n### 5. Exception Handling\n\n```java\n\u002F\u002F Before\n.exceptionHandling()\n    .authenticationEntryPoint((request, response, ex) -> {\n        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);\n    })\n.and()\n\n\u002F\u002F After\n.exceptionHandling(ex -> ex\n    .authenticationEntryPoint((request, response, authException) -> {\n        response.sendError(HttpServletResponse.SC_UNAUTHORIZED,\n            authException.getMessage());\n    })\n)\n```\n\n### 6. Headers Configuration\n\n```java\n\u002F\u002F Before\n.headers().frameOptions().disable()\n\n\u002F\u002F After\n.headers(headers -> headers\n    .frameOptions(frame -> frame.disable())\n)\n```\n\n### 7. UserDetailsService Configuration\n\n```java\n\u002F\u002F The UserDetailsService bean is auto-detected\n\u002F\u002F No need to explicitly configure in AuthenticationManagerBuilder\n\n@Service\npublic class CustomUserDetailsService implements UserDetailsService {\n\n    @Override\n    public UserDetails loadUserByUsername(String username) {\n        \u002F\u002F Implementation\n    }\n}\n```\n\n## Complete Migration Example\n\n### Before (Spring Boot 2.x)\n\n```java\n@Configuration\n@EnableWebSecurity\n@EnableGlobalMethodSecurity(prePostEnabled = true)\npublic class SecurityConfig extends WebSecurityConfigurerAdapter {\n\n    @Autowired\n    private UserDetailsService userDetailsService;\n\n    @Bean\n    public PasswordEncoder passwordEncoder() {\n        return new BCryptPasswordEncoder();\n    }\n\n    @Override\n    protected void configure(AuthenticationManagerBuilder auth) throws Exception {\n        auth.userDetailsService(userDetailsService)\n            .passwordEncoder(passwordEncoder());\n    }\n\n    @Override\n    @Bean\n    public AuthenticationManager authenticationManagerBean() throws Exception {\n        return super.authenticationManagerBean();\n    }\n\n    @Override\n    protected void configure(HttpSecurity http) throws Exception {\n        http\n            .csrf().disable()\n            .sessionManagement()\n                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)\n            .and()\n            .exceptionHandling()\n                .authenticationEntryPoint((request, response, ex) -> {\n                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, ex.getMessage());\n                })\n            .and()\n            .authorizeRequests()\n                .antMatchers(HttpMethod.POST, \"\u002Fapi\u002Fusers\").permitAll()\n                .antMatchers(\"\u002Fapi\u002Fauth\u002F**\").permitAll()\n                .antMatchers(\"\u002Fh2-console\u002F**\").permitAll()\n                .antMatchers(\"\u002Factuator\u002Fhealth\").permitAll()\n                .anyRequest().authenticated()\n            .and()\n            .headers().frameOptions().disable();\n    }\n}\n```\n\n### After (Spring Boot 3.x)\n\n```java\n@Configuration\n@EnableWebSecurity\n@EnableMethodSecurity(prePostEnabled = true)\npublic class SecurityConfig {\n\n    @Bean\n    public PasswordEncoder passwordEncoder() {\n        return new BCryptPasswordEncoder();\n    }\n\n    @Bean\n    public AuthenticationManager authenticationManager(\n            AuthenticationConfiguration authConfig) throws Exception {\n        return authConfig.getAuthenticationManager();\n    }\n\n    @Bean\n    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {\n        http\n            .csrf(csrf -> csrf.disable())\n            .sessionManagement(session ->\n                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))\n            .exceptionHandling(ex -> ex\n                .authenticationEntryPoint((request, response, authException) -> {\n                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED,\n                        authException.getMessage());\n                })\n            )\n            .authorizeHttpRequests(auth -> auth\n                .requestMatchers(HttpMethod.POST, \"\u002Fapi\u002Fusers\").permitAll()\n                .requestMatchers(\"\u002Fapi\u002Fauth\u002F**\").permitAll()\n                .requestMatchers(\"\u002Fh2-console\u002F**\").permitAll()\n                .requestMatchers(\"\u002Factuator\u002Fhealth\").permitAll()\n                .anyRequest().authenticated()\n            )\n            .headers(headers -> headers\n                .frameOptions(frame -> frame.disable())\n            );\n\n        return http.build();\n    }\n}\n```\n\n## Servlet Namespace Change\n\nDon't forget the servlet import change:\n\n```java\n\u002F\u002F Before\nimport javax.servlet.http.HttpServletResponse;\n\n\u002F\u002F After\nimport jakarta.servlet.http.HttpServletResponse;\n```\n\n## Testing Security\n\nUpdate security test annotations if needed:\n\n```java\n@SpringBootTest\n@AutoConfigureMockMvc\nclass SecurityTests {\n\n    @Test\n    @WithMockUser(roles = \"ADMIN\")\n    void adminEndpoint_withAdminUser_shouldSucceed() {\n        \u002F\u002F Test implementation\n    }\n}\n```\n\n## Migration Commands Summary\n\n### Step 1: Remove WebSecurityConfigurerAdapter\n\n```bash\n# Find classes extending WebSecurityConfigurerAdapter\ngrep -r \"extends WebSecurityConfigurerAdapter\" --include=\"*.java\" .\n\n# The class must be refactored - cannot be automated with sed\n```\n\n### Step 2: Replace Method Security Annotation\n\n```bash\n# Replace @EnableGlobalMethodSecurity with @EnableMethodSecurity\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F@EnableGlobalMethodSecurity\u002F@EnableMethodSecurity\u002Fg' {} +\n\n# Update import\nfind . -name \"*.java\" -type f -exec sed -i 's\u002Fimport org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity\u002Fimport org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity\u002Fg' {} +\n```\n\n### Step 3: Replace antMatchers with requestMatchers\n\n```bash\n# Replace antMatchers\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F\\.antMatchers(\u002F.requestMatchers(\u002Fg' {} +\n\n# Replace mvcMatchers\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F\\.mvcMatchers(\u002F.requestMatchers(\u002Fg' {} +\n\n# Replace regexMatchers\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F\\.regexMatchers(\u002F.requestMatchers(\u002Fg' {} +\n```\n\n### Step 4: Replace authorizeRequests with authorizeHttpRequests\n\n```bash\nfind . -name \"*.java\" -type f -exec sed -i 's\u002F\\.authorizeRequests(\u002F.authorizeHttpRequests(\u002Fg' {} +\n```\n\n## Verification Commands\n\n### Verify No Deprecated Patterns Remain\n\n```bash\n# Should return NO results\ngrep -r \"WebSecurityConfigurerAdapter\" --include=\"*.java\" .\ngrep -r \"@EnableGlobalMethodSecurity\" --include=\"*.java\" .\ngrep -r \"\\.antMatchers(\" --include=\"*.java\" .\ngrep -r \"\\.authorizeRequests(\" --include=\"*.java\" .\n```\n\n### Verify New Patterns Are Present\n\n```bash\n# Should return results\ngrep -r \"@EnableMethodSecurity\" --include=\"*.java\" .\ngrep -r \"SecurityFilterChain\" --include=\"*.java\" .\ngrep -r \"\\.requestMatchers(\" --include=\"*.java\" .\ngrep -r \"\\.authorizeHttpRequests(\" --include=\"*.java\" .\n```\n\n## Common Migration Pitfalls\n\n1. **@Configuration is now required separately** - Before Spring Security 6, `@Configuration` was part of `@EnableWebSecurity`. Now you must add it explicitly.\n\n2. **Lambda DSL is mandatory** - The old chained method style (`http.csrf().disable().and()...`) is deprecated and must be converted to lambda style.\n\n3. **AuthenticationManager injection changed** - Use `AuthenticationConfiguration.getAuthenticationManager()` instead of overriding `authenticationManagerBean()`.\n\n4. **UserDetailsService auto-detection** - Spring Security 6 automatically detects `UserDetailsService` beans; no need for explicit configuration.\n\n5. **Method security default changes** - `@EnableMethodSecurity` enables `@PreAuthorize` and `@PostAuthorize` by default (unlike the old annotation).\n\n## Sources\n\n- [Baeldung - Migrate from Spring Security 5 to 6](https:\u002F\u002Fwww.baeldung.com\u002Fspring-security-migrate-5-to-6)\n- [Baeldung - Upgrading Deprecated WebSecurityConfigurerAdapter](https:\u002F\u002Fwww.baeldung.com\u002Fspring-deprecated-websecurityconfigureradapter)\n- [Spring Security 6 Reference](https:\u002F\u002Fdocs.spring.io\u002Fspring-security\u002Freference\u002F)\n",{"name":5,"description":7},"main","7eeb258ada72b7f58119b0e7a2c00ea89d9beedd","tasks-no-skills\u002Fspring-boot-jakarta-migration\u002Fenvironment\u002Fskills\u002Fspring-security-6","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench","https:\u002F\u002Fgithub.com\u002FWaaaalnut","student of Zhejiang University","2026-04-21 23:16:23",{"source":8,"skillName":5,"commands":47,"prompt":57,"zipAvailable":58},[48,51,54],{"tool":49,"command":50},"npx","npx skills add Waaaalnut\u002Fskillsbench --skill spring-security-6",{"tool":52,"command":53},"bunx","bunx skills add Waaaalnut\u002Fskillsbench --skill spring-security-6",{"tool":55,"command":56},"pnpm","pnpm dlx skills add Waaaalnut\u002Fskillsbench --skill spring-security-6","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks-no-skills\u002Fspring-boot-jakarta-migration\u002Fenvironment\u002Fskills\u002Fspring-security-6\u002FSKILL.md",true,[],[61,75,90,116,138,157],{"skillNo":62,"name":63,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":64,"categories":65,"keywords":71,"publishedAt":34},"01M6XEWMJ6VY3ZC53MPDCPG3GH","data-reconciliation","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fxlsx-recover-data\u002Fenvironment\u002Fskills\u002Fdata-reconciliation\u002FSKILL.md",[66],{"categoryNo":67,"categoryName":68,"taxonomyType":69,"taxonomyTypeDesc":70},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[72,73,74],"data reconciliation","reconciliation","data",{"skillNo":76,"name":77,"nameZh":6,"description":78,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":34},"01M6XEW8MNPMF1KRXV6ATGFRQF","speech-to-text","Transcribe video to timestamped text using Whisper tiny model (pre-installed).","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-tutorial-indexer\u002Fenvironment\u002Fskills\u002Fspeech-to-text\u002FSKILL.md",[],[82,83,84,85,86,87,88,89],"speech","text","speech to text","transcribe video","whisper","model","Video","transcribe",{"skillNo":91,"name":92,"nameZh":6,"description":93,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":101,"publishedAt":34},"01M6XEW3FQZP0T1RKQQJFXVY9T","video-processor","Process videos by removing segments and concatenating remaining parts. Use when you need to remove detected pauses\u002Fopenings from videos, create highlight reels, or batch process segment removals using ffmpeg filter_complex.","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Fvideo-processor\u002FSKILL.md",[96],{"categoryNo":97,"categoryName":98,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[88,102,103,104,105,106,33,107,108,109,110,111,112,113,114,25,115],"processor","video processor","batch","create","reels","parts","segments","process","videos","you","segment","filter","ffmpeg","remove",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":123,"publishedAt":34},"01M6XEVXJ5KZ0NTY3XZKRY4AS1","silence-detector","Detect initial silence segments in audio\u002Fvideo using energy-based analysis. Use when you need to find low-energy periods at the start of recordings (title slides, setup time, pre-roll silence).","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Fsilence-detector\u002FSKILL.md",[122],{"categoryNo":97,"categoryName":98,"taxonomyType":99,"taxonomyTypeDesc":100},[124,125,126,127,33,111,128,129,130,131,132,108,133,134,88,135,136,137,25],"detector","silence detector","title","slides","time","energy","at","recordings","detect","find","Audio","analysis","start","setup",{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":144,"publishedAt":34},"01M6XEVT3NGRN1FT7JPMAPXS6M","segment-combiner","Combine multiple segment detection results into a unified list. Use when you need to merge segments from different detectors, prepare removal lists for video processing, or consolidate detection outputs.","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Fsegment-combiner\u002FSKILL.md",[],[112,145,88,146,147,148,149,150,33,151,152,108,111,153,154,25,155,156],"segment combiner","detection","prepare","merge","video processing","for","outputs","combine","processing","consolidate","results","list",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":166,"publishedAt":34},"01M6XEVMPVASGS2KX86QK4FMT7","report-generator","Generate compression reports for video processing. Use when you need to create structured JSON reports with duration statistics, compression ratios, and segment details after video processing.","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Freport-generator\u002FSKILL.md",[163],{"categoryNo":164,"categoryName":165,"taxonomyType":69,"taxonomyTypeDesc":70},"01JBSEEDCAT000000000000034","行政与办公人员",[167,168,169,112,33,150,111,28,153,170,171,172,25,149,173,88,174,175,105],"generator","report generator","report","statistics","structured","reports","json","compression","generate"]