Spring Boot3 + Security + JWT 를 구성하려다 보니 JWT에서 refresh Token 의 저장소를 구성하기 위해 Redis를 가 필요 했다.
그래서 구글링 + ChatGTP를 이용하여 구성했다. 구성 방식은 아래와 같다.

1. Linux용 Windows 하위 시스템 / 가상 머신 플랫폼 활성화
Windows의 기능 켜기/끄기 창에서 
   

2. WSL 설치
Windows PowerShell을 관리자 모드로 실행한다.
아래 명령어를 실행한다.

PS C:\> wsl --install

3. WSL에서 사용할 수 있는 Linux 배포판 목록 확인

PS C:\> wsl -l --online

실행결과

PS C:\> wsl -l --online
다음은 설치할 수 있는 유효한 배포판 목록입니다.
'wsl.exe --install <Distro>'를 사용하여 설치합니다.

NAME                            FRIENDLY NAME
Ubuntu                          Ubuntu
Debian                          Debian GNU/Linux
kali-linux                      Kali Linux Rolling
Ubuntu-18.04                    Ubuntu 18.04 LTS
Ubuntu-20.04                    Ubuntu 20.04 LTS
Ubuntu-22.04                    Ubuntu 22.04 LTS
Ubuntu-24.04                    Ubuntu 24.04 LTS
OracleLinux_7_9                 Oracle Linux 7.9
OracleLinux_8_7                 Oracle Linux 8.7
OracleLinux_9_1                 Oracle Linux 9.1
openSUSE-Leap-15.6              openSUSE Leap 15.6
SUSE-Linux-Enterprise-15-SP5    SUSE Linux Enterprise 15 SP5
SUSE-Linux-Enterprise-15-SP6    SUSE Linux Enterprise 15 SP6
openSUSE-Tumbleweed             openSUSE Tumbleweed

4. Ubuntu 설치
위의 목록 중에 Ubuntu-24.04 를 설치한다.

PS C:\> wsl --install Ubuntu-24.04

설치된 Version 확인한다.

PS C:\> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-24.04    Running         2

5. Ubuntu 실행

PS C:\> wsl

위 명령어를 수행하면 리눅스가 실행된다.

 


6. Redis 설치
Ubuntu 실행 상태에서 시작합니다.
아래 명령어들을 한 줄씩 실행합니다.

****:/mnt/d$ curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
****:/mnt/d$ echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
****:/mnt/d$ sudo apt-get update
****:/mnt/d$ sudo apt-get install redis

위의 명령어를 모두 수행하면 설치가 완료 된다. 설치된 위치: /etc/redis이고 해당 폴더에 접근하려면 root 권한 또는  sudo 권한이 있어야 접근이 가능하다.

위의 사유로 root 권한으로 접근할 수 있도록 비밀번호를 설정해 준다.
우분투에서 빠져 나와서 명령어를 수행한다.

PS C:\> wsl --user root

비밀번호 설정

root@****:/mnt/d# passwd

 

7. Redis 실행
Redis 실행 방법은 2가지가 있다.

# 전역(어디서든) 실행 가능한 명령
root@****:/mnt/d# sudo service redis-server start
# redis 경로(/etc/redis)에서 실행
root@****:/mnt/d# redis-server ./redis.conf

실행이 되고 나면 접속 확인한다.

root@****:/mnt/d# redis-cli -p 6379
127.0.0.1:6379> ping
PONG

redis-cli 뒤에 포트를 입력해도 되고 안해도 된다. 기본 포트가 6379이다.
접속한 상태에서 ping를 입력하면 시스템은 PONG를 리턴해 준다.

End.

개발 환경

Java 23, Spring Boot 3
Spring Security 6
Sprint + React + typescript
Spring Boot : 3.3.5

Eclipse 환경 설정

1. eclipse download
https://www.eclipse.org/downloads/

 

Eclipse Downloads | The Eclipse Foundation

The Eclipse Foundation - home to a global community, the Eclipse IDE, Jakarta EE and over 415 open source projects, including runtimes, tools and frameworks.

www.eclipse.org

현 시점에 Eclipse 버전 : Eclipse IDE 2024-09 R Packages

2. STS(Spring Tool Suite) 설치

Eclipse의 Help > Elcipose Marketplace... 클릭

Spring Tools 4 (aka Spring Tool Suite 4) 설치


React 설치

1. VSCode 설치
https://code.visualstudio.com/download

 

