취미로 음악을 하는 개발자

[Spring Boot] Security 본문

공대인/Spring[Boot]

[Spring Boot] Security

영월특별시 2019. 8. 22. 17:47
728x90

프로젝트 생성




코드 구현


// build.gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
plugins {
    id 'org.springframework.boot' version '2.1.7.RELEASE'
    id 'io.spring.dependency-management' version '1.0.8.RELEASE'
    id 'java'
    id 'war'
}
 
group = 'com.study'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
 
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
 
repositories {
    mavenCentral()
}
ext['tomcat.version'] = '8.5.38'
 
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    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'
    implementation 'javax.servlet:jstl'
    implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
}
cs


// application.properties, jsp에 필요한 설정만 해준다.

1
2
3
4
server.port = 8081
# JSP
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.study.springboot;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
 
@Controller
public class MyController {
 
    @RequestMapping("/")
    public @ResponseBody String root() throws Exception {
        return "Security";
    }
    
    @RequestMapping("/guest/welcome")
    public String welcome1() {
        return "guest/welcome1";
    }
    
    @RequestMapping("/member/welcome")
    public String welcome2() {
        return "member/welcome2";
    }
    
    @RequestMapping("/admin/welcome")
    public String welcome3() {
        return "admin/welcome3";
    }
}
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.study.springboot.auth;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/css/**""/js/**""/img/**").permitAll()
                .antMatchers("/guest/**").permitAll()
                .antMatchers("/member/**").hasAnyRole("USER""ADMIN")
                .antMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated();
        
        http.formLogin().permitAll();
        
        http.logout().permitAll();
    }
    
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password(passwordEncoder().encode("1234")).roles("USER")
            .and()
            .withUser("admin").password(passwordEncoder().encode("1234")).roles("ADMIN");
            // ROLE_ADMIN 에서 ROLE_는 자동으로 붙음
    }
    
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
 
cs


[18~28번 줄]

루트, css, js, img, guest 폴더 아래에 있는 파일로 접근은 모두 허용

member 폴더 안으로 접근하려면 USERADMIN권한이 있는 자만 접근 허용

admin 폴더 안으로 접근하려면 ADMIN권한이 있는 자만 접근 허용

로그인과 로그아웃에 대해서는 모두 허용


[32~36번 줄]

user라는 id에 1234라는 암호를 가진 유저는 "USER"라는 권한을 갖고

admin이라는 id에 1234라는 암호를 가진 유저는 "ADMIN"이라는 권한을 가짐.


* 이 메소드는 테스트 용으로만 사용하는 것을 권장



// welcome1, 2, 3 .jsp

1
2
3
4
5
6
7
8
9
10
11
12
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8">
<title>Welcome</title>
</head>
<body>
welcome : Guest
</body>
</html>
cs


welcome2는 10번 줄의 Guest 대신 Member,

welcome3은 Admin으로 출력하게 한다.




처음 게스트 화면으로 가면 로그인 없이도 화면이 나오고



member에 접근하려면 "USER"나 "ADMIN"의 권한을 가진 유저의 로그인이 필요하다

user/1234 로 로그인하면 아래와 같은 화면이 나온다.



하지만 여기서 admin 화면으로 가려고 하면 아래와 같이 오류가 뜬다.



왜냐하면 "USER"의 권한으로는 admin에 접근할 수 없기 때문이다.



따라서, admin/1234로 다시 로그인을 하고 들어가야 아래와 같이 접근이 허용된다.




Comments