[Spring-Framework] 16. Spring MVC, Spring Security 5.4, Oracle - 보안처리(로그인-Java) (1)
이번에 소개할 프로젝트는 13, 14, 15번 게시글을 Java 방식으로 구현한 프로젝트이다.
동일하게 진행할 것이다. 실질적으로 제대로 소개하고 있는 책이나 게시글은 찾아보질 못했다.
많은 오류가 있었다는 이야기이다.
순수한 Spring-Framework에서도 Spring Security를 원만히 잘 사용할 수 있도록 하는 게 글의 핵심이다.
이번 게시글도 양이 많아서 나눠서 작성하였으니 잘 따라해보면 도움이 될 것으로 보인다.
[작업환경]
[WAS(Web Application Server), 웹 애플리케이션 서버]
1. apache-tomcat-9.0.37-windows-x64
[DBMS(DataBase Management System - Tools]
2. sqldeveloper-19.2.1.247.2212-x64
[DB(DataBase)]
3. Oracle Databases 19.3.0.0
[IDE(Integration Development Environment)]
4. Spring-Tool Suites 4-4.7.2. Releases.
[Framework(프레임워크)]
5. spring-security-taglibs(5.4)
6. spring-security-config(5.4)
7. spring-security-web(5.4)
8. spring-security-core(5.4)
9. javax.servlet-api(4.0.1)
10. spring-webmvc(5.2.9.RELEASE)
11. spring-context(5.2.9.RELEASE)
12. Maven 3.6.3/1.16.0.20200610-1735
[Java]
OpenJDK-14.0.2 (https://openjdk.java.net/)
[이전 글 주제]
1. [Spring-Framework] 13. Spring MVC, Spring Security 5.4, Oracle - 보안처리(로그인-XML) (1)
- https://yyman.tistory.com/1419
2. [Spring-Framework] 13. Spring MVC, Spring Security 5.4, Oracle - 보안처리(로그인-XML) (2)
- https://yyman.tistory.com/1420
3. [Spring-Framework] 13. Spring MVC, Spring Security 5.4, Oracle - 보안처리(로그인-XML) (3) // 자동 로그인 유지, 유지 세션
1. XML 기반 프로젝트 vs 자바 기반 프로젝트
이번에 소개할 주제는 자바 기반 프로젝트이다.
이전 게시물과 지금 구현할 게시물의 차이점에 대해서 간단하게 소개하겠다.
그림 1. XML 방식 |
그림 2. 자바 방식(Java) |
(특징) - web.xml 파일이 있음. - 기본 프로젝트 pom.xml을 별도로 설정하지 않아도 됨. | (특징) - web.xml 파일이 없음. - 기본 프로젝트 생성 후 pom.xml을 별도로 설정해야 함. |
(구현 난이도) 무난함. (셋팅 값 및 지정된 변수 등을 잘 사용하는 것이 매우 중요함) - 적당한 지식이면 무난할 것으로 보임. | (구현 난이도) 머리를 조금 사용해야 함. - 많은 프로그래밍 지식이 다소 필요함. |
사용해보면, 장/단점이 있음. -> 간단하게 관리하는 면에서는 편할 수도 있음. (xml) -> 튜닝에 있어서 제약이 있을 수도 있음. | ...... |
[이전 - XML 기반 게시글]
1. [Spring-Framework] 13. Spring MVC, Spring Security 5.4, Oracle - 보안처리(로그인-XML) (1), 2020. 9. 26
https://yyman.tistory.com/1419
2. [Spring-Framework] 13. Spring MVC, Spring Security 5.4, Oracle - 보안처리(로그인-XML) (2), 2020. 9. 26
https://yyman.tistory.com/1420
3. [Spring-Framework] 13. Spring MVC, Spring Security 5.4, Oracle - 보안처리(로그인-XML) (3), 2020. 9. 26
2. 결과(1) - (Result)
출력 결과는 이전 프로젝트(13, 14, 15번)과 동일하게 구현 하였다.
그림 3. 결과(자바 버전) - 메인
그림 4. 결과(자바 버전) - 로그인 폼
그림 5. 결과(자바 버전) - 로그인 실패
그림 6. 결과(자바 버전) - 로그인 후
그림 7. 결과(자바 버전) - 비밀번호 출력의 예(암호화 패키지) - 업데이트 전
그림 8. 결과(자바 버전) - 로그인 후 모습 - 업데이트 전
그림 9. 결과(자바 버전) - 권한이 없는 계정이 특정 페이지를 접속할 때 모습(1) // 순정 (업데이트 전)
그림 9-1. 결과(자바 버전) - 권한이 없는 계정이 특정 페이지를 접속할 때 모습(2) // 커스텀 (업데이트 완료함)
그림 9-2. 결과(자바 버전) - 권한이 있는 계정의 메뉴 모습 // 커스텀 (업데이트 함)
그림 9-3. 결과(자바 버전) - 권한이 없는 계정의 메뉴 모습 // 커스텀 (업데이트 함)
3. 결과(2) - 프로젝트 구성
프로젝트 구성에 대한 것이다.
상당히 양이 많다. 초기 셋팅만 잘 해주면, 나머지는 순조로울 것으로 보인다.
그림 10, 11. 프로젝트 구성
다소 구현할 양이 많다는 것을 확인할 수 있다.
완성된 프로젝트 구성에 대해서 살펴보는 것은 무엇을 진행할 것인지 예상할 수 있는 방법 중 하나라고 주장해본다.
4. 데이터베이스 설계
그림 12. ER-D
테이블을 작성하는 데, 순번을 대략적으로 잡아본 이유는 외래키, 참조키 등에 기준이 되는 테이블을 먼저 생성하고 작업하는 것이 좋기 때문이다.
편집해서 외래키, 참조키 등 지정해줘도 무방하다. 단, 무결성이나 각종 조건 등 때문에 데이터가 존재하지 않은 상태에서 진행해야 한다.
그림 13. 테이블: COMP_GROUP
그림 14. 테이블: COMP_USERS
그림 15. 테이블: COMP_GROUP_AUTHORITIES
그림 16. 테이블: COMP_GROUP_MEMBERS
그림 17. 테이블: COMP_AUTHORITIES
그림 18. 테이블: PERSISTENT_LOGINS
5. 테이블 - SQL(Create table - DML)
테이블 작성에 관한 사항이다.
CREATE TABLE comp_users (
username VARCHAR(50) NOT NULL,
password VARCHAR(300) NOT NULL,
enabled INT NOT NULL,
PRIMARY KEY (username)
);
CREATE TABLE comp_authorities (
username VARCHAR(50) NOT NULL,
authority VARCHAR(50) NOT NULL,
CONSTRAINT fk_authorities_users FOREIGN KEY (username) REFERENCES comp_users (username)
);
CREATE TABLE comp_groups(
id VARCHAR2(20) NOT NULL,
group_name VARCHAR2(20) NULL
);
CREATE TABLE comp_group_authorities(
group_id VARCHAR2(20) NOT NULL,
authority VARCHAR2(20) NOT NULL
);
CREATE TABLE comp_group_members(
group_id VARCHAR2(20) NOT NULL,
username VARCHAR2(20) NOT NULL
);
CREATE TABLE persistent_logins (
username VARCHAR(64) NOT NULL,
series VARCHAR(64) PRIMARY KEY,
token VARCHAR(64) NOT NULL,
last_used TIMESTAMP NOT NULL
);
-- 계정
INSERT INTO comp_users (username, password, enabled) VALUES ('user', '$2a$10$x04djNV2e9rpcPPRyXoLk.rMm6iZe2/vYdzpqHQcLeNSYdt7kc30O', 1);
INSERT INTO comp_users (username, password, enabled) VALUES ('admin', '$2a$10$QUddY3O/6ZgkYCR6MFlv9.nqA501Fm0cc/ZxQHX5pwb1o0CYCTiIS', 1);
-- 사용자 권한
INSERT INTO comp_authorities (username, authority) VALUES ('user', 'ROLE_ADMIN');
INSERT INTO comp_authorities (username, authority) VALUES ('admin', 'ROLE_USER');
-- 그룹
INSERT INTO comp_groups (id, group_name) VALUES ('G01', '관리자 그룹');
INSERT INTO comp_groups (id, group_name) VALUES ('G02', '사용자 그룹');
-- 그룹 권한
INSERT INTO comp_group_authorities (group_id, authority) VALUES ('G01', 'ROLE_ADMIN');
INSERT INTO comp_group_authorities (group_id, authority) VALUES ('G01', 'ROLE_USER');
INSERT INTO comp_group_authorities (group_id, authority) VALUES ('G02', 'ROLE_USER');
-- 그룹 회원
INSERT INTO comp_group_members (group_id, username) VALUES ('G01', 'user');
INSERT INTO comp_group_members (group_id, username) VALUES ('G02', 'admin');
파일명: sampleDb-oracledb.sql
[첨부(Attachments)]
비고: 꼭 오라클만 되는 것은 아니고, 살짝 튜닝하면 MySQL 등에서도 사용할 수 있는 형태로 작성하였다.
(SQL 명령어가 일부 데이터베이스에서는 차이가 있을 수도 있음. 특정 DB의 함수 등)
6. 프로젝트 - 신규 생성하기
Spring-Legacy-Project를 생성한다.
그림 19. 테이블: Spring MVC Project 생성하기
Spring MVC Project를 선택한다.
Project Name의 항목을 입력한다.
Next를 누른다.
그림 20. 테이블: Spring MVC Project 생성하기
top-level-package를 입력한 후 Finish를 누른다.
7. 프로젝트 - pom.xml 수정작업
양이 많긴 하지만, 작성해본다.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springMVC</groupId>
<artifactId>javaSecurity5</artifactId>
<name>SpringSecurity5-Java</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<!-- web.xml 사용 안함 표기 -->
<failOnMissingWebXml>false</failOnMissingWebXml>
<java-version>14</java-version>
<org.springframework-version>5.2.9.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-taglibs -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>5.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.7.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
그림 21. pom.xml 파일 선택 후 마우스 오른쪽 버튼 메뉴 모습
pom.xml을 선택한다.
마우스 오른쪽 버튼을 누른다.
maven-> Add Dependency를 클릭한다.
그림 22. Add Dependency에서 Oracle 검색하기
8. 프로젝트 - web.xml, spring 폴더 제거 작업
파일: /src/main/web-app/WEB-INF/web.xml (삭제할 것)
폴더: /src/main/web-app/WEB-INF/spring (삭제할 것)
9. 프로젝트 - Build Path, Project factes 버전 바꾸기
초기 Spring MVC Project를 생성하면 1.6버전으로 설정되어 있다. 14버전으로 바꿔주겠다.
그림 23. Properties 속성 바꿔주기(1) / Build-Path - JavaSE 14로
JRE System Library [JavaSE-14]로 Edit 버튼을 통해서 수정해준다.
그림 23. Properties 속성 바꿔주기(2) / Project Factes - JavaSE 14로
Java 버전을 1.6에서 14로 바꿔준다.
10. Controller - web.xml 제거 (핵심작업)
web.xml 제거한 Spring MVC라는 주제로 접근하여 작성하려고 한다.
지금 작업, pom.xml 수정 작업을 중심으로 HomeController.java(Servlet) 파일을 구성해서 view파일 jsp를 만들면 web.xml없이 동작하는 화면을
볼 수 있다.
package com.springMVC.javaSecurity5.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpringMvcAnnotation extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
// bean 설정과 spring container 설정을 위한 Config 클래스를 등록한다.
// Config 클래스는 web.xml의 dispatcher servlet 초기화에 사용된 xml과 같은 기능을 한다.
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
// web.xml의 servlet mapping 부분을 대체한다.
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
파일명: SpringMvcAnnotation.java
[첨부(Attachments)]
이 파일을 시작점으로 한다.
package com.springMVC.javaSecurity5.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@EnableWebMvc // <mvc:annotation-driven>에 해당.
// @ComponentScan(basePackages = {"com.figo.web"}) // <context:component-scan base-package="”com.figo.web”/">에 해당됨.
@ComponentScan("com.springMVC.javaSecurity5")
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
// <resources mapping="/resources/**" location="/resources/">에 해당됨.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/").setCachePeriod(31556926);
}
// <mvc:default-servlet-handler>에 해당됨.
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
// web.xml에서 봤던 내용들임.
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
/*
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// registry.addViewController("/web").setViewName("home");
registry.addViewController("/").setViewName("home");
}
*/
}
파일명: WebConfig.java
[첨부(Attachments)]
참고: HomeController의 초기내용으로 두고 서버 상에서 실행시켜봤다면, 동작했을 것으로 보인다.
(10번까지 잘 따라왔으면 화면 출력을 볼 수 있음.)
11. Controller - HomeController.java
HomeController에 관한 내용이다. 자세히 보면, "13, 14, 15번"글하고 거의 동일하다는 것을 알 수 있다.
쉽게 이야기하면, web.xml 파일부터 xml로 구성된 환경설정 파일을 프로젝트 내에서 제거한 것이다.
그러니 Controller 등은 동일할 수 밖에 없다고 본다.
package com.springMVC.javaSecurity5.controller;
import java.security.Principal;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
//@CrossOrigin(origins = "*", allowedHeaders = "*")
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@RequestMapping("/")
public String home(Locale locale, Model model, Principal principal) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
String username = null;
// Principal 예제
if (principal != null) {
username = principal.getName();
System.out.println("타입정보 : " + principal.getClass());
System.out.println("ID정보 : " + principal.getName());
}
model.addAttribute("username", username);
model.addAttribute("serverTime", formattedDate );
return "home";
}
@RequestMapping("/admin")
public String admin(Locale locale, Model model) {
return "admin";
}
@RequestMapping(value = "/encode-password", method = RequestMethod.GET)
public String passwordEncode(Locale locale, Model model, HttpServletRequest req) {
// 1. xml 방식에서 java 방식으로 전환
// web.xml 파일 제거로 인한 사용 불가(ServletConfig sc 연결됨)
// WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(req.getServletContext());
// PasswordEncoder passwordEncoder = context.getBean(PasswordEncoder.class);
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String password = req.getParameter("password");
String encode = passwordEncoder.encode(password);
model.addAttribute("encode", encode);
System.out.println(encode);
return "home";
}
}
파일명: HomeController.java
[첨부(Attachments)]
12. Controller - AdminController.java
관리자 페이지에 관한 내용이다.
package com.springMVC.javaSecurity5.controller;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class AdminController {
private static final Logger logger = LoggerFactory.getLogger(AdminController.class);
@RequestMapping(value = "/admin/home", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome - 관리자 페이지(Admin Home)!");
return "admin/home";
}
}
파일명: AdminController.java
[첨부(Attachments)]
13. Controller - MemberController.java
MemberController.java에 관한 내용이다.
package com.springMVC.javaSecurity5.controller;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class MemberController {
// 커스텀 페이지 - 양식만
private static final Logger logger = LoggerFactory.getLogger(MemberController.class);
@RequestMapping(value = "/member/loginForm")
public String loginForm(Locale locale, Model model) {
logger.info("안녕 - 로그인 폼(Hello - Login Form");
// model.addAttribute("serverTime", formattedDate );
return "member/loginForm";
}
@RequestMapping(value = "/member/accessDenied")
public String accessDenied(Locale locale, Model model) {
logger.info("접근 금지 - 이동(Accessed Denied)");
// model.addAttribute("serverTime", formattedDate );
return "redirect:/member/accessDeniedView";
}
@RequestMapping(value = "/member/accessDeniedView")
public String accessDeniedView(Locale locale, Model model) {
logger.info("접근 금지 - 출력(Accessed Denied)");
// model.addAttribute("serverTime", formattedDate );
return "member/accessDenied";
}
}
파일명: MemberController.java
[첨부(Attachments)]
* 2부에서는
2부에서는 Spring-Security 설정에 대해서 집중적으로 다뤄보도록 하겠다.
조금 어려울 수도 있으니 마음을 편안하게 하고 따라해보면 좋겠다.
1. [Spring-Framework] 16. Spring MVC, Spring Security 5.4, Oracle - 보안처리(로그인-Java) (2), 2020-09-27