Download Visual Studio Code - Mac, Linux, Windows

Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows. Download Visual Studio Code to experience a redefined code editor, optimized for building and debugging modern web and cloud applications.

code.visualstudio.com

 

2. node.js 다운로드
https://nodejs.org/en

 

Node.js — Run JavaScript Everywhere

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

 


개발 시작

Back-End 작성

1. Eclipse Project 설정
- Spring Boot Initializr를 통한 프로젝트 생성
  File > New > Project 메뉴 클릭
 

  다이얼로그에서 Spring Starter Project 선택 후 Next 클릭

  정보를 입력하고 Next 클릭
  · Package에 입력한 Package가 Root Package가 되어 SpringBootApplication 가 해당 Package에 생성이 된다.
    해당 Package에 하위 Package를 생성 후 개발이 시작된다.
  · 만약 생성 시 "No locally installed toolchains match and toolchain download repositories have not been configured." 오류가 발생할 경우 https://kamsi76.tistory.com/entry/Gradle-No-locally-installed-toolchains-match-and-toolchain-download-repositories-have-not-been-configured-%ED%95%B4%EA%B2%B0%EB%B0%A9 참조

   사용할 Dependence 항목을 선택하고 Finish 클릭하면 프로젝트가 생성이 된다.
    · 위의 항목들을 선택하고 우선은 테스트를 위해서 build.gradle 의 dependencies의 몇가지 항목을 주석 처리 한다.
      추후 진행하면서 주석을 풀 예정이다.

    ·  위와 같이 주석 처리를 하고 반드시 프로젝트에 오른쪽 마우스 클릭 후 Gradle를 Refresh 해 줘야 한다.

2. Yml 파일 작성
   프로젝트가 생성이 되면 src/main/resources 밑에 application.properties 파일이 생성되어 있다.
   application.properties 를 application.yml로 확장자를 변경하고 설정한다.

spring:
   application:
      name: first-react-board
   devtools:
      restart:
         enabled: true
server:
   port: 8080
   servlet:
      context-path: /

 

2. Back-End API 작성

package kr.co.infob.api.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value="/api")
public class ApiController {
	
	@GetMapping("/hello")
	public ResponseEntity<String> hello() {
		return ResponseEntity.ok().body("Hello World!!!!");
	}
}

 

3. 서버 시작 후 Api 테스트 확인

    서버 시작후 위와 같이 보이면 Back-End는 우선 성공


Front-End

1. typescript 템플릿 기반의 nodejs 프로젝트 생성

import React, {useEffect} from 'react';

function App() {
  
  const [txtHello, printText] = React.useState("");

  useEffect( () => {

    // Back-End의 API를 호출한다.
    fetch('http://localhost:8080/api/hello', {
        method: "GET"
      })
      .then( res => {
        /*
          * API 호출 결과가 ok가 아닌경우
          * 오류 메시지를 출력한다.
          */
        if( !res.ok ) {
          throw new Error("Network response was not ok!!!!");
        }
        return res.text()
      })
      .then( res => {
        console.log( res );
        if (typeof res === 'string'){
          printText(res);
        }
      })
      .catch(err => console.log(err) );
  },[]);

  return (
    <div>{txtHello}</div>
  );
}

export default App;


    VSCode 실행 후 터미널 실행
    Eclipse에서 생성 한 프로젝트의 src/main 폴더까지 이동한다.
    아래는 해당 폴더까지 이동한 예시이다.

    해당 폴더에서 아래 명령어 실행

npx create-react-app frontend --template typescript

    Typescript의 기반의 React 프로젝트는 생성한다.

    설치가 완료 되면 소스 코드를 VBCode의 openFolder로 생성 한 프로젝트 frontend 폴더를 선택한다.
   

   src 밑에 app.tsx파일을 Back-End에서 생성한 Api를 호출 하도록 수정한다.

import React, {useEffect} from 'react';

function App() {
  
  const [helloTxt, printText] = React.useState("");

  useEffect( () => {

    // Back-End의 API를 호출한다.
    fetch('http://localhost:8080/api/hello', {
        method: "GET"
      })
      .then( res => {
        /*
          * API 호출 결과가 ok가 아닌경우
          * 오류 메시지를 출력한다.
          */
        if( !res.ok ) {
          throw new Error("Network response was not ok!!!!");
        }
      })
      .then( res => {
        console.log( res );
        if (typeof res === 'string'){
          printText(res);
        }
      })
      .catch(err => console.log(err) );
  },[]);

  return (
    <div>{helloTxt}</div>
  );
}

