SSH 프로토콜은 22번 포트를 사용한다.

SSH프로토콜은 암호화된 터널을 통해 데이터가 전송되는 방식다.

원격지 호스트 컴퓨터에 접속하기 위해 사용된다. 이렇게 되면 우분투 서버를 켜 놓기만 하면 다른 곳에서 접속이 가능하게 된다.

<조건은 우분투 서버의 네트워크(아이피) 설정이 되어 있어야 한다. 외부에서도 접속가능하게 설정 되어 있어야한다.

  이 부분을 공부하려면 포트포워딩을 공부해야 한다>

 

우분투에 원격 접속이 되도록 서버를 구축하자.

우분투 서버는 : ssh서버를 구축

내컴퓨터는 원격 접속을 위한 putty를 설치한다.

https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html

 

Download PuTTY: latest release (0.83)

This page contains download links for the latest released version of PuTTY. Currently this is 0.83, released on 2025-02-08. When new releases come out, this page will update to contain the latest, so this is a good page to bookmark or link to. Alternativel

www.chiark.greenend.org.uk

 

윈도우를 사용하고 있어서 위에서 표시한 파일로 다운로드 받았다.

다음 다음 예 다음 누르다 보면 설치가 완료 된다

 

시작버튼을 누르고 설치된 프로그램을 찾아 본다

동그라미 친 아이콘을 실행한다.

 

동그라미로 표신된 곳에 접속할 서버의 ip를 입력하는 곳이다.

그 옆에 포트번호 22는 수정할 필요 없다. 포트 번호 22는 CS개념으로 암기하고 있는 것이 좋다.

우분투리눅스가 서버가 된다.

우분투리눅스 아이피를 찍어보자

172.30.1.19 이다.  이것은 컴퓨터 마다 다를 수 있다. 아마 거의 다를 것이다.

우선 통신의 기본 ping 명령어로 대상 컴퓨터와 통신이 가능한 상태인지 살펴보자

TTL이 나오는 거니 통신이 가능하다.

이젠,

서버의 아이피를 확인 했으니 putty의 설정은 다음과 같다.

Open을 해도 열리지 않을 것이다. 다음과 같은 그림이 나온다.

이유는 아직 우분투가 서버역활을 하지 못하기 때문이다.

 

이제 우분투 리눅스에 ssh서버를 구축해 보자

우분투에서 터미널을 실행한다.

그리고 먼저는 apt 명령어를 업데이트 한다.

그리고 ssh서버를 설치한다.

 

설치를 하면 ssh프로그램이 자동으로 실행된다. 즉, 서버가 실행된다는 이야기 이다.

그럼 클라이언트에서 접속해 본다. 

putty를 실행하고 

서버의 아이피를 입력하고 Open

아직도 막혀있다.  

이유는 크게 2가지이다.

첫번째는 ssh서버가 실행되지 않았을 경우이다. 위에서 자동으로 실행된다고 하였는데

그래도 한 번확인해 보자. 명령어는 다음 그림에 있다.  systemctl status ssh   > active를 확인할 수 있다. 정상이다.

 

포트도 열려 있는지 확인해보자.

위에서 다룬 내용중에 22번이 있었을 것이다. 그게 포트번호이다. 포트 번호도 열려 있다.

 

이제 방확벽을 확인해보자.

우분투에는 기본방화벽인 ufw가 설치되어 있다.

 

방화벽일 활성화 되어 있다.

일단 방화벽을 비활성화 시키고 putty접속이 가능한지 확인해 본다.

 

putty로 접속해본다



접속이 성공된 화면이다 accept를 클릭하면 아래와 같이 로그인 화면이 나온다.

아이디와 비번을 입력하면

이런 글자가 나온다.. sss는 아이디 주소 뒤에 sss-server는 설치 할 때 입력한 컴퓨터 이름, 전문용어로 hostname이라고 한다.

 

아래 그림은 로그인 후 테스트로 ifconfig를 입력한 것이다.

 

비교를 위해 우분투 서버 터미널에서 실행 된 화면과 비교해 보자

 

sss@sss-server 똑같다

주소도 똑같다.

 

