HttpSecurity 구성 심층 학습
다양한 HTTP 요청과 엔드포인트에 대한 보안 규칙을 정의하도록 `HttpSecurity` 구성을 익힙니다.
HttpSecurity 구성 심층 학습은(는) CoddyKit의 무료 Spring Security 6 & JWT Authentication 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Spring Security 6 & JWT Authentication 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Spring Security 6 & JWT Authentication 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
What is HttpSecurity?
HttpSecurity is a core component in Spring Security. It's like the security guard for your web application's doors.
It lets you define rules for different HTTP requests, controlling who can access which parts of your application and under what conditions.
- Authentication: Who are you? (Are you logged in?)
- Authorization: What are you allowed to do? (Do you have permission?)
Your First Security Chain
You configure HttpSecurity within a SecurityFilterChain bean. This bean defines a chain of filters that Spring Security uses to secure your app.
Here's a minimal setup. Run it and try to access /hello. You'll be redirected to a login page!
Use username: user, password: password.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class SecurityApp {
public static void main(String[] args) {
SpringApplication.run(SecurityApp.class, args);
}
@GetMapping("/hello")
public String sayHello() {
return "Hello, secured world!";
}
}
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated() // All requests need authentication
)
.formLogin(form -> form
.permitAll() // Allow everyone to see the login page
)
.logout(logout -> logout
.permitAll()); // Allow everyone to logout
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}Setting Access Rules
The .authorizeHttpRequests() method is where you begin defining authorization rules for your application's URLs.
Inside its lambda, you specify patterns and the access requirements for those patterns. Think of it as telling the security guard: "For this path, apply these rules."
This method chain is part of the SecurityFilterChain bean.
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.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
// This snippet shows the core authorizeHttpRequests() part.
// It assumes the surrounding Spring Boot application and
// SecurityConfig class from the previous scene.
@Configuration
@EnableWebSecurity
class SecurityConfigSnippet {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
// Your specific rules go here!
// Example: .requestMatchers("/public/**").permitAll()
// Example: .anyRequest().authenticated()
)
.formLogin(form -> form.permitAll())
.logout(logout -> logout.permitAll());
return http.build();
}
}Public & Restricted Paths
You can define paths that are accessible to everyone (permitAll()) or absolutely no one (denyAll()).
Use requestMatchers() to specify the URL patterns. Remember, rules are processed in order, so more specific rules should come first.
Run this app and try /public, then /private (login as user/password), then /secret.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class PublicPrivateApp {
public static void main(String[] args) {
SpringApplication.run(PublicPrivateApp.class, args);
}
@GetMapping("/public")
public String publicContent() {
return "This is public content!";
}
@GetMapping("/private")
public String privateContent() {
return "This is private content!";
}
@GetMapping("/secret")
public String secretContent() {
return "Top secret! No one allowed here.";
}
}
@Configuration
@EnableWebSecurity
class SecurityConfigPublicPrivate {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll() // Anyone can access
.requestMatchers("/secret/**").denyAll() // No one can access
.anyRequest().authenticated() // All other requests need login
)
.formLogin(form -> form.permitAll())
.logout(logout -> logout.permitAll());
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}Only Logged-In Users
The .authenticated() method is used to ensure that a user has successfully logged in before accessing a specific path.
This is a fundamental rule for any part of your application that requires a user identity, such as a dashboard or profile page.
// Inside your SecurityFilterChain configuration:
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/register").permitAll() // Public paths
.requestMatchers("/dashboard/**").authenticated() // Needs login
.anyRequest().denyAll() // Deny everything else by default
)
// ... other http configurations (formLogin, logout) ...Restricting by User Roles
You can grant access based on a user's role using .hasRole("ROLENAME") or .hasAuthority("ROLE_ROLENAME"). Spring Security automatically prefixes roles with "ROLE_" when using hasRole().
This allows fine-grained control over who can access sensitive resources. Run this app. Login as 'user' (password 'password') to access /user-dashboard. Login as 'admin' (password 'admin') to access /admin-panel.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class RoleBasedApp {
public static void main(String[] args) {
SpringApplication.run(RoleBasedApp.class, args);
}
@GetMapping("/home")
public String home() { return "Welcome!"; }
@GetMapping("/user-dashboard")
public String userDashboard() { return "User Dashboard!"; }
@GetMapping("/admin-panel")
public String adminPanel() { return "Admin Panel!"; }
}
@Configuration
@EnableWebSecurity
class SecurityConfigRoles {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/home").permitAll()
.requestMatchers("/user-dashboard").hasRole("USER") // Only users with ROLE_USER
.requestMatchers("/admin-panel").hasRole("ADMIN") // Only users with ROLE_ADMIN
.anyRequest().authenticated() // All others need login
)
.formLogin(form -> form.permitAll())
.logout(logout -> logout.permitAll());
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
UserDetails admin = User.withDefaultPasswordEncoder()
.username("admin")
.password("admin")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}Rule Order is Crucial
When defining multiple rules with requestMatchers(), their order matters! Spring Security processes them from top to bottom, applying the first matching rule.
- Most Specific First: Place specific URL patterns (e.g.,
/api/admin/users) before broader ones (e.g.,/api/admin/**). - Catch-All Last: The
.anyRequest()matcher should almost always be the last rule, acting as a default for anything not matched before.
// Incorrect order example (the second rule is unreachable):
// auth
// .requestMatchers("/admin/**").authenticated()
// .requestMatchers("/admin/public").permitAll()
// Correct order example:
// auth
// .requestMatchers("/admin/public").permitAll()
// .requestMatchers("/admin/**").hasRole("ADMIN")
// .anyRequest().authenticated()Configuring Form Login
Spring Security provides a default login page. You can customize its behavior using .formLogin() within HttpSecurity.
Key configurations include the login page URL, the URL to process login data, and where to redirect after success or failure.
// Inside your SecurityFilterChain configuration:
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/custom-login") // Specify custom login page URL
.loginProcessingUrl("/authenticate") // URL to submit login data
.defaultSuccessUrl("/dashboard", true) // Redirect after success
.failureUrl("/custom-login?error") // Redirect on failure
.permitAll() // Allow access to login page and its processing
)
.logout(logout -> logout.permitAll());Cross-Site Request Forgery (CSRF)
CSRF is an attack where a malicious website tricks a user's browser into making an unwanted request to another trusted site where the user is authenticated.
Spring Security provides robust CSRF protection by default for stateful applications.
- Enabled by default: For POST, PUT, DELETE requests, requiring a unique token.
- Disable with caution: Use
.csrf().disable()only for stateless APIs (e.g., REST APIs using JWTs) or when you have other CSRF protection.
// Inside your SecurityFilterChain configuration:
http
// ... authorization rules ...
.csrf(csrf -> csrf.disable()) // ONLY disable if you know what you're doing!
// Common for stateless REST APIs.
// ... formLogin, logout ...
;HttpSecurity Configuration Check
You're building a Spring Boot application. You need to:
- Allow public access to
/api/public/**. - Require users with the
ADMINrole to access/api/admin/**. - All other requests should require any authenticated user.
Which of the following configurations correctly achieve these requirements? (Select all that apply)
HttpSecurity Deep Dive Recap
Great job! You've mastered the essentials of HttpSecurity configuration.
We covered:
- The role of
HttpSecurityin defining web security rules. - Using
.authorizeHttpRequests()for path-based authorization. - Methods like
.permitAll(),.denyAll(),.authenticated(), and.hasRole(). - The importance of rule order when defining multiple access rules.
- Configuring
.formLogin()for custom login pages. - Understanding and managing CSRF protection.
These skills are crucial for building robust and secure Spring Boot applications!
자주 묻는 질문
“HttpSecurity 구성 심층 학습” 강의는 무료인가요?
네 — “HttpSecurity 구성 심층 학습” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Spring Security 6 & JWT Authentication 강의 전체를 잠금 해제할 수 있습니다. Spring Security 6 & JWT Authentication 강의에는 총 4개의 강의가 포함되어 있습니다.
“HttpSecurity 구성 심층 학습”에서 뭘 배우나요?
다양한 HTTP 요청과 엔드포인트에 대한 보안 규칙을 정의하도록 `HttpSecurity` 구성을 익힙니다. 브라우저에서 직접 실행하는 실습 코드로 Spring Security 6 & JWT Authentication을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Spring Security 6 & JWT Authentication을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Spring Security 6 & JWT Authentication은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“HttpSecurity 구성 심층 학습” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Spring Security 6 & JWT Authentication 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Spring Security 6 & JWT Authentication 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 역할 기반 접근 제어(RBAC)
- 주석을 사용한 메서드 수준 보안
- HttpSecurity 구성 심층 학습
- 사용자 지정 접근 규칙으로 엔드포인트 보호하기