export default App;

   VBCode 터미널에서 npm start 명령을 실행 시켜 기동한다.
   ※ Back-End는 반드시 실행 되어 있어야 한다.
   - 구동 후 CORS 오류가 발생하는 경우 Proxy 설정과 SpringBoot의 설정 값을 변경해 줘야 한다.
      Back-End 설정 파일을 추가

package kr.co.infob.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
	
	@Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("Authorization", "Content-Type")
                .exposedHeaders("Custom-Header")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

    Front-End package.json 파일 변경

   package.json 파일을 변경 하면 frontend 소스에서 http://localhost:8080은 빼고 작성을 하면 된다.

 // Back-End의 API를 호출한다.
fetch('/api/hello', {
    method: "GET"
  })
  ...
)
...

VScode 터미널에서 npm 사용시 

PS D:\Develop\Workspace\202409\first-react-board\src\main\frontend> npm start
npm : 이 시스템에서 스크립트를 실행할 수 없으므로 C:\Program Files\nodejs\npm.ps1 파일을 로드할 수 없습니다. 자세한 내용은 about_Execution_Policies(https://
go.microsoft.com/fwlink/?LinkID=135170)를 참조하십시오.

위의 오류가 발생할 경우 위의 경로(https://go.microsoft.com/fwlink/?LinkID=135170)를 검색한 결과로 아래와 같은 PowerShell 정책을 가지고 있다고 한다.


PowerShell 실행 정책

이러한 정책의 적용은 Windows 플랫폼에서만 발생합니다. PowerShell 실행 정책은 다음과 같습니다.

  • AllSigned

    • 스크립트를 실행할 수 있습니다.
    • 로컬 컴퓨터에서 작성하는 스크립트를 포함하여 신뢰할 수 있는 게시자가 모든 스크립트 및 구성 파일에 서명해야 합니다.
    • 아직 신뢰할 수 있거나 신뢰할 수 없는 것으로 분류되지 않은 게시자의 스크립트를 실행하기 전에 메시지를 표시합니다.
    • 서명되었지만 악의적인 스크립트가 실행될 위험이 있습니다.
  • Bypass

    • 아무것도 차단되지 않으며 경고 또는 프롬프트가 없습니다.
    • 이 실행 정책은 PowerShell 스크립트가 더 큰 애플리케이션에 기본 제공되는 구성 또는 PowerShell이 자체 보안 모델을 가진 프로그램의 기초가 되는 구성을 위해 설계되었습니다.
  • Default

    • default 실행 정책을 설정합니다.
    • Restricted Windows 클라이언트의 경우
    • Windows 서버용 RemoteSigned .
  • RemoteSigned

    • default Windows 서버 컴퓨터에 대한 실행 정책입니다.
    • 스크립트를 실행할 수 있습니다.
    • 전자 메일 및 인스턴트 메시징 프로그램을 포함하는 인터넷에서 다운로드되는 스크립트 및 구성 파일에 대해 신뢰할 수 있는 게시자의 디지털 서명이 필요합니다.
    • 로컬 컴퓨터에 작성되고 인터넷에서 다운로드되지 않은 스크립트에는 디지털 서명이 필요하지 않습니다.
    • cmdlet을 사용하는 등 스크립트가 차단 해제된 경우 인터넷에서 다운로드되고 서명되지 않은 스크립트를 Unblock-File 실행합니다.
    • 악의적일 수 있는 인터넷 및 서명된 스크립트 이외의 원본에서 서명되지 않은 스크립트를 실행할 위험이 있습니다.
  • Restricted

    • default Windows 클라이언트 컴퓨터에 대한 실행 정책입니다.
    • 개별 명령을 허용하지만 스크립트는 허용하지 않습니다.
    • 서식 및 구성 파일(), 모듈 스크립트 파일() 및 PowerShell 프로필(.ps1xml.psm1)을 비롯한 모든 스크립트 파일의 실행을 방지합니다.ps1.
  • Undefined

    • 현재 scope실행 정책 집합이 없습니다.
    • 모든 범위 Undefined의 실행 정책이 있는 경우 유효한 실행 정책은 Restricted Windows 클라이언트 및 Windows Server용 RemoteSigned 에 대한 것입니다.
  • Unrestricted

    • Windows가 default 아닌 컴퓨터에 대한 실행 정책이며 변경할 수 없습니다.
    • 서명되지 않은 스크립트를 실행할 수 있습니다. 악의적인 스크립트를 실행할 위험이 있습니다.
    • 로컬 인트라넷 영역이 아닌 스크립트 및 구성 파일을 실행하기 전에 사용자에게 경고합니다.

    참고

    UNC(유니버설 명명 규칙) 경로를 인터넷 경로와 구분하지 않는 시스템에서 UNC 경로로 식별되는 스크립트는 RemoteSigned 실행 정책을 사용하여 실행할 수 없습니다.


현재 정책 확인 방법

PowerShell을 관리자 모드로 실행 후 아래의 명령어를 실행한다.

PS C:\Users\AAAAA> get-ExecutionPolicy
Restricted

현재 정책이 " Restricted" 라는 것을 확인할 수 있다. 명령어를 허용하지 않는 정책이기 때문에 변경한다.

실행 정책 변경

PS C:\Users\AAAAA> Set-ExecutionPolicy RemoteSigned

위의 명령어를 실행 후 VBCode 터미널에서 실행하면 정상 동작한다.

Gradle에서 java 버전이 맞지 않아 생기능 현상.

원인 : 

Spring Boot를 설정 화면

Java Version 항목의 버전과 컴퓨터에 설치되어 있는 버전이 달라서 발생하는 오류.

해결방법 :

1.  eclipse ini 파일 수정

-vm
JAVA 설치 경로/bin/javaw.exe

위의 항목 추가 처리

 

2. 환경설정에 자바 경로 설정
    해당 방법은 별도로 설명하지 않음.

Windows에 Git이 설치 되어 있고 Gitea에 Repository가 생성되었다는 전제로 시작한다.
여기서 주의 점은 Repository를 생성하고 나서는 Readme 같은 파일도 생성하지 말고 아예 빈 Repository로 두고 진행하는 것이 좋다.

1. CMD를 통해 기존 프로젝트 폴더로 이동한다.

D:\Workspace>cd projet-system

2. git을 초기화 한다.

D:\Workspace\project-system>git init

만약, 기존에 git을 사용했던 프로젝트라면 git이 이미 설정되어 있다고 아래와 같이 오류가 발생할 수 있다.

Reinitialized existing Git repository in D:/Develop/Workspace/eclipse/project-system/.git/

이런 경우 프로젝트 폴더에서 .git 폴더를 삭제한다.
정상적으로 초기화가 되면 다음과 같은 메시지가 보여진다.

Initialized empty Git repository in D:/Develop/Workspace/eclipse/infobee-system/.git/

3. Repository와 연결한다.

D:\Workspace\project-system>git remote add origin http://192.168.1.100:3000/project/project-system.git

4. 연결이 올바로 되었는지 확인한다.

D:\Workspace\project-system>git remote -v
origin  http://192.168.1.100:3000/project/project-system.git (fetch)
origin  http://192.168.1.100:3000/project/project-system.git (push)

5. Repository에서 pull을 받아 git을 동기화 한다.

D:\Workspace\project-system>git pull origin main

6. Repository에 파일을 올리기 위해 파일을 추가한다.

D:\Workspace\project-system>git add .

7. 최초로 commit 한다.

D:\Workspace\project-system>git commit -m "first commit"

8. Repository에 파일을 업로드 한다.

D:\Workspace\project-system>git push -u origin main

여기서 문제가 발생했다.
Gitea는 기본적으로 branch가 main으로 잡힌다.
그런데 git의 경우에는 master가 기본 branch가 된다.
위의 사유로 아래와 같은 오류가 발생했다.

error: src refspec main does not match any
error: failed to push some refs to 'http://192.168.1.100:3000/project/project-system.git'

그래서 branch 이름을 확인해 봤다. 

D:\Workspace\project-system>git branch
* master

위와 같이 master로 되어 있어서 main으로 branch를 변경해야 했다.

D:\Workspace\project-system>git fetch
D:\Workspace\project-system>git checkout -b main
branch 'main' set up to track 'origin/main'.
Switched to a new branch 'main'

위와 같이 branch를 변경했다면 
6번부터 8번까지 다시 진행하면 된다.

'소스형상화' 카테고리의 다른 글

[GITEA] 회사 폐쇄망 Git 설치 하기  (0) 2024.04.04

회사에서만 사용하는 Git을 설치하고하 하여 이곳 저곳을 찾아 봤지만 많은 글이 올라와 있지는 않았다.
특히, 단순히 Git을 설치하여 진행하는 컨텐츠는 많았으나 Github 같은 Web GUI를 이용하게 해주는건 찾기가 힘들었다.

구글링한 결과 Gitea를 이용하여 설치하면 되는 것을 알았고, 설치 방법을 저장하려고 한다.

1. Gitea 다운로드
    다운로드 경로 : https://github.com/go-gitea/gitea/release

    현재 적용버전은 1.21.10으로 윈도우 설치 프로그램을 찾아야 한다.
    하단 Show all 106 assets를 클릭하면 전체 다운 받을 수 있는 목록 보여진다.

    윈도우에 설치하기 위해 gitea-1.21.10-windows-4.0-amd64.exe 파일을 다운로드 한다.

   다운로드한 파일을 관리자권한으로 실행 한다.
   여기서 주의사항은 되도록이면 Git repositories로 사용하고자 하는 폴더로 파일을 이동시켜 놓고 실행하도록 한다.
   이유는 나중에 해당 파일을 Service에 등록해야 하는데 Download 폴더에 있으면 어떻게 될지 모르기 때문에.... 

   위와 같이 실행이 되면 브라우저를 실행한다.
   주소는 http://localhost:3000를 입력한다.
   그러면 설정 화면이 보여지게 된다. 
   아래 이미지는 데이터베이스 설정으로 Gitea는 DB를 통해서 정보를 관리한다.
   나는 PostgresSQL을 사용하고 DB 사용자 및 데이터베이스는 만들어 놓은 상태이다.

   다음은 기본 설정을 화면이다.
   Git을 사요하기 위한 기본 설정을 진행한다.

   다음은 추가설정 화면이다.
   사용자를 마음대로 등록하지 못하도록 사용자 등록 비활성화를 체크한다.

   추가설정 완료 후 관리자 설정화면이다.
   관리자 정보를 입력하고 Gitea 설치하기 버튼을 눌러서 최종 설정을 완료 한다.

   설치가 완료 되면 Git 화면이 보여진다.

   이상으로 Gitea 설치가 완료 되었고 이클립스와 같은 툴에서 사용하면 된다.

  다음으로 실행파일을 Service에 등록해야 한다.
  그렇지 않으면 위에 있는 CMD 창을 계속 띄워놓아야 하고 또 서버를 껐다가 켜도 다시 실행해줘야 하는 번거로움이 있다.
   CMD 를 관리자로 열고 다음과 같이 입력하여 준다.

sc.exe create gitea start=auto binPath="\"D:\GIT\gitea-1.21.10-windows-4.0-amd64.exe\" web --config \"D:\GIT\custom\conf\app.ini\""

  마지막으로 Service에 들어가서 실행시켜 준다.

sc start gitea

끝....

'소스형상화' 카테고리의 다른 글

[GITEA] 기존 프로젝트 Git repository 적용  (0) 2024.04.08

SSO 처리를 위해 AbstractAuthenticationProcessingFilter를 사용하여 사전에 사용자 정보를 가져와 로그인 처리를 하려 하는데 분명 로그인을 했는데 자꾸 AnonymousUser라고 로그인 안 된거 처럼 되는 현상으로 하루 죙일 구글링 시작...

찾은 결과

SecurityContext는 인증 성공후에 기본적으로 저장하지 않는다. 
UsernamePasswordAuthenticationFilter는 form-login 기반으로 SSO 처리시에는 호출 되지 않기 때문에
SessionManagementFilter에 인증정보를 감지할 수 없다.
그렇기 때문에 인증 성공후에 인정된 객체를 SecurityContext에 저장해야 한다.
SecurityContext에 저장하기 위하여는 AbstractAuthenticationProcessingFilter의 successfulAuthentication를 재정의하여야 한다.

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {

        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(authResult);
        //SecurityContextHolder.setContext(context);
        HttpSessionSecurityContextRepository secRepo = new HttpSessionSecurityContextRepository();
        secRepo.saveContext(context, request, response);

        super.successfulAuthentication(request, response, chain, authResult);
}

이걸 찾는데 너무 오랜 시간을 사용했다...ㅜㅜ

SecurityConfig에서 해당 부분만 발췌한 내용은 아래와 같다.

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig {

    ...
    
    @Autowired
    private UrlBasedAuthorizationManager urlBasedAuthorizationManager;

    @Bean
    public PasswordEncoder encoder() {
    return new BCryptPasswordEncoder();
    }

    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    	http
			.csrf((csrf) ->
				csrf.disable()
			)
            .authorizeHttpRequests(
					(requests) ->
							requests
								.requestMatchers("/", "/loginionvalid.html").permitAll()
								.anyRequest().authenticated()
			)
			.formLogin((form) ->
							form
								.loginPage("/login.html")
								.usernameParameter("userId")
								.passwordParameter("pass")
								.loginProcessingUrl("/login/proc.html")
								.defaultSuccessUrl("/")
								.successHandler(customAuthenticationSuccessHandler)
								.failureHandler(customAuthenticationFailureHandler)
								.permitAll()
			)
			.logout((logout) ->
						logout
							.logoutUrl("/logout.html")
							//.logoutSuccessHandler(null)
							.logoutSuccessUrl("/")
							.permitAll()
			)
			.addFilterBefore(requestProcessingFilter(http), UsernamePasswordAuthenticationFilter.class)
			.addFilterBefore(urlBaseAuthorizationFilter(), AuthorizationFilter.class)
		;

        return http.build();
    }
    
    /**
     * SSO 처리를 위한 처리
     * @param http
     * @return
     * @throws Exception
     */
    @Bean
    public RequestProcessingFilter requestProcessingFilter(HttpSecurity http) throws Exception {

        AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManagerBuilder.class).build();

        RequestProcessingFilter rpf = new RequestProcessingFilter("/ssoLogin.html");
        rpf.setAuthenticationManager(authenticationManager);
        rpf.setAuthenticationFailureHandler(ssoAuthenticationFailureHandler);
        rpf.setAuthenticationSuccessHandler(customAuthenticationSuccessHandler);
        return rpf;
    }
    
    ...
}