그런데. 원격 접속을 위해 ssh 암호화된 프로토콜을 사용하는데 서버의 방화벽을 비활성화 하는게 

말이 되는가?

지금 까지는 테스트를 위한 것이고 

리눅스 서버의 방화벽은 활성화 시키고, 포트만 방화벽에서 허용하도록 한다.. < 이렇게 해야 한다. 

 

우선, 방화벽을 활성화 시키자

 

그리고, ssh를 방화벽에서 허용시키자

 

명령어는 간단하지만, 개념과 이론을 같이 정리해 두는 것이 중요하다.

이제 접속해 보자

정상적으로 접속이 된다

 

 

이젠, putty만 있으면 원격 서버에 접속해서 사용할 수 있다..

리눅스 공부는 윈도우같은 환경이 아닌, CLI환경에서 공부하는 것을 추천한다.

 

그런데 문제가 하나 있다.

지금은 ssh 서비스가 실행중인데.

리눅스 서버를 재부팅하면 자동 실행되지 않는다.

윈도우의 시작프로그램 같이,

리눅스에서도 ssh서버 서비스를 시작프로그램에 등록해야 한다. 

systemctl 명령어를 이용한다. 

 

리눅스를 종료한다.

 

리눅스를 다시 실행한다

그리고 ssh의 상태를 확인한다.

실행되고 있다.

 

먼저 우분투에서 받아 오는 ip를 찍어본다.

 

명령어는 ifconfig

ifconfig명령어가 없어서 설치해야 한다.

sudo 루트권한을 빌린다

apt 는 패키지 명령어

install 설치하는 명령어

install 뒤에 오는 단어는 패키지 명

 

sudp apt install net-tools를 입력하면 명령어가 포함된 패키지가 설치 된다.

ifconfig명령어가 실행된다.

동그라미 친 부분은 컴퓨터 마다 이름이 다를 수 있다. 그 뒤에 밑줄 친 곳 10.0.2.15가 아이피 주소이다. 

 

virtualbox를 설치한 컴퓨터와 우분투간의 네트워크를 NAT로 설정하면 다음과 같은 구조가 된다

virtualbox를 설치한 컴퓨터, 위 그림에서는 내컴퓨터가 연결된 인터넷 주소는 172.30.1.15   <컴퓨터 마다 다 다름>

우분투 리눅스가 설치된 가상컴퓨터는  10.0.2.15, 위 그림에서는 오른쪽 밑줄 <컴퓨터 마다 다 다름>

여기서 중요한 것은 virtualbox를 설치한 컴퓨터 172로 시작되고 우분투는 10으로 시작되어 서로 다른 네크워크가 형성된다.

 

이번에는 NAT가 아닌 브리지 모드로 설정해 본다.

설정하는 방법은 다음과 같다

확인을 누르고  우분투에서 다시 아이피를 찍어본다

주소가 172로 시작된 것을 알 수 있다.

브리지 모드로 설정했을 경우 구조는 다음과 같다.

네모친 곳을 보면 172.30으로 값이 같다. 이렇게 되면 내컴퓨터와 가상머신 우분투가 설치된 컴퓨터는 같은 네트워크 상에 있게 된다.

 

만약, 같은 네트워크라면 공유폴더로 접근이 가능하지만 다른 네트워크라면 ftp로 파일을 전송해야 한다.

 

현재는 윈도우와 리눅스가 각각 설치되어서 공유폴더도 의미는 없다. 만약 윈도우와 윈도우라면 공유폴더로 접근이 가능하다.

 

지금까지의 내용은 네트워크 환경에 대한 이해였다.

알고 있으면 좋은 내용인 것은 맞다.

 

리눅스를 공부 하기 위해서는 ifconfig명령어로 네트워크 주소만 볼 수 있어도 된다.

즉, 리눅스 공부를 한다면 nat 모드나 브리지 모드 어떤 것을 사용해도 상관이 없다..

 

들어 본 것만으로 중요하기에 잠깐 다루어 봤다.

 

기록은 어댑터에브리지로 설정하고 남긴다

 

우분투에서는 root권한이 최고 권한이다.

프로그램을 설치 하거나 명령어를 실행 할 때는 root권한이 필요한 경우가 있다.

 

