1. Spring Security Dependency 추가

 

gradle

dependencies { implementation "org.springframework.boot:spring-boot-starter-security" }

maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.6.1</version>
</dependency>

 

 

2. Security패키지를 생성하고, 안에 SecurityConfig클래스를 추가한다.

: SecurityConfig클래스는 WebSecurityConfigureAdapter를 상속받는다.

 

기본 설정이 된 SecurityConfig클래스의 코드는 아래와 같다.

@Configuration // 설정을 위한 어노테이션
@EnableWebSecurity // 스프링 시큐리티 사용을 위한 어노테이션
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationProvider authenticationProvider;

    @Override
    public void configure(HttpSecurity http) throws Exception { // Security 기본 설정
        http.authorizeRequests()
                .antMatchers("/css/**", "/js/**", "/img/**", "/favicon.ico").permitAll() // resource들은 권한 없이 접근 가능하다.
                .antMatchers("/").hasRole("USER")
                .anyRequest().authenticated();

        http.formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/authenticate") // login페이지 form의 action과 값이 같아야한다.
                .usernameParameter("userId")
                .passwordParameter("password")
                .defaultSuccessUrl("/")
                .failureUrl("/login?error")
                .permitAll();

        http.logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login");

        http.sessionManagement()
                .maximumSessions(1)
                .maxSessionsPreventsLogin(false); // 먼저 접속한 사용자를 로그아웃 시킨다.
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider);
    }
}

스프링 시큐리티에서는 자동적으로 CSRF 보호가 실행되기 때문에,
당장 관련 설정을 하지 않는다면 csrf.disable()을 설정해 CSRF보호를 꺼 놓아야 개발하기 편하다. (위 코드엔 없다)

만약 보호를 꺼 놓지 않는다면 스프링 시큐리티가 CSRF로부터 보호를 시작하기 때문에 정상적으로 작동시키려면
서버에서 토큰을 발행하고 클라이언트 측에서도 서버에 요청할 때에 CSRF토큰을 포함해서 보내야 하기 때문이다.

 

 

3. SecurityConfig클래스에서 호출한 authenticationProvider인터페이스를 상속받아 클래스를 작성한다.

@Component
public class UserAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private AuthService authService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String userId = authentication.getName();
        String password = authentication.getCredentials().toString();
        return authService.authenticate(userId, password);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }
}

Authentication은 세션 정보를 저장해놓는 컨텍스트이다.

클래스 안에는 Principal(아이디), Authority(권한), Credential(패스워드)이 있고,

 

사용자가 화면을 열면 > 스프링 시큐리티가 UserAuthenticcationProvider을 열어서 아이디 패스워드값을 Authentication컨텍스트에 저장 > 서비스 클래스로 가서 DB검증하고, 패스워드 값 맞춰서 보낼 정보 중 민감한 정보는 지우고, 권한 부여하고(DB에 기록되어 있는) > 접근을 허용하는 방식으로 진행된다.

 

Spring Security는 Filter 기반으로 운용되고, SpringMVC와는 독립적으로 동작한다는걸 알면 이해하기 수월하다.

 

 

4. 인증을 위한 서비스 클래스를 만들어준다.

@Service
public class AuthService {

    @Autowired
    private UserMapper userMapper;