RequestProcessingFilter.java

public class RequestProcessingFilter extends AbstractAuthenticationProcessingFilter {

	private String usernameParameter = "userInfo";

	public RequestProcessingFilter(String defaultFilterProcessesUrl) {
		super(defaultFilterProcessesUrl);
	}

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException, IOException, ServletException {

		String requestInfo = obtainUsername(request);
		if( !StringUtils.hasText(requestInfo) ) {
			logger.error("사용자 정보 연계시 사용자 정보 미전송");
			throw new BadCredentialsException("사용자 정보가 올바르게 전송되지 않았습니다. 관리자에게 문의하여 주시기 바랍니다.");
		}

		...
		String userNo = ...;

		UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(userNo,
				"user1");

		// Allow subclasses to set the "details" property
		setDetails(request, authRequest);
		return this.getAuthenticationManager().authenticate(authRequest);
	}

	protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
		authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
	}

	public String obtainUsername(HttpServletRequest request){
		return request.getParameter(usernameParameter);
	}

	@Override
	protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {

	        SecurityContext context = SecurityContextHolder.createEmptyContext();
	        context.setAuthentication(authResult);
	        //SecurityContextHolder.setContext(context);
	        HttpSessionSecurityContextRepository secRepo = new HttpSessionSecurityContextRepository();
	        secRepo.saveContext(context, request, response);

	        super.successfulAuthentication(request, response, chain, authResult);
	}

}