우분투를 처름 설치하면 root 비밀번호가 없다.

그래서, root비밀번호를 설정해 준다.

 

우선, 터미널을 실행한다.

실행하는 방법은 바탕화면에서 마우스 우클릭 후 터미널로 열기를 클릭한다.

 

위 그림에서 현재 사용자는 sss이다.

현재 사용자가 sudo 루트권한을 잠시 빌리는 것이다.

passwd 명령어는 패스워드를 변경한다는 뜻이고 뒤에 오는 문자는 아이디를 의미한다.

즉, 루트권한을 빌려서 패스워드 명령어를 실행하는데 패스워드를 변경할 아이디는 root라는 의미이다.

 

신규비밀번호와 재입력을 같은 비밀번호를 입력하고 성공적이라는 메시지가 뜨면 성공한 것이다. 

 

 

필요한 프로그램 

- virtual box 

- 우분투 22.05  - 우분투 홈페이지에서 다운로드 받는다. 바로가기 https://releases.ubuntu.com/22.04/

 

Ubuntu 22.04.5 LTS (Jammy Jellyfish)

Select an image Ubuntu is distributed on three types of images described below. Desktop image The desktop image allows you to try Ubuntu without changing your computer at all, and at your option to install it permanently later. This type of image is what m

releases.ubuntu.com

 

먼저 vitual box를 설치하고 실행합니다.

 

새로만들기 버튼을 클립합니다.

 

- 이름은 컴퓨터 이름입니다. 임의대로 지정하면 됩니다.

- 폴더는 우분투를 설치할 위치입니다. 기본값으로 해도 됩니다. 별도의 디렉토리에 생성하고자 한다면

  원하는 폴더를 만들고 지정하면 됩니다.

- ISO 이미지는 우분투 22.08 이미지로 지정하였습니다. < 위 예제는 우분투 중 데스크탑 iso를 선택함>

- 설치 과정을 살펴보기 위해서 무인설치 건너뛰기를 선택했습니다. 

- 마지막으로 다음 버튼을 클릭합니다.

 

- 메모리는 4GB를 지정하였습니다. 2GB를 해도 공부하는데는 지장이 없습니다.

- CPU(프로세서)는 2개로 지정하였습니다. 1개를 지정해도 공부하는 데는 지장이 없습니다.

  ** 메모리와 프로세서 설정은 나중에 변경이 가능합니다. 사용하다가 속도가 느리면 수정할 수 있습니다. 

- 하드 디스크를 설정하는 화면입니다. 적당히 80GB를 설정합니다. 최소 용량은 15GB입니다.

- 다음 버튼을 누르면 지금까지 설정을 요약해서 확인 가능합니다.

- 지금까지 설정한 내용의 요약입니다. 한 번 더 확인합니다. 확인이 되었으면 완료 버튼을 누릅니다.

- 가상컴퓨터가 만들어 졌습니다.

- IDE 세컨더리 장치 0 부분이 광디스크를 의미하고, 운영체제 파일이 연결되었습니다.  그냥 확인만 하면 됩니다. 

-

부팅할 머신을 선택하고, 머신이라고 부릅니다. 시작 버튼을 누르면 컴퓨터가 켜 지는데, 처음 켜는 것이라서 설치 화면이 나옵니다.

 

< 혹시나 에러가 난다면 메인보드 설정에서 가상화를 지원 할 수 있도록 설정해야 합니다>

< 다음과 같은 에러를 참조하세요>

 

<메인보드에서 가상화 설정의 화면입니다. 메인보드 설정으로 진입하셔서 어드밴스 가시면 거의 있습니다.

  저는 AMD를 사용하는데 AMD는 메뉴가  SVM입니다>

이제 다시 virtualbox를 실행해 보겠습니다.

 

정상적으로 실행되고 있습니다.

이제 본격적으로 우분투22를 설치합니다.

엔터를 치거나 그냥 두시면 자동으로 다음 화면으로 넘어 갑니다.

계속 기다리면 다음과 같은 화면이 나옵니다.

 

한국어를 선택하고 ubuntu설치를 클릭합니다.

 

기본값을 그냥 두고 계속하기를 클릭합니다.

