Spring

스프링 시큐리티

Stater 2019. 11. 20. 10:51

인증(Authentication)

- 인증을 통해 사용자를 식별

인가(Authorization)

- 인가를 통해 시스템 자원에 대한 접근을 통제

 

Ex) 사원증 ( 입구에서는 모두 사원증을 통해 입장(인증)-> 사무실, 제한된 구역에 따른 입장 할 수 있는 권한(인가)를 통해 관리

 

개인적으로 전에 적용했던 부분은 -> 세션을 통한 로그인 (HttpSession)

1. 세션을 체크

2. 로그인 성공 -> 관리자 권한만 게시글 삭제

 

3. 문제점 - 유지보수 과정중에 인증/인가 관련된 코드를 모든 클래스 메소드 마다 적용하면 유지보수가 어렵다.

             - 모든 사이트 내에 아무런 제약과 조건 없이 모두 접근이 가능해진다.

 

 

4. 해결점 - HttpSession을 통한 인증/인가 방법은 코드를 모든 클래스 메소드마다 적용하여 유지보수가 어려워진다.

               따라서, 스프링 시큐리티를 적용한다.

 

 

 

[ Springboot Security  dependency 추가 ]

<!-- security config 설정 -->
		<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
		<dependency>
		    <groupId>org.springframework.security</groupId>
		    <artifactId>spring-security-config</artifactId>
		    <version>5.1.7.RELEASE</version>
		</dependency>

[ Springboot Security  dependency 추가 된 후 자동으로 재시작 되면 아래와 같은 화면이 출력된다.]

 

Security 적용된 후 비밀번호가 출력된 화면

 

mvnrepository 사이트에서 추가

참조사이트 :

https://mvnrepository.com/artifact/org.springframework.security/spring-security-config/5.1.7.RELEASE

 

Maven Repository: org.springframework.security » spring-security-config » 5.1.7.RELEASE

org.springframework.security spring-security-config 5.1.7.RELEASE // https://mvnrepository.com/artifact/org.springframework.security/spring-security-config compile group: 'org.springframework.security', name: 'spring-security-config', version: '5.1.7.RELEA

mvnrepository.com

기본 아이디 : user

기본 비밀번호 : 위의 출력된 password를 입력하면 접근이 제한된 페이지로 접근이 가능하다.

 

별다른 설정 없이 기본적으로 Security를 적용하고 나면 아이디/패스워드를 통해서 제한 된 페이지를 제공한다.

 

SecurityConfig 클래스를 생성해서 WebSecurityConfigurerAdapter 클래스에서 configure()메소드를 통해서 시큐리티를 다양하게 재정의 해서 사용이 가능하다(커스터마이징 가능)

 

package com.rubypaper.config;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

	@Override
	protected void configure(HttpSecurity security) throws Exception{
		
	}
}

 configure() 메소드를 통해서 재정의 하여 커스터마이징이 가능하다.

위의 클래스 소스로 설정이 되면 강제적으로 로그인 해야 했던 부분이 사라진다.

 

package com.rubypaper.config;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

	@Override
	protected void configure(HttpSecurity security) throws Exception{
		
		security.authorizeRequests().antMatchers("/").permitAll();
		security.authorizeRequests().antMatchers("/member/**").authenticated();
		security.authorizeRequests().antMatchers("/manager/**").hasRole("MANAGER");
		security.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN");
		
		security.csrf().disable();
		//form태그기반의 로그인을 지원하는 설정
		security.formLogin();
	}
}

 

 스프링부트에서 제공하는 로그인 페이지 말고 사용자가 직접 만든 로그인 페이지를 연결하고 싶은 경우

 

security.formLogin().loginPage("/login").defaultSuccessUrl("/loginSuccess",true);

 

위의 소스 처럼 사용하면 된다.

loginPage() 메소드 역할 -> 로그인에 사용할 화면을 지정

defaultSuccessUrl() 메소드 역할 -> 로그인 성공한 경우 이동할 URL 작성

 

메모리를 통한 사용자 인증 방법 소스는 아래와 같다.

 

package com.rubypaper.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

	@Override
	protected void configure(HttpSecurity security) throws Exception{
		
		security.authorizeRequests().antMatchers("/").permitAll();
		security.authorizeRequests().antMatchers("/member/**").authenticated();
		security.authorizeRequests().antMatchers("/manager/**").hasRole("MANAGER");
		security.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN");
		
		security.csrf().disable();
		//form태그기반의 로그인을 지원하는 설정
//		security.formLogin();
		security.formLogin().loginPage("/login").defaultSuccessUrl("/loginSuccess",true);
	}
	
	//메모리를 통한 사용자 인증
	@Autowired
	public void authenticate(AuthenticationManagerBuilder auth) throws Exception{
		auth.inMemoryAuthentication()
		.withUser("manager")
		.password("{noop}manager123")
		.roles("MANAGER");
		
		auth.inMemoryAuthentication()
		.withUser("admin")
		.password("{noop}admin123")
		.roles("ADMIN");
	}
}

 

마지막 정리 

package com.rubypaper.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

	@Override
	protected void configure(HttpSecurity security) throws Exception{
		
		security.authorizeRequests().antMatchers("/").permitAll();
		security.authorizeRequests().antMatchers("/member/**").authenticated();
		security.authorizeRequests().antMatchers("/manager/**").hasRole("MANAGER");
		security.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN");
		
		security.csrf().disable();
		//form태그기반의 로그인을 지원하는 설정
//		security.formLogin();
		security.formLogin().loginPage("/login").defaultSuccessUrl("/loginSuccess",true);
		//Security - 권한이 없어서 해당 페이지를 볼수 없을 경우 페이지 이동할 떄 사용
		//인증되지 않은 사용자에게 제공할 URL을 사용 - accessDeniedPage()을 통해서 사용 
		security.exceptionHandling().accessDeniedPage("/accessDenied");
		
		//로그아웃 강제 관련 설정
		//쿠기 정보 삭제- deleteCookies() 메소드를 뒤에 추가로 사용
		//logoutSuccessUrl("/login") 로그아웃 후에 이동할 화면 설정 가능 
		security.logout().invalidateHttpSession(true).logoutSuccessUrl("/login");
	}
	
	//메모리를 통한 사용자 인증
	@Autowired
	public void authenticate(AuthenticationManagerBuilder auth) throws Exception{
		auth.inMemoryAuthentication()
		.withUser("manager")
		.password("{noop}manager123")
		.roles("MANAGER");
		
		auth.inMemoryAuthentication()
		.withUser("admin")
		.password("{noop}admin123")
		.roles("ADMIN");
	}
}

 

 

{noop}의미

- 암호에 NoOpPasswordEncoder를 사용하겠다는 의미로 접두사 {noop} 를 붙인다.

- 참조 사이트 : https://thecodinglog.github.io/spring/security/2018/06/07/spring-security-3.html

반응형

'Spring' 카테고리의 다른 글

스프링 특징  (0) 2020.02.03
Spring Security 관련 참고사항  (0) 2019.11.22
Springboot Thymeleaf 적용방법  (0) 2019.11.18
Springboot JPA 쿼리메소드 사용하기  (0) 2019.11.17
springboot JPA Annotation 정리  (0) 2019.11.16