애플리케이션 설계 및 테스트

스프링 시큐리티 - 기본 준비

황샐리 2022. 7. 14. 15:36

[build.gradle]

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
	annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
	annotationProcessor 'org.projectlombok:lombok'
	providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.security:spring-security-test'
}

[properties]

spring.datasource.url=jdbc:mariadb://
spring.datasource.driver-class-name=org.mariadb..
spring.datasource.username=
spring.datasource.password=
#jpa
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true

[INDEX]

인덱스 페이지를 만들어주었습니다.

템플릿에 html로 만들어줬슴다.

local로 돌려줄게요!

스프링 시큐리티 기본 화면

그러면 이렇게 나옵니다!

만들어준 인덱스 페이지도 못 들어가는,,, 왜그럴까요?🤷‍♀️?

 

바로 스프링 시큐리티에 있는 보안 때문입니다!

보여주게 하려면? 설정을 해야합니다.  인덱스 페이지부터 함 해볼게요

시큐리티 설정 어케합니까?

Http보안

지금까지 WebSecurityConfig 에는 사용자를 인증하는 방법에 대한 정보만 포함되어 있습니다. Spring Security는 모든 사용자의 인증을 요구한다는 것을 어떻게 알 수 있습니까? Spring Security는 우리가 양식 기반 인증을 지원하기를 원한다는 것을 어떻게 알 수 있습니까? 실제로, 이라고 불리는 장면 뒤에서 호출되는 빈이 있습니다 SecurityFilterChain. 다음 기본 구현으로 구성됩니다.

출처 : https://docs.spring.io/spring-security/reference/servlet/configuration/java.html

 

Java Configuration :: Spring Security

Spring Security’s Java Configuration does not expose every property of every object that it configures. This simplifies the configuration for a majority of users. Afterall, if every property was exposed, users could use standard bean configuration. While

docs.spring.io

 

필터체인을 그대로 복사해서 가져올게요~

이거 복사하라는 뜻,,


[SecurityConfig]

퍼블릭은 뺀다!!

빈으로 등록할건데 퍼블릭이 먼 의미가 있니,,?

사실 예전에는 제거하라고 안 나왔지만, 최근에는 제거하라고 나옵니다!

그리고 모두 임포트 해주자고요.

폼 로그인, httpBasic은 아직 안쓰니 일단 다 지워줄게요.

@EnableWebSecurity
public class SecurityConfig {

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests(authorize -> authorize
			.anyRequest().authenticated()
            );
                
        return http.build();
    }
}

위에 어노테이션은 웹세큐리티로 설정해줍니다!

authorize -> authorize
			.anyRequest().authenticated()

이것이 웹 세큐리티에서의 디폴트입니다~ withDefault 굳이 쓸 필요X,,

 

[PasswordEncoder]

passwordEncoder는 인터페이스로 만들고요, 리턴값으로 아무거나 써도 될거같긴하지만!

가장 무난한 BcryptPasswordEncoder로 설정하겠습니다.

BcryptPasswordEncoder

모든 패스워드 인코더가 다르게 되고,

복호화가 안되기 때문에! 유출이 되더라도 비번을 알 수 없습니다.
4부터 31까지 강도설정이 가능하고, 만약 아무것도 주지 않는다면 기본은 10으로 설정됩니다.

/* @param strength the log rounds to use, between 4 and 31*/
	public BCryptPasswordEncoder(int strength) {
		this(strength, null);
	}

솔트에 따라서,, 뭘 치냐에 따라서 암호화가 달라져요.

@Bean
	PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

이렇게 설정해줍니다.

 

[권한 설정]

다시 필터 체인으로 와서! 퍼밋 올 해줄건데요, 홈으로 들어오는거 일단 다 허용한단 뜻입니다.

 http.authorizeRequests(authorize -> 
        			authorize
        				.antMatchers("/").permitAll()
        				.anyRequest().authenticated()

permitAll 은 모두에게. 아무나!!

authenticated는 권한있는 유저에게만. 인증되어있는 유저에게만

하고나면?

일케 나옵니다.

왜요? 모두에게 인덱스로 들어오라고 이야기 해주었기 때문이죠!

.antMatchers("/").permitAll() 가 없다면?

액세스 거부..!!

그러나 여기에 formlogin을 추가한다면?

기존에 있는 폼을 불러오게 되겠죠?

이 폼은 스프링 시큐리티에 있는 그 폼입니다~~  이렇게 나오게 됩니다!

 

 form 쓰는 법
1) " . "으로 이어서 하기
2) " ; " 으로 마무리한 후 http.formLogin을 주기
http.authorizeRequests(authorize -> 
        			authorize
        				//.antMatchers("/").permitAll()
        				.anyRequest().authenticated()
    			)
        	.formLogin();
///////////////
http.authorizeRequests(authorize -> 
        			authorize
        				//.antMatchers("/").permitAll()
        				.anyRequest().authenticated()
    			);
       http.formLogin();

 

 

- hasRole.

롤을 주어서 그 역할에 맞는 사람에게만 접근 허용을 해줍니다. EX) GUEST/ADMIN/MANAGER etc..

볼가요

.antMatchers("/").permitAll()
.antMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()

 

주의❗❗

 : 굳이 ROLE_ADMIN 이라고 쓰지 않습니다~! 자동으로 들어가 있으니까요! ⬇참고!⬇

If you do not want to have role prefix (default "ROLE_") automatically inserted see hasAuthority(String).
Parameters:
role the role to require (i.e. USER, ADMIN, etc). Note, it should not start with role prefix as this is automatically inserted.

❗순서에도 주의가 필요합니다.

먼저 쓰여진 코드가 먼저 적용됩니다! 그러니까 아무한테나 다 해줄때는 생각을하고 하도록 합시다.

authenticated를 먼저 주고 permitAll을 준다면, admin이 먼저 적용되기때문에 애가 admin만 들어가게 되는 불상사가,, 

그러니 뇌에 힘주기 약속~!!


/*코드 보기*/

 

-security

@EnableWebSecurity
public class SecurityConfig {
	
	@Bean
	PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();//10
	}

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    	
    	http
    		//url 설정
    		.authorizeRequests(authorize -> 
        			authorize
        				.antMatchers("/","/signup").permitAll()//Specify that URLs are allowed by anyone.
        				.antMatchers("/admin").hasRole("ADMIN")//'ROLE_'자동으로 삽입됩니다. 빼고 파라미터 정의
        				.anyRequest().authenticated()//Specify that URLs are allowed by any authenticated user.
    			)
    		//로그인페이지: 인증이 필요한 주소에 접근시 이동.
        	.formLogin();
        		
        //http.csrf().disable();
    	
        return http.build();
    }

}

회원 가입 기능 구현

https://hwangsally.tistory.com/63

 

'애플리케이션 설계 및 테스트' 카테고리의 다른 글

스프링 시큐리티 -회원가입  (0) 2022.07.14