이때, 계속하기가 나오지 않은 경우가 있습니다. . 이 부분은 VGA카드 때문에 발생하는 이슈입니다..

 

계속하기 버튼을 누르면 다음과 같은 화면이 나옵니다.

계속하기 버튼 을 클릭합니다.

지금 설치를 클릭합니다.

계속하기를 클릭 합니다.

 

이름은 컴퓨터를 사용하기 위한 아이디입니다. 

컴퓨터 이름은 지금 설치하는 리눅스 컴퓨터 이름입니다.

사용자이름은 사용자 이름입니다.

암호도 입력하시고

자동으로 로그인을 선택하면 리눅스가 부팅될때 메인화면이 나오고

로그인할 때 암호 입력을 선택하면 로그인시 암호를 요청하는데 대게 2번째를 많이 사용합니다. 

 

설치중입니다. 기다리시면 됩니다.

 

지금 다시 시작을 클릭하면 재부팅이 됩니다.

위와 같은 화면이 나오면 엔터를 한 번 쳐 주세요

로그인시 암호를 사용하기로 설정해서 사용자를 선택하게 되어 있네요.

사용자를 선택하고 암호를 입력하면 됩니다.

 

정상적으로 설치가 되었습니다.

위와 같은 화면은 건너뛰기 하시면 됩니다.

업그레이드 화면인데.. 그냥 하지 않겠습니다. 다음을 클릭하세요

이 부분도 기본값을 두고 다음 버튼을 클릭하겠습니다.

 

테스트로 네이버에 접속해 볼께요

왼쪽 상단의 Firefox 아이콘(아래 그림의 v 표시된)을 실행하고 주소창에 네이버를 입력합니다.

 ** 웹브라우저는 윈도우는 엣지나 익스플로러를 사용하고, 리눅스는 파이어폭스를 사용합니다. 크롬은 둘다 지원이 됩니다.

 

우분투 리눅스를 종료하는 법은 다음과 같습니다.

@Service
public class MyUserDetailsService implements UserDetailsService {
	@Autowired
	private IF_MemberDao memberdao;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// TODO Auto-generated method stub
		try {
			MemberVO member = memberdao.selectOne(username);
		    return User.builder().username(member.getId()).password(member.getPass()).roles(member.getRole()).build();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

}

 

 

return User.builder().username(member.getId()).password(member.getPass()).roles(member.getRole()).build();

이코드에서 

다음부분을

roles(member.getRole())

다음과 같이 수저한다.

roles(member.getRole(),"ADMIN")

 

이번에는

사용자 로그인시

실제 데이터 베이스에 저장된 값으로 로그인을 하도록 커스터 마이징을 합니다.

 

데이터베이스는 오라클을 

퍼시스턴스 프레임워크는 mybatis를 사용하고 있습니다.

 


데이터 베이스를 먼저 살펴보겠습니다.

 

테이블 구조입니다.

 

 

튜플입니다. 튜플을 보면 ROLE이라는 권한이 저장 되어 있습니다. 이 글에는 저장되어 있는 경우와

저장되어 있지 않은 경우(즉, 컬럼이 없는 경우)도 기록해 놓았습니다.

 

또 튜플을 보면 비밀번호가 암호화 되어 있습니다. 이 글에는 저장된 비밀번호가 평문일 경우도

해결하는 방법도 기록이 되어 있습니다. 


 

 

 

먼저 Spring Security 에서 이해해야 할 인터페이스가 있습니다. 

이전에 언급한 UserDetailsService입니다. 