    public Authentication authenticate(String userId, String password) {
        UserVo userVo = userMapper.getUser(userId);
        if (userVo != null) {
            if (userVo.getPassword().equals(password)) { 
                userVo.setPassword(null); // 보안을 위해 확인이 끝나면 삭제한다.
                List<SimpleGrantedAuthority> authorities = new ArrayList<>();
                authorities.add(new SimpleGrantedAuthority(userVo.getRole()));  
                return new UsernamePasswordAuthenticationToken(userVo, null, authorities);
            }
        }

        throw new BadCredentialsException("No such user.");
    }

 

 

 

 

'Java > SpringBoot' 카테고리의 다른 글

Spring boot : Mustache 사용시 한글 인코딩 설정  (0) 2024.03.11
Spring Security CSRF 설정  (0) 2021.12.09
Logback 기본 설정  (0) 2021.12.07

어노테이션이란?

JDK1.5 이상에서 사용할 수 있으며, @로 시작한다.
어노테이션을 클래스나 메서드 위에다가 쓰면 그에 해당하는 역할을 부여할 수 있다.
 
예를 들어보면 자바에서 인터페이스를 만들어서 상속할 때, @Override 를 쓴다.
애너테이션 Override는 부모 클래스의 기능을 자식 클래스에서 재정의 하는 것을 말한다.
그러므로 @Override가 붙은 메서드는 상속받은 메서드가 된다.
 
 
사진은 MemberDAOImpl클래스가 implements로 인터페이스 MemberDAO를 상속받고,
메서드 마다 @Override를 붙여 메서드를 재정의 하게 된다.
 
이런식으로 애너테이션이 붙으면 특별한 의미가 생기게 된다.
 
 
 

스프링에서 자주 쓰는 어노테이션

 

@Service

: 서비스 클래스라는 의미(비즈니스 로직을 수행)

 

@Controller
: 컨트롤러 클래스라는 의미
 
@RequestMapping
: 컨트롤러의 url매핑을 하는 역할
 
@Component
: 빈(VO)의 역할을 부여하기 위해 사용, 싱글톤에 사용
 
@Autowired
: 필드, 생성자, Setter에 붙인다.
인스턴스를 알아서 주입시켜주는 어노테이션 (객체의 타입으로 주입할 인스턴스를 판단)

 

 
 
 
 
 
~ 추가 / 수정 중 ~
 
 

참고 문헌

< Logging 프레임워크 >

1. log4j

: 개발 중단, 최근 보안 이슈로 사용하지 않는 게 낫다... 

 

참고 : 보안뉴스 권준 '거의 모든 서버가 위험하다! 매우 치명적인 '로그4j'보안 취약점 발견'

https://www.boannews.com/media/view.asp?idx=103257

 

2. logback

: slf4j의 구현체. 스프링부트에서는 기본으로 설정되어 있다.

 

 

< 로그의 레벨 >

1. Error : 빠른 조치가 필요한 단계
2. Warn : 로직상 유효성 확인, 예상가능한 문제로 인한 예외처리, 운영엔 문제없음
3. Info : 참고할 만한 사항
------------------------------------------------
4. debug : 개발단계에서 사용. sql 로깅 가능
5. trace : 모든 레벨에 대한 로깅이 추적된다.

 

 

< logback-spring.xml >

<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="60 seconds">
    <property name="LOG_DIR" value="log"/>
    <property name="LOG_PATH_NAME" value="${LOG_DIR}/data.log" />
    
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <charset>UTF-8</charset>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSSS} [%12t] %-5level %logger{5} - %msg %n</pattern>
        </encoder>
    </appender>

    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <charset>UTF-8</charset>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSSS} [%12t] %-5level %logger{5} - %msg %n</pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>C:\logs\%d{yyyy-MM-dd}_log.log</FileNamePattern>
            <MaxHistory>365</MaxHistory>
        </rollingPolicy>
    </appender>

    <root level="info">
        <appender-ref ref="console" />
        <appender-ref ref="file" />
    </root>
</configuration>

내가 쓰는 logback-spring.xml 포맷이다.

 

로그의 경우 아래와 같이 application.properties에서도 설정이 가능하지만,

logging.level.root=debug
logging.level.com.springboottest.controller=info
logging.path=c:/logs/
logging.file=c:/logs/my.log
logging.config=classpath:/logback.logback.xml

스프링부트는 classpath에 logback-spring.xml이 있으면 알아서 읽기 때문에

상세 설정을 위해 xml파일을 만들어 따로 분리해 두는게 편리하다.

 

스프링부트는 logback-spring.xml이라는 파일이 없다면 properties.yml파일을 읽는다.

우선순위는 .yml > .xml 이다.

 

'Java > SpringBoot' 카테고리의 다른 글

Spring boot : Mustache 사용시 한글 인코딩 설정  (0) 2024.03.11
Spring Security CSRF 설정  (0) 2021.12.09
Spring Security 기본 설정  (0) 2021.12.08
스프링으로 짜여진 기존 코드를 수정하다가 에러를 만나게 되었다.
 
 
에러문
 
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/tx]
Offending resource: ServletContext resource [/WEB-INF/spring/appServlet/servlet-context.xml]
 

 

해결법은 구글링해보니 바로 나왔다.
 
pom.xml에 
 
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>4.1.0.RELEASE</version>
</dependency>
 
작성 후 해결...
 
라이브러리를 다운로드 하지 않아서 생긴 문제였다.

'Java > Spring' 카테고리의 다른 글

Spring Annotation  (0) 2021.12.08

+ Recent posts