암복호화를 하기 위한 pgcrypto 확장 기능 적용

CREATE EXTENSION pgcrypto;

암호화 하기

SELECT
   encode(
      encrypt(
         convert_to('암호화 하기 위한 문자열', 'utf8'),
         '암호화Key',
         'aes'
      ),
      'hex'
);

복호화 하기

SELECT
   convert_from(
      decrypt(
         decode('d359bf2938e5ef1cb6dca49dce459654b10e82e4cb3a62c63ef7511df01b6...',
         'hex'
      ),
      '암호화Key',
      'aes'
   ),
   'utf8'
);

'Database > PostgreSQL' 카테고리의 다른 글

[PostgreSQL] 테이블/컬럼 정보 조회 SQL  (0) 2023.06.20
[PostgreSQL] UPSERT 적용  (1) 2020.05.19

테이블 목록 조회

SELECT RELNAME AS TABLE_NAME
  FROM PG_STAT_USER_TABLES

컬럼목록 조회

SELECT *
  FROM INFORMATION_SCHEMA.COLUMNS
 WHERE TABLE_CATALOG = '데이터베이스명'
   AND TABLE_NAME    = '테이블명'
 ORDER BY ORDINAL_POSITION;

기본키 조회

SELECT CC.COLUMN_NAME AS COLUMN_NAME
  FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS       TC
      ,INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CC
 WHERE TC.TABLE_CATALOG   = '데이터베이스명'
   AND TC.TABLE_NAME      = '테이블명'
   AND TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
   AND TC.TABLE_CATALOG   = CC.TABLE_CATALOG
   AND TC.TABLE_SCHEMA    = CC.TABLE_SCHEMA
   AND TC.TABLE_NAME      = CC.TABLE_NAME
   AND TC.CONSTRAINT_NAME = CC.CONSTRAINT_NAME