 UserDetailsService   - 아이디로 디비 조회 후 사용자 정보 리턴(체크, 아이디만 가지고 디비 조회)
       - 주요설정 -
        a. 서비스 로직을 통해 아이디 디비 조회
        b. 사용자정보 리턴  -  리턴시 User객체를 builder, 또는 User객체를 커스트마이징 한 객체 타입으로 리턴

 

UserDetailService는 구현받은 클래스를 객체로 만드는 설정만 있다면 정상적으로 시큐리티가 알아서 동작시켜준다.

구현받은 클래스 작업외에는 설정하지 않을 것이다. @Service 어노테이션으로 객체로 생성되도록 처리한다.

@Service
public class MyUserDetailsService implements UserDetailsService {

 


먼저 UserDetailService로 완성 된 소스를 살표 보겠습니다.


@Service
public class MyUserDetailsService implements UserDetailsService {
	@Autowired
	private IF_MemberDao memberdao;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// TODO Auto-generated method stub
		try {
			MemberVO member = memberdao.selectOne(username);
		    return User.builder().username(member.getId()).password(member.getPass()).roles(member.getRole()).build();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

}

 

디비를 조회할 객체가 필요합니다. < 이 부분은 미리 데이터베이스 작업이 필요합니다 >

@Autowired

private  IF_MemberDao memberdao;

 

UserDetailsService  인터페이스가 실행되면 자동으로 loadUserByUsername(String username) 메서드가 실행되고

메서드는 UserDetails 타입을 리턴하게 됩니다. 

소스를 보겠습니다.

 

MemberVO member = memberdao.selectOne(username);
이 코드에서 username은 클라이언트가 보낸  username을 스프링 시큐리티가 저장한 변수입니다.
즉, 클라이언트가 보낸 username으로 데이터베이스를 조회합니다. 
return User.builder().username(member.getId()).password(member.getPass()).roles(member.getRole()).build();
이 코드는 리턴하는 코드입니다.
loadUserByUsername 메서드는 UserDetails(인터페이스) 타입을 리턴하게 되어 있습니다.
코드는 User 객체 (import org.springframework.security.core.userdetails.User;)를 리턴합니다.
User 디테일은 스프링시큐리티에서 제공하는 객체이고  Userdetails 인터페이스를 상속 받은 것입니다.

User 객체로 리턴한다는 것을 이해했으니
세부적으로 User 객체의 값을 셋팅하는 부분을 살펴 봅니다. 
usename(디비에서검색한 결과의 아이디),
password(디비에서 검색한 결과의 암호),
role(디비에서 저장된 회원의  Role)으로 user객체를  builder합니다.

이렇게 하면
자동으로 
클라이언트가 입력한 비밀번호와
디비에서 조회한 비밀번호의 일치 여부를 판단하여 최종 인가가 완료 됩니다.


주의점
UserDetails에서 인식하는 비밀번호는 반드시 암호화가 되어 있어야 합니다.
그래서 데이터 베이스에 저장할 때 암호화 시켜야 하는 것이 좋습니다.

만약, 데이터베이스에 저장된 암호가 평문일 때는 
User.builder().username(member.getId()).password(member.getPass()).roles(member.getRole()).build();
이 코드에서 password(member.getPass()를 암호화 작업함)를 빌드 하기 전 암호화 작업을 합니다.

 

 

User.builder().username(member.getId()).password(member.getPass()).roles(member.getRole()).build();

에서 암호화 하는 방법도 설명해 봅니다.

먼저, 스프링에서 제공하는 암호 객체를 사용하기 위해 bean을 등록합니다.

 

 

 

이렇게 빈을 등록하면 필요한 곳에서 주입 받아서 쓰면 됩니다.

지금 필요한 곳은 UserDetails 이니 MyUserDetailsService 에서 작업해 봅니다. 

 

 

@Service
public class MyUserDetailsService implements UserDetailsService {
	
	@Autowired
	private PasswordEncoder passwordEncoder;
    
	@Autowired
	private IF_MemberDao memberdao;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// TODO Auto-generated method stub
		try {
			MemberVO member = memberdao.selectOne(username);
			String passwordEncoding = passwordEncoder.encode(member.getPass());
			return User.builder().username(member.getId()).password(passwordEncoding).roles(member.getRole()).build();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

 

코드를 살펴 보겠습니다

@Autowired
private PasswordEncoder passwordEncoder;

SecurityConfig 에서 설정한 Bean의 주소를 주입 받습니다.
String passwordEncoding = passwordEncoder.encode(member.getPass());
디비에서 조회한 password를 암호화 합니다.


return User.builder().username(member.getId()).password(passwordEncoding).roles(member.getRole()).build();
암호화된 passwordEncoding  변수를 리턴할 때 사용합니다,

참고,
member.getRole(), 즉 멤버의 ROLE 이 데이터 베이스에 없을 경우 
문자열로 직접 기입하되 됩니다.. 예) roles("USER")

 

* 이번장에서는 스프링 시큐리티에서 제공하는 로그인 화면이 아닌

