스프링 보안은 인증 및 접근 제어를 통해 애플리케이션을 보호하는 데 필수적인 구성 요소입니다. 기본적으로 애플리케이션 내의 모든 URL 또는 웹 페이지에 대해 권한이 있는 개인의 유효성 검사가 필요하도록 강제합니다.
이 프레임워크가 제공하는 유연성을 통해 애플리케이션 내의 개별 HTTP 요청 경로뿐만 아니라 개별 사용자 집단에 대한 맞춤형 보안 조치를 설정할 수 있습니다. 따라서 홈페이지와 같이 사용자 인증이 필요하지 않은 페이지에 적용되는 제한을 완화할 수 있습니다. 또한 특정 사용자 분류에 대한 역할 할당 및 권한 수준을 쉽게 지정할 수 있습니다.
애플리케이션에 스프링 보안 추가하기
스프링 보안은 두 가지 방법 중 하나를 통해 애플리케이션에 통합할 수 있습니다. 첫 번째 접근 방식은 Spring Initializr 도구를 사용하여 새 Spring Boot 프로젝트를 생성하는 동안 포함을 선택하는 것입니다. 또는 프로젝트를 생성한 후 빌드 사양 파일의 종속성 섹션에서 Spring Security를 추가하도록 지정할 수 있습니다.
종속성 관리 시스템으로 Gradle과 Maven 중 어떤 것을 선택하느냐는 Gradle 기반 프로젝트 구조를 선택했는지 또는 Maven 기반 프로젝트 구조를 선택했는지에 따라 달라집니다. 전자의 경우 외부 라이브러리 및 리소스를 관리하기 위한 구성 파일을 build.gradle이라고 하며, 후자의 경우 pom.xml로 지정됩니다.
프로젝트가 올바르게 구성되었는지 확인하려면 build.gradle 파일에 특정 의존성을 포함해야 합니다. 필요한 특정 종속성은 빌드하는 애플리케이션의 유형 및 요구 사항과 같은 다양한 요소에 따라 달라집니다. 따라서 특정 상황에 적합한 종속성을 결정하기 위해 문서를 참조하거나 전문가의 도움을 받는 것이 중요합니다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
}
프로젝트에 필요한 종속성이 있는지 확인하려면 앞서 언급한 종속성을 pom.xml 파일에 포함시켜야 합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
아래에서 인증 관련 작업을 처리하는 HttpSecurity 클래스의 formLogin() 및 logout() 함수를 좀 더 세분화하여 표현한 원본 문장을 참조하세요.
이러한 기술을 활용하면 작업이 완료되면 사용자를 지정된 웹페이지로 자동 리디렉션할 수 있습니다. 예를 들어, 사용자가 유효한 인증 정보를 입력하고 “/로그인” 웹페이지에서 “로그인” 버튼을 클릭하면 추가 입력 없이 “/사용자” 페이지로 원활하게 리디렉션됩니다.
궁극적으로 필터체인빈은 인증된 개인에게 소프트웨어에 대한 진입 권한을 부여하는 필터 체인을 구성하고 산출합니다. 보안 구성 모듈 내의 세 가지 구성 요소의 집합적인 기능은 애플리케이션을 보호하는 데 목적이 있습니다.
실제로 필터체인 빈은 모든 HTTP 조회에 대한 권한 임계값을 결정하는 데 중추적인 기능을 담당합니다. 소프트웨어 내의 웹 페이지 수가 증가함에 따라 filterChain 빈을 통해 보안 구성을 설정할 수 있습니다.
스프링 보안의 주요 이점
스프링 보안은 애플리케이션 내에서 사용자 인증과 권한 부여를 모두 고급 수준으로 제어할 수 있는 기능을 제공합니다. 여기에는 특정 수준의 액세스 권한을 가진 다양한 사용자 역할을 정의하여 민감한 데이터와 기능을 무단 액세스로부터 보호할 수 있는 기능이 포함됩니다. 일반 사용자에게 과도한 권한을 부여하면 민감한 정보의 잠재적 침해 또는 오용이라는 심각한 결과를 초래할 수 있으므로 애플리케이션의 보안과 무결성을 유지하려면 액세스 제어를 올바르게 구현하는 것이 중요합니다.
이 문서에 포함된 내용에 따라 제공된 샘플 애플리케이션은 지정된 GitHub 저장소를 통해 액세스할 수 있으며, MIT 라이선스에 명시된 조건에 따라 오픈 소스 기반으로 활용할 수 있습니다.
Spring Security 사용
Spring Security 모듈을 프로젝트에 통합하면 해당 기능에 즉시 액세스할 수 있습니다. 이 기능을 시연하려면 프로그램을 실행하고 브라우저를 Spring Boot의 기본 랜딩 페이지 또는 애플리케이션 내의 다른 대상으로 이동하기만 하면 됩니다. 제공된 예제에서는 시스템의 기본 웹 주소인
package com.springSecurityDemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WebController {
@GetMapping("/")
public String home() {
return "Welcome!";
}
}
앞서 언급한 새로 도입된 컨트롤러의 구현은 다음과 같은 초기 시각적 표현을 가져옵니다:
애플리케이션에 처음 액세스하면 localhost:8080/login 페이지로 이동합니다. 애플리케이션 내의 다른 페이지에 액세스하기 전에 사용자는 콘솔에서 제공하는 자동 생성 비밀번호와 함께 미리 할당된 사용자 이름인 “user”를 입력해야 합니다. 이 정보는 콘솔 자체에 표시되는 메시지 형태로 확인할 수 있습니다.
Using generated security password: c-4c65-4e72-8c3f-3800e631ba81
이후 애플리케이션을 다시 시작할 때 미리 결정된 비밀번호는 변경될 수 있지만, 사용자 이름은 일정하게 유지됩니다. 일반적인 로그인 자격 증명을 입력하면 프로그램 내에서 원하는 인터페이스에 대한 액세스 권한이 부여됩니다.
스프링 보안 사용자 지정
특정 요구 사항에 따라 애플리케이션의 보안을 맞춤화하려면 스프링 보안에서 제공하는 기본 설정을 수정해야 합니다. 그러나 그 전에 이미 Spring Web을 사용하여 기본 웹 애플리케이션을 설정했다고 가정하고 이 특정 예제를 효과적으로 실행하기 위해 충족해야 하는 몇 가지 추가 전제 조건이 있습니다.
Spring Data JPA는 Spring 기반 애플리케이션에서 Java 지속성 API(JPA)로 작업하는 프로세스를 간소화하는 강력하고 효율적인 프레임워크입니다. 데이터 액세스를 위한 사용하기 쉬운 인터페이스를 제공하여 개발자가 데이터베이스 상호 작용의 낮은 수준의 세부 사항에 대해 걱정하지 않고 비즈니스 로직을 구축하는 데 집중할 수 있도록 합니다. 쿼리 번역, 엔티티와 데이터베이스 간의 자동 매핑, 여러 지속성 공급자 지원과 같은 고급 기능을 갖춘 Spring Data JPA를 통해 개발자는 강력하고 확장 가능한 애플리케이션을 쉽게 구축할 수 있습니다.
MySQL JDBC 드라이버는 데이터베이스에 저장된 데이터에 액세스하기 위한 표준화된 인터페이스를 제공하여 Java 애플리케이션이 MySQL 데이터베이스에 연결하고 상호 작용할 수 있도록 하는 소프트웨어 구성 요소입니다. 이 드라이버는 Java 프로그램과 MySQL 서버 간의 통신을 용이하게 하여 개발자가 애플리케이션 코드 내에서 SQL 쿼리 및 데이터베이스 작업의 강력한 기능을 활용할 수 있도록 합니다. MySQL JDBC 드라이버는 연결 풀링, 트랜잭션 및 다중 스레딩과 같은 다양한 기능을 지원하므로 대규모 데이터 세트 또는 트래픽이 많은 애플리케이션으로 작업할 때 성능과 효율성을 향상시킬 수 있습니다. 또한 업계 표준 및 모범 사례를 준수하여 최신 소프트웨어 개발 프로젝트에서 일반적으로 사용되는 다른 도구 및 기술과의 호환성 및 상호 운용성을 보장합니다.
Thymeleaf는 Spring 프레임워크 및 기타 Java 애플리케이션에서 동적 웹 콘텐츠를 제작하는 데 사용되는 인기 있는 서버 측 Java 템플릿 엔진입니다. 런타임에 채워질 데이터의 자리 표시자를 포함하는 특수 구문을 사용하여 작성된 템플릿을 처리하여 HTML 페이지를 생성하는 편리한 방법을 제공합니다. Spring과의 손쉬운 통합과 텍스트 번역과 같은 국제화 기능을 지원하는 Thymeleaf는 효율적이고 사용자 친화적인 웹사이트를 만들고자 하는 개발자에게 필수적인 도구가 되었습니다.
롬복은 인도네시아에 위치한 아름답고 매력적인 섬으로 깨끗한 해변, 맑은 바닷물, 무성한 녹지로 유명합니다. 스노클링, 다이빙, 서핑, 하이킹, 현지 문화 탐험 등 다양한 액티비티를 즐길 수 있어 열대 휴양지를 찾는 여행객들에게 인기 있는 곳입니다. 사람들은 친절하고 친절하여 자연의 아름다움과 문화 체험에 빠져들면서 휴식을 취하고 긴장을 풀기에 이상적인 장소입니다.
Thymeleaf 프레임워크를 활용하면 제시된 데이터에 대한 다양한 관점을 생성할 수 있습니다. 롬복을 통합하면 객체 클래스 내의 코드 양을 크게 최소화할 수 있습니다. JPA 라이브러리와 MySQL 드라이버를 사용하면 특정 데이터베이스를 반드시 사용해야 하는 것은 아니지만, 대안으로 MySQL 데이터베이스와의 상호 작용을 용이하게 할 수 있습니다. 연결을 구성하려면 ‘resources’ 디렉토리 아래에 있는 ‘application.properties’ 파일에 있는 구성을 수정해야 합니다.
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/spring_security
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
로컬에서 호스팅되는 “spring\_security”라는 이름의 MySQL 데이터베이스에 사용자 이름 “root”와 비밀번호 “1234”를 사용하여 연결을 설정하려면 특정 데이터베이스 엔티티와 관련된 해당 정보를 업데이트하여 제공된 구성 코드를 수정해야 합니다.
필요한 모든 종속성이 추가되고 데이터베이스가 생성되면 애플리케이션에 포함할 관점의 수를 결정할 수 있습니다. 또한 애플리케이션 내의 각 관점에 대한 보안 구성을 확인하는 것이 중요합니다. 예시 사례에서는 선택할 수 있는 6가지 관점이 있습니다.
저희 서비스와 관련된 다양한 주제에 대한 풍부한 정보와 리소스를 찾을 수 있는 저희 웹사이트에 오신 것을 환영합니다. 당사 홈페이지는 사용자가 당사 사이트를 탐색하고 필요와 관심사에 따라 관련 콘텐츠에 액세스할 수 있는 진입점 역할을 합니다. 트위터는 방문자에게 유용하고 유익한 기사, 가이드 및 기타 자료를 엄선하여 선별했습니다. 팁과 요령, 업계 인사이트를 찾고 계시든, 아니면 단순히 저희 회사와 저희가 하는 일에 대해 더 자세히 알고 싶으시든, 여기에서 모든 것을 찾을 수 있습니다.
계정을 등록하고 개인의 성장과 발전을 위한 여정을 시작할 수 있는 등록 페이지에 오신 것을 환영합니다. 저희 플랫폼은 모든 배경과 기술 수준의 개인에게 적합한 사용자 친화적인 경험을 제공하도록 설계되었습니다. 시간 관리 기술을 향상하고 싶든 창의력을 개발하고 싶든, 성공에 필요한 도구와 리소스를 갖추고 있습니다. 아래 양식에 정보를 입력하고 제출하기만 하면 빠르고 간편하게 가입할 수 있습니다. 여러분의 목표 달성을 도와드리겠습니다.
우아함과 단순함을 염두에 두고 설계된 사용자 친화적인 로그인 페이지에 오신 것을 환영합니다. 보다 원활한 온라인 경험을 위한 여정에 동참해 주셔서 감사합니다. 계속하려면 아래에 사용자 이름과 비밀번호를 입력하여 인증 절차를 진행해 주세요. 도중에 어려움이 발생하거나 도움이 필요하시면 언제든지 전담 지원팀에 연락하시면 기꺼이 도와드리겠습니다.
로그아웃 페이지는 사용자가 현재 세션을 종료하고 현재 사용 중인 시스템 또는 애플리케이션에서 로그아웃할 수 있는 수단으로 사용됩니다. 이 작업을 통해 민감한 정보가 안전하게 유지되어 사용자의 개인정보와 시스템 내에 저장된 데이터의 무결성을 모두 보호할 수 있습니다. 로그아웃 프로세스에는 일반적으로 세션 종료를 진행하기 전에 사용자의 확인이 포함되므로 무단 액세스에 대한 추가적인 보안 계층을 제공합니다.
사용자 페이지는 각 개인의 고유한 자질과 특성을 보여주는 개인화된 프로필 역할을 합니다. 사용자 페이지는 개인의 배경, 기술, 관심사 및 업적에 대한 개요를 제공하여 다른 사람들이 해당 개인의 전문성과 역량에 대한 통찰력을 얻을 수 있도록 합니다. 사용자 페이지는 대화형으로 설계되어 사용자가 댓글과 토론을 통해 서로 소통하고 아이디어를 공유할 수 있도록 장려합니다. 전반적으로 사용자 페이지는 각 개인에 대한 포괄적인 보기를 제공하여 플랫폼 내에서 협업과 커뮤니티를 촉진합니다.
불편을 드려 죄송합니다만, 원하는 콘텐츠에 액세스하는 동안 오류가 발생한 것 같습니다. 나중에 다시 시도하거나 지원팀에 문의하여 도움을 받으세요.
사용자가 애플리케이션 내에서 개인 프로필 페이지에 액세스하려면 먼저 등록한 후 자격 증명을 사용하여 로그인해야 합니다. 이 단계를 완료한 후에만 이 특정 웹페이지에 액세스할 수 있습니다. 또한 프로젝트 프레임워크 내에 Spring Boot의 표준 리소스 세트에서 제공하는 것 외에 추가로 4개의 패키지를 구축해야 합니다.
등록 컨트롤러 클래스
컨트롤러 패키지의 구현에는 HTTP 요청 관리를 담당하는 클래스의 통합이 포함됩니다. 일반적으로 각 개별 웹 페이지는 이러한 요청을 처리하기 위해 단일 컨트롤러 클래스를 활용하며, WebController 클래스가 그 예입니다. 반대로 등록 뷰는 특정 요구 사항을 수용하기 위해 별도의 기밀 컨트롤러 클래스를 지정해야 하는 고유한 기능을 제공합니다.
@Controller
@RequestMapping("/register")
public class RegistrationController {
private UserRepository userRepo;
private PasswordEncoder passwordEncoder;
public RegistrationController( UserRepository userRepo, PasswordEncoder passwordEncoder) {
this.userRepo = userRepo;
this.passwordEncoder = passwordEncoder;
}
@GetMapping
public String registerForm() {
return "registration";
}
@PostMapping
public String processRegistration(RegistrationForm form) {
userRepo.save(form.toUser(passwordEncoder));
return "redirect:/login";
}
}
등록 컨트롤러는 애플리케이션 내에서 보안 기능의 진입점 역할을 하며, @RequestMapping 주석은 로컬 호스트:8080/register로 향하는 요청을 관리할 수 있음을 나타냅니다.
`@GetMapping` 주석의 사용은 `/register` 요청을 수신할 경우 `registrationForm()` 메서드가 해당 등록 뷰를 렌더링하여 해당 요청을 처리할 책임이 있음을 의미합니다.
방문자가 등록 버튼을 클릭하면 @PostMapping 어노테이션이 작동합니다. processRegistration() 메서드를 사용하면 등록 양식 클래스에서 가져온 사용자 데이터를 UserRepository 클래스를 사용하여 데이터베이스에 게시할 수 있습니다. 하지만 이 데이터를 저장하기 전에 processRegistration() 메서드는 Spring의 PasswordEncoder 인터페이스를 사용하여 사용자의 비밀번호를 암호화합니다.
새 보안 구성 생성
Spring 3.1에는 개발자가 Spring Security에 Java 기반 구성을 활용할 수 있는 새로운 기능이 도입되었습니다. 이를 위해서는 클래스를 사용해야 하며 장황한 XML 파일이 필요하지 않습니다. 이러한 구성 클래스의 주요 전제 조건은 @Configuration 어노테이션이 있어야 한다는 것입니다.
@Configuration
public class SecurityConfiguration {
}
`@Configuration` 어노테이션은 뒤에 오는 클래스가 Spring 프레임워크 에코시스템 내에서 구성 클래스를 구성한다는 선언적 표시 역할을 합니다. 이러한 구성은 애플리케이션을 구성하는 다양한 어셈블리(또는 ‘빈’)를 구성하고 감독하는 저장소 역할을 하는 Spring 애플리케이션 컨텍스트에 대한 조항을 제공하는 데 중요한 역할을 합니다. 이 특별한 사례에서 “빈”이라는 용어로 지정된 첫 번째 요소는 다름 아닌 보안 중심 프로세스의 운영에 필수적인 중추적인 구성 요소인PasswordEncoder 인스턴스화입니다.
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
새로 등록된 비밀번호를 안전하게 인코딩하는 기능을 적절히 통합하기 위해 RegistrationController는 Spring Security에서 제공하는 passwordEncoder 빈의 활용에 의존합니다. 또한 SecurityConfiguration 구성 파일에 userDetailsService 빈이라는 또 다른 중요한 구성 요소를 포함시키는 것이 필수적입니다.
@Bean
public UserDetailsService userDetailsService(UserRepository userRepo) {
return username -> {
Customer customer = userRepo.findByUsername(username);
if (customer != null)
return customer;
throw new UsernameNotFoundException("Customer '" + username + "' not found");
};
}
userDetailsService 빈은 고객의 로그인 세션 중에 Spring Security의 UserDetailsService 인터페이스를 사용하여 인증을 위해 사용자의 사용자 이름과 비밀번호를 검색합니다. 따라서 고객이 로그인 보기에서 로그인 버튼을 클릭하자마자 userDetailsService 빈이 작동합니다.
userDetailsService 빈은 사용자 리포지토리 인터페이스를 활용하여 데이터베이스 내에 저장된 전체 사용자에 대한 액세스 권한을 부여받습니다. 이 리포지토리를 사용하여 userDetailsService는 해당 사용자 이름과 비밀번호를 보유한 고객을 식별한 후 해당 개인에 관한 모든 관련 세부 정보를 객체로 반환할 수 있습니다.
사용자의 로그인 정보가 성공적으로 인증되면 인증된 고객에게 시스템에 대한 액세스 권한이 부여됩니다. 응답이 잘못된 인증 시도를 나타내는 경우 웹 페이지가 자동으로 업데이트되어 사용자가 자격 증명을 다시 입력하고 시스템에 성공적으로 진입할 수 있는 기회를 제공합니다.
필터 체인
스프링 시큐리티의 보안필터체인 인터페이스는 스프링 시큐리티 구성에서 필수적인 역할을 하는 유용한 애플리케이션 프로그래밍 인터페이스(API)입니다. 이 인터페이스는 Spring Security의 HttpSecurity 클래스와 함께 작동하여 특정 HTTP 요청에 대한 필터 체인을 생성합니다.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/user").hasAuthority("USER").anyRequest().permitAll())
.formLogin(formLogin -> formLogin
.loginPage("/login").defaultSuccessUrl("/user", true))
.logout(logout -> logout.logoutSuccessUrl("/logout"));
return http.build();
}
SecurityFilterChain 인터페이스를 활용하여 filterChain 빈은 여러 가지 목표를 달성합니다. 특히, ‘USER’로 지정된 역할이 있는 고객에 대해서만 localhost:8080/user에 대한 액세스를 제한하는 HttpSecurity 클래스를 구현하여 권한 부여를 시행합니다. 이 제한은 새로 생성되는 모든 고객 객체에서 getAuthorities() 메서드를 구현함으로써 가능합니다.
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("USER"));
}
필터 체인을 사용하면 권한이 없는 사용자가 애플리케이션 내의 모든 URL에 제한 없이 액세스할 수 있습니다.