테이블 Comment 조회

SELECT PS.RELNAME    AS TABLE_NAME
      ,PD.DESCRIPTION AS TABLE_COMMENT
  FROM PG_STAT_USER_TABLES PS
      ,PG_DESCRIPTION      PD
 WHERE PS.RELNAME  = '테이블명'
   AND PS.RELID   = PD.OBJOID
   AND PD.OBJSUBID  = 0

컬럼 Comment 조회

SELECT PS.RELNAME    AS TABLE_NAME      ,PA.ATTNAME     AS COLUMN_NAME      ,PD.DESCRIPTION AS COLUMN_COMMENT  FROM PG_STAT_ALL_TABLES PS      ,PG_DESCRIPTION     PD      ,PG_ATTRIBUTE       PA WHERE PS.SCHEMANAME = (SELECT SCHEMANAME                            FROM PG_STAT_USER_TABLES                           WHERE RELNAME = '테이블명')   AND PS.RELNAME  = '테이블명'   AND PS.RELID   = PD.OBJOID   AND PD.OBJSUBID <> 0   AND PD.OBJOID    = PA.ATTRELID   AND PD.OBJSUBID  = PA.ATTNUM ORDER BY PS.RELNAME, PD.OBJSUBID

 

출처 : https://jmap.tistory.com/549