   개발자가 직접 만들 로그인 화면으로 커스터마이징을 할 것이다.

   이때, 로그인 화면의 변경과 같이 클라이언트가 파라미터로 전송하는 아이디와 패스워드도 저장 할 것이다 **

 

 

IDE : STS4 - Spring Tool Suite-4

 

** 개발환경

spring boot 3.3.5

spring security 6.0

oracle 11g

mybatis

gradle

 

-


spring security작업에 앞서

login view와 컨트롤러 작업을 먼저 한다.

 

login.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>Login</h2>
	<form action="login" method="post">
		ID<input type="text" name="username">
		pw<input type="password" name="password">
		<input type="submit" value="login">
	</form>
</body>
</html>

 

login url 처리 추가 (컨트롤러)

 

<확인> 서버를 재시작하고 http://www.localhost:8080/login 이라고 입력해 본다. 

결과 : 막혀있을 것이다.. 이유는 spring scurity의 인가정책에서 거부 되어 있을 것이다. 이 부분을 다음과 같이 수정한다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
	@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http	.csrf((csrfConfig) -> csrfConfig.disable())
                .authorizeHttpRequests(auth -> auth
                         .requestMatchers("/","/login").permitAll()
                         .requestMatchers("/freeboard*").hasRole("USER")
                         .anyRequest().authenticated() 
                )
                ;  
        return http.build();
    }	

}

 

이제 정상적으로 로그인 화면이 보여진다.

 

 


login 관련 Spring security를 작성하자

 

SecurityFilterChain 에 로그인관련 설정을 한다. 

 

<Check>

1. usernameParameter("username")  username은 클라이언트가 넘겨 주는 아이디를 저장하고 있는 변수이다.

2. passwordParameter("password")  password는 클라이언트가 넘겨 주는 비밀번호 변수이다.

3. loginPage("/login")  인가받지 않은 사용자에게 login url로 이동하게 하는 것. 즉, 인가 받지 않은 url인 경우 자동으로 

                                     login url로 이동하고 컨트롤러는 해당 뷰로 응답한다.

4. defaultSuccessUrl("/") 로그인 성공시 이동하려는 url 정의

5. failureForwardUrl("/login") 로그인 실패시 이동하려는 url정의

  login.html 과 securityFilterChain과 비교  - 서로 일치해야 한다.
                                                                        - Spring security 내부에서는 username과 password 변수로 인식 됨
                                                                        -  이런 이유로 html파일부터 변수명을 같게 코딩 함
 

 

@Configuration
@EnableWebSecurity
public class SecurityConfig {
	@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http	.csrf((csrfConfig) -> csrfConfig.disable())
                .authorizeHttpRequests(auth -> auth
                         .requestMatchers("/","/login").permitAll()
                         .requestMatchers("/freeboard*").hasRole("USER")
                         .anyRequest().authenticated() 
                )
                .formLogin(formLogin->formLogin     
                        .loginPage("/login")        // 로그인 url
                        .defaultSuccessUrl("/")     // 성동하면 이동할 url
                        .usernameParameter("username")  //  클라이언트가 넘겨 주는 아이디 변수값
                        .passwordParameter("password")  //  클라이언트가 넘겨 주는 비밀번호 변수값
                        .failureForwardUrl("/login") // 인증 실패시 이동할 url
                )
                ;  
        return http.build();
    }	

}

 

 

 정상 작동하는지 테스트 해 보자. 

테스트 url 결과 설명
http://www.localhost8080/ home.html 나옴 인가 정책에서   permitAll
http://www.localhost8080/freeboard login.html 나옴 인가가 되어 있지 않아서 
loginPage("/login") 설정에 의해
로그인 화면이 나옴
http://www.localhost8080/login login.html 나옴 인가 정책에서   permitAll

 

 

> 위 테스트 내역 중 2번째 테스트를 실행해 보겠습니다.

 

이렇게 입력하면 아래와 같이 이동한다.

 

 

 

 

 

 

 

 

 

ID는 user 

PW는 암호를 입력해보자

이제는 로그인 창이 아닌 다음과 같은 창이 나올 것이다.  정상이다.. 이유는 로그인은 성공했으나 freeboard는 USER권한 자만 가능하다.. 즉 아직 권한을 부여 받지 않은 상태이므로 아직까지는 접근할 수 없다. 

 

 

더 정확하게 테스트를 하기 위해서

컨트롤러에 url 매핑을 추가하고 뷰를 하나더 만들어 보자

 

study.html도 만들어 보자

 

 

다시 테스트 해 보자

테스트 url 결과 설명
http://www.localhost8080/ home.html 나옴 인가 정책에서   permitAll
http://www.localhost8080/freeboard
로그인은 되었으나 USER권한이 없음
http://www.localhost8080/login login.html 나옴 인가 정책에서   permitAll
http://www.localhost8080/study study.html 나옴 인가정책에서
anyRequest().authenticated()

 

 

다음에는 인증과 권한 부여를 실제 데이터베이스에서 조회하는 방법으로 커스터마이징을 할 것이다.

 

~~

IDE : STS4 - Spring Tool Suite-4

 

** 개발환경

spring boot 3.3.5

spring security 6.0

oracle 11g

mybatis

gradle

 

Spring Security 이해 맟 암기.

* 다음 내용은 이해도 중요하지만 암기가 맞다. 암기해야 한다. 

 먼저, Spring security에서 사용하는 객체를 이해한다.
  1. SecurityFilterChain 
       - 주요설정 -
        a. csrf 설정                               - csrf기능을 비활성화 또는 사용과 관련된 설정, (이번장에서는 비활성화)
        b. authorizeHttpRequests        - url 요청에 따른 인가정책 
        c. formLogin                             - 클라이언트가 로그인 요청시 파라미터 값 받기등 부가작업
        d. logout                                   - 클라이언트가 로그아웃 요청시 처리
        e. userDetailsService (생략가능)  - 아이디로 디비 조회 후 사용자 정보 리턴(User 또는 User객체를 커스터마이징한 객체)
  2. UserDetailsService   - 아이디로 디비 조회 후 사용자 정보 리턴(체크, 아이디만 가지고 디비 조회)
       - 주요설정 -
        a. 서비스 로직을 통해 아이디 디비 조회
        b. 사용자정보 리턴  -  리턴시 User객체를 builder, 또는 User객체를 커스트마이징 한 객체 타입으로 리턴