'Database > PostgreSQL' 카테고리의 다른 글

[PostgreSQL] 암복호화  (0) 2023.06.27
[PostgreSQL] UPSERT 적용  (1) 2020.05.19

1. dependency 추가

implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"

 

2. 새로 고침 대상의 View를 SwipeRefreshLayout의 자식 View 만든다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/swiperefreshlayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <WebView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/activity_main_webview"
            android:fadingEdge="none" />
    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

 

3. 소스에 이벤트 등록을 한다.

private SwipeRefreshLayout swipeRefreshLayout;
private WebView mWebView;

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
        mWebView = findViewById(R.id.activity_main_webview);
        
        swipeRefreshLayout.setOnRefreshListener(() -> {
        	/* Webview를 새로고침한다. */
            mWebView.reload();
            /* 업데이트가 끝났음을 알림 */
            swipeRefreshLayout.setRefreshing(false);
        });
        
        ....
}

 

- 커널 버전 확인

# uname -r

5.8.0-44-generic

 

- 메모리 확인
전체 메모리 8G

# free -h

              total        used        free      shared  buff/cache   available
Mem:          7.8Gi       679Mi       6.5Gi       7.0Mi       635Mi       6.9Gi
Swap:         1.8Gi          0B       1.8Gi

 

- CPU 정보 확인

# lscpu

Architecture:                    x86_64
CPU op-mode(s):                  32-bit, 64-bit
Byte Order:                      Little Endian
Address sizes:                   39 bits physical, 48 bits virtual
CPU(s):                          2
On-line CPU(s) list:             0,1
Thread(s) per core:              1
Core(s) per socket:              2
Socket(s):                       1
NUMA node(s):                    1
Vendor ID:                       GenuineIntel
CPU family:                      6
Model:                           142
Model name:                      Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
Stepping:                        10
CPU MHz:                         1992.000
BogoMIPS:                        3984.00
Hypervisor vendor:               KVM
Virtualization type:             full
L1d cache:                       64 KiB
L1i cache:                       64 KiB
L2 cache:                        512 KiB
L3 cache:                        16 MiB
NUMA node0 CPU(s):               0,1
Vulnerability Itlb multihit:     KVM: Mitigation: VMX unsupported
Vulnerability L1tf:              Mitigation; PTE Inversion
Vulnerability Mds:               Mitigation; Clear CPU buffers; SMT Host state unknown
Vulnerability Meltdown:          Mitigation; PTI
Vulnerability Spec store bypass: Vulnerable
Vulnerability Spectre v1:        Mitigation; usercopy/swapgs barriers and __user pointer sanitization
Vulnerability Spectre v2:        Mitigation; Full generic retpoline, STIBP disabled, RSB filling
Vulnerability Srbds:             Unknown: Dependent on hypervisor status
Vulnerability Tsx async abort:   Not affected
Flags:                           fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq
                                  pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti fsgsbase avx2 invpcid rdseed clflushopt md_clear 
                                 flush_l1d

 