  3. AuthenticationProvider - 사용자 정보가 리턴되면 자동으로 클라이언트가 입력한 암호와 디비 조회에서 가져온
                                             암호를 비교 함. 이때 둘 다 암호화 되어있어야 함.
       특징 : 커스트마이징 하지 않아도 자동
       - 주요설정 -
        a. 클라이언트가 전송한 아이디와 비번을 저장하는 객체
        b. 디비 조회로 가져온 객체의 정보
        c. a와 b의 암호가 같은지 판단 (아이디는 이미 userDetailsService에서 조회 함)
        d. 권한부여... -여기서 부여하는 권한은  1번 SecurityFilterChain의 b. authorizeHttpRequests 의 정책에 적용된다.
  

 

그럼,

1.  SecurityFilterChain 작업을 시작해 보자. 

가. package만들기 






나. SecurityFilterChain class만들기 (클래스명은 SecurityConfig로 한다.)   * 어노테이션은 spring security 설정이라는 의미
   



다.  csrf와 authorizeHttpRequests 의 설정을 먼저 한다. 
     --------------------------------------------------------
    - 주요설정 -
        a. csrf 설정                               -  비활성화
        b. authorizeHttpRequests        - / 요청은 모두 허용, freeboard로 시작하는 요청은 USER권한만 가능, 그외 요청은 허가 
                                                             받은 유저만 가능
     --------------------------------------------------------
 

 

2. 위에서 설정한 작업이 정상인지 확인해 보자

서버를 재시작한다. 

브라우저 창에  다음 순서로 입력한다.

url 주소 결과 설명
http://www.localhost:8080        home.html 문서가 보인다. requestMatchers("/").permitAll()
http://www.localhost:8080/freeboard 액세스가 거부 됨. 그 밑에는
HTTP ERROR 403
requestMatchers("/freeboard*").hasRole("USER")

 

 

위 표와 같이 테스팅이 나오면 spring security의 인가 정책은 정상적으로 동작하는 것이다. 

 

 

 

다음장은 login 커스트마이징 입니다 ~

IDE : STS4 - Spring Tool Suite-4

 

** 개발환경

spring boot 3.3.5

spring security 6.0

oracle 11g

mybatis

gradle

 

- spring boot project가 이미 만들어진 후 spring  security를 적용하는 방법으로  기록한다.

 

1. 의존성 추가

build.gradle 파일을 클릭하여 의존성을 추가 한다. > gradle을 업데이트 한다.

<소스>  implementation 'org.springframework.boot:spring-boot-starter-security'

 

build.gradle 파일을 클릭하여 의존성을 추가 

 

Gradle 업데이트

 

 

확인방법-----------------------------------------

서버를 다시 시작하고 주소창에 주소를 입력하면 로그인 창이 나온다.

주소창에 localhost:8080 이라고 입력(포트번호는 다를 수 있음, 스프링 부트 콘솔을 참고)하면 자동으로 로그인 창으로 이동된다. 아래 화면에 보이는 로그인 창은 spring boot가 내장하고 있는 화면.

 

http://www.localhost:8080   이라고 브라우저 주소창에 입력한다.. 여기서 포트 번호를 다를 수 있으니

스프링 부트의 콘솔을 확인해 보자.

이렇게 되면 spring security 설치는 완료 된 것.

 

 

http://www.localhost:8080 또는 http://www.localhost:8080/freeboard로 입력하고 로그인 화면으로 전환된다. 

즉, 어떤  url을 요청해도 spring security는 필터링하여 인증을 하도록 한다.

 

 

맛보기 - 인증과 인가를 이해해 보자.

서버를 재시작하고 콘솔을 보면 임시 비밀번호가 있다.



임시 비밀번호로 로그인을 할 것이다.
 username부분에는  user를 입력하고, password부분은 콘솔에 출력된 암호를 입력한다. 
Sing in을 입력하면 다음과 같이 인가가 된 것을 확인 할 수 있다.
인가 받은 user이기 때문에 다른 url요청도 모두 인가해 준다. 

맛보기 -------------------------------------------- 끝

 

 

IDE : STS4 - Spring Tool Suite-4

 

오늘은  spring security를 프로젝트에 적용시킬 것이다.

적용 시킬 프로젝트를 먼저 간단하게 만들어 보자

 

1. 프로젝트 생성

 

2. Dependency는 간단하게 4개만 추가 한다.

    spring security는 추가하지 않고 프로젝트 완성 후에 추가할 예정

 

생성 된 프로젝트의 구조를 먼저 살펴본다

많이 다루게 될 부분을 빨간색으로 표시함

 

 

서버를 구동시키고 콘솔창을 확인한다. 다음과 같은 failed가 나온다.

이유를 잘 읽어 보면, 프로젝트 생성 시 mybatis 퍼시스턴스 프레임워크를 추가 했는데 관련 된 설정 파일을 로딩할 수 없어서 생긴 문제이다.

 

      - 해결방법 -

다음 설정 내용을 application.properties 파일에 추가한다.

#Oracle DataSource

spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver

spring.datasource.url=jdbc:oracle:thin:@127.0.0.1:1521/orcl

spring.datasource.username=system

spring.datasource.password=11111111

 

# Mapper Xml Location

mybatis.mapper-locations=classpath:mappers/*.xml

 

 

다시 서버를 부팅하고 콘솔창을 확인하면 fail이 사라졌다.

 

여기까지 설정은 완료 되었다

이제 간단한 컨트롤러를 만들어 보자.

 

이제 컨트롤러에서 응답할 뷰를 만들어 보자.

 

home.html 소스

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

<h2>Main Page</h2>

</body>

</html>

 

freeboard.html 소스

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

<h2>freeboard</h2>

</body>

</html>

 

 

컨트롤러 동작이 되는지 확인해 본다. 

 

 

이제 부터는 spring security를 추가하여 권한별로 접근이 가능하도록 설정한다.

+ Recent posts