- OS 버전 정보 확인

# cat /etc/os-release

NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

 

- Text 부팅으로 구성

# systemctl set-defalut multi-user.target

ubun

# vi /etc/hostname
master.example.co.kr

- SSH 설치

sudo apt-get install openssh-server

 

- hostname 수정

# vi /etc/hostname
master.example.co.kr

 

- hosts 수정
현재 Master을 제외한 노드를 3개 사용할 계획
아이피는
master : 192.168.1.130 
node1 : 192.168.1.131
node2 : 192.168.1.132
node3 : 192.168.1.134

# vi /etc/hosts

192.168.1.130   master.example.co.kr master
192.168.1.131   node1.example.co.kr node1
192.168.1.132   nodE2.example.co.kr node2
192.168.1.133   node3.example.co.kr node3

 

'Kubernetes' 카테고리의 다른 글

Microk8s 공부하면서 대충 필요한 것들 마구마구  (0) 2021.02.18
[Kubernetes] Calico  (0) 2021.01.27

WIFI 국가설정
# vi /etc/defalt/crda

REGDOMAIN=KR

 

WIFI 연결 설정
# vi /etc/netplan/[TAB키]

network:
    ethernets:
        eth0:
            dhcp4: true
            optional: true
    wifis:
        wlan0:
            addresses: [192.168.1.113/24]
            gateway4: 192.168.1.1
            nameservers:
             addresses: [168.126.63.1,168.126.63.2]
            dhcp4: no
            optional: true
            access-points:
                    "Infobee-5G":
                      password: "1234qwer"
    version: 2

# netplan generate
# netplan apply

Dashboard Token 확인

kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep default | awk '{print $1}')

 

Dashboard 외부에서 접근가능하게 처리

kubectl port-forward -n kube-system svc/kubernetes-dashboard 10443:443 --address 0.0.0.0 &

 

kubectl alias 

snap alias microk8s.kubectl kubectl

 

port-forward 찾아서 지우기

root@ubuntu-master:~# ps -ef|grep port-forward
root       35872    3925  0 16:32 pts/1    00:00:00 /bin/bash /snap/microk8s/2036/microk8s-kubectl.wrapper port-forward -n kube-system svc/kubernetes-dashboard 10443:443 --address 0.0.0.0
root       35901   35872  0 16:32 pts/1    00:00:00 /snap/microk8s/2036/kubectl port-forward -n kube-system svc/kubernetes-dashboard 10443:443 --address 0.0.0.0
root       39913    3925  0 16:36 pts/1    00:00:00 grep --color=auto port-forward

root@ubuntu-master:~# kill -9 35901

 

apt install net-tools 설치시 
Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process
에러 발생 대처

root@ubuntu:~# killall apt apt-get
root@ubuntu:~# rm /var/lib/apt/lists/lock
root@ubuntu:~# rm /var/cache/apt/archives/lock
root@ubuntu:~# rm /var/lib/dpkg/lock*
root@ubuntu:~# dpkg --configure -a
root@ubuntu:~# apt update

위와 같이 했는데 안되면 reboot~

microk8s status 실행 시 
The memory cgroup is not enabled. 
메시지 발생 처리
/boot/firmware/cmdline.txt 파일 제일 앞에 cgroup_enable=memory cgroup_memory=1 추가

cgroup_enable=memory cgroup_memory=1 net.ifnames=0 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

 

'Kubernetes' 카테고리의 다른 글

[Ubuntu] 01. Ubuntu 설치  (0) 2021.02.26
[Kubernetes] Calico  (0) 2021.01.27

'Kubernetes' 카테고리의 다른 글

[Ubuntu] 01. Ubuntu 설치  (0) 2021.02.26
Microk8s 공부하면서 대충 필요한 것들 마구마구  (0) 2021.02.18

+ Recent posts