http://ojc.asia/bbs/board.php?bo_table=LecSpring&wr_id=848
ojc.asia

(동영상,스프링프레임워크MVC5, 스프링시큐리티5, 하이버네이트5, 마리아DB 로그인 예제 실습)Spring MVC5,Security5, Hibernate5, Login
Spring Security는 스프링 기반 어플리케이션의 인증과 권한을 담당하는 프레임워크 입니다. 다음의 간단한 예제를 작성해 봄으로서 기본적인 동작원리를 이해해 보세요.
n 실습환경
JDK1.8 STS 4.7.1 Spring-Webmvc 5.2.3 Spring Security 5.2.3 Hibernate 5.2.17.Final C3p0 0.9.5.2 Servlet API 3.1.0 Apache Tomcat 9 MariaDB 10.5.5 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n 실행화면

사진 삭제
사진 설명을 입력하세요.
n 프로젝트 구조
전송중...
사진 설명을 입력하세요.
nDB 스키마(마리아 DB에 test 라는 DB 생성 후 아래 스크립트 실행)
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
DROP TABLE auth ; DROP TABLE user ; CREATE TABLE user( uname varchar(50) not null primary key, pwd varchar(100) not null, enabled boolean not null ); CREATE TABLE auth ( uname varchar(50) not null, role varchar(50) not null, constraint fk_auth_user foreign key(uname) references user(uname) ); -- user1 -- pwd : 1234 insert into user(uname,pwd,enabled) values('user1','$2a$10$fZL/N/Xotw.zH2n8A/JbUugjC4SegtDKzh2t.GTAauv5k8WRljApa', true); insert into auth(uname,role) values('user1','ROLE_USER'); -- user2 -- USER or ADMIN Role은 없다. -- pwd : 1234 insert into user(uname,pwd,enabled) values('user2','$2a$10$fZL/N/Xotw.zH2n8A/JbUugjC4SegtDKzh2t.GTAauv5k8WRljApa', true); -- admin -- pwd : "admin@123" insert into user(uname,pwd,enabled) values('admin','$2a$10$hbxecwitQQ.dDT4JOFzQAulNySFwEpaFLw38jda6Td.Y/cOiRzDFu',true); insert into auth(uname,role) values('admin','ROLE_ADMIN'); insert into auth(uname,role) values('admin','ROLE_USER'); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n pom.xml
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>SpringSecurityExam</groupId> <artifactId>SpringSecurityExam</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <properties> <failOnMissingWebXml>false</failOnMissingWebXml> <spring.version>5.2.3.RELEASE</spring.version> <hibernate.version>5.2.17.Final</hibernate.version> <hibernate.validator>5.4.1.Final</hibernate.validator> <c3p0.version>0.9.5.2</c3p0.version> <mariadb.client.version>1.5.7</mariadb.client.version> <jstl.version>1.2.1</jstl.version> <tld.version>1.1.2</tld.version> <servlets.version>3.1.0</servlets.version> <jsp.version>2.3.1</jsp.version> <log4j.version>1.2.17</log4j.version> </properties> <dependencies> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>${c3p0.version}</version> </dependency> <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> <version>${mariadb.client.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlets.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>${jsp.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>javax.servlet.jsp.jstl-api</artifactId> <version>${jstl.version}</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>${tld.version}</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>${jsp.version}</version> </dependency> </dependencies> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.3</version> <configuration> <warSourceDirectory>WebContent</warSourceDirectory> </configuration> </plugin> </plugins> </build> </project> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n src/reources/db.properties
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
# MariaDB 접속설정 mysql.driver=org.mariadb.jdbc.Driver mysql.jdbcUrl=jdbc:mysql://localhost:3306/test?useSSL=false mysql.username=root mysql.password=mariadb # Hibernate 설정 # hbm2ddl : Entity 매핑을 기반으로 DB스키마 스크립트 생성 # validate는 Entity 매핑과 DB스키마가 같은데 검증만 수행 hibernate.show_sql=true hibernate.hbm2ddl.auto=validate #C3P0 properties hibernate.c3p0.min_size=2 hibernate.c3p0.max_size=10 hibernate.c3p0.acquire_increment=1 hibernate.c3p0.timeout=1200 hibernate.c3p0.max_statements=150 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n security/config/AppConfig.java
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
package security.config; import static org.hibernate.cfg.AvailableSettings.C3P0_ACQUIRE_INCREMENT; import static org.hibernate.cfg.AvailableSettings.C3P0_MAX_SIZE; import static org.hibernate.cfg.AvailableSettings.C3P0_MAX_STATEMENTS; import static org.hibernate.cfg.AvailableSettings.C3P0_MIN_SIZE; import static org.hibernate.cfg.AvailableSettings.C3P0_TIMEOUT; import static org.hibernate.cfg.AvailableSettings.DRIVER; import static org.hibernate.cfg.AvailableSettings.HBM2DDL_AUTO; import static org.hibernate.cfg.AvailableSettings.PASS; import static org.hibernate.cfg.AvailableSettings.SHOW_SQL; import static org.hibernate.cfg.AvailableSettings.URL; import static org.hibernate.cfg.AvailableSettings.USER; import java.util.Properties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.orm.hibernate5.HibernateTransactionManager; import org.springframework.orm.hibernate5.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; import security.model.Auth; import security.model.User; /** * 자바설정기반 * DB연결정보 및 하이버네이트 설정정보 로딩 * @author jclee * */ @Configuration @PropertySource("classpath:db.properties") //@EnableTransactionManagement 와 <tx:annotation-driven/>은 //빈의 @Transactional 을 찾아서 트랜잭션이 적용되게 합니다. @EnableTransactionManagement @ComponentScan({ "security" }) public class AppConfig { @Autowired private Environment env; @Bean public LocalSessionFactoryBean getSessionFactory() { LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean(); Properties props = new Properties(); // MariaDB 연결 정보 설정 props.put(DRIVER, env.getProperty("mysql.driver")); props.put(URL, env.getProperty("mysql.jdbcUrl")); props.put(USER, env.getProperty("mysql.username")); props.put(PASS, env.getProperty("mysql.password")); // 하이버네이트 속성 설정 props.put(SHOW_SQL, env.getProperty("hibernate.show_sql")); props.put(HBM2DDL_AUTO, env.getProperty("hibernate.hbm2ddl.auto")); // C3P0 속성 설정 props.put(C3P0_MIN_SIZE, env.getProperty("hibernate.c3p0.min_size")); props.put(C3P0_MAX_SIZE, env.getProperty("hibernate.c3p0.max_size")); props.put(C3P0_ACQUIRE_INCREMENT, env.getProperty("hibernate.c3p0.acquire_increment")); props.put(C3P0_TIMEOUT, env.getProperty("hibernate.c3p0.timeout")); props.put(C3P0_MAX_STATEMENTS, env.getProperty("hibernate.c3p0.max_statements")); factoryBean.setHibernateProperties(props); factoryBean.setAnnotatedClasses(User.class, Auth.class); return factoryBean; } @Bean public HibernateTransactionManager getTransactionManager() { HibernateTransactionManager transactionManager = new HibernateTransactionManager(); transactionManager.setSessionFactory(getSessionFactory().getObject()); return transactionManager; } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n security/config/DispatcherConfig.java
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
package security.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @author jclee * 디스패처 서블릿의 설정파일 * * 스프링 MVC 빈설정, 뷰리졸버 설정 * 스프링시큐리티에 위해 Default 로그인 페이지로 렌더링될 뷰를 지정 * 디스패처 서블릿의 설정을 위한 XML파일의 역할을 하는 자바설정 기반의 파일 */ @Configuration @EnableWebMvc //Spring MVC에서 빈설정을 자동으로 해준다. 필요한 빈 등록 //@Controller, @Service등에서 빈을 검색할 기본 패키지경로 지정 @ComponentScan(basePackages = { "security" }) public class DispatcherConfig implements WebMvcConfigurer { /** * JSP ViewResolver를 등록 */ @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.jsp().prefix("/WEB-INF/views/").suffix(".jsp"); } /** * 스프링시큐리티에 위해 로그인이 안된 사용자는 main.jsp에 진입할 수 없고 * /login으로 요청을 보내는데, 이때 login.jsp가 로딩 * 컨트롤러에서 별도의 요청처리를 하지않고 addViewControllers를 재정의하면 됨 * 뷰컨트롤러를 설정한다. */ @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/login").setViewName("login"); } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n security/config/SecurityWebApplicationInitializer.java
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
package security.config; import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; /** * springSecurityFilterChain 필터를 등록 * @author jclee * */ public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n security/config/WebSecurityConfig.java
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
package security.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; 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.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; /** * 스프링 시큐리티 설정파일 * WebSecurityConfigurerAdapter를상속받고 configure() 메소드를 오버라이드를 재정의 * * @author jclee * */ //----------------------------------------------------------------- // @EnableWebSecurity은 SpringSecurityFilterChain이 자동으로 포함되게 한다. // 스프링시큐리티 사용을 위한 어노테이션 //----------------------------------------------------------------- @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder()); } @Override protected void configure(HttpSecurity http) throws Exception { // authorizeRequests : 요청에 따른 권한을 지정 // hasRole() or hasAnyRole() : 특정 권한을 가지는 사용자만 접근할 수 있다. // permitAll() or denyAll() : 접근을 전부 허용하거나 제한한다. http.authorizeRequests().antMatchers("/login**").permitAll() .and() // 스프링 시큐리티의 로그인 처리 모두에게 요청 허용되며 // /loginAction 요청이며 이는 login화면의 Form태그에 정의됨 .formLogin().loginPage("/login").loginProcessingUrl("/loginAction").permitAll() .and() // 로그아웃은 모든 사용자에게 접근이 호용되며 성공시 /login 즉 로그인 페이지로 이동한다. .logout().logoutSuccessUrl("/login").permitAll() .and() .authorizeRequests().antMatchers("/admin").hasRole("ADMIN") .and() // 이 예제의 모든 요청은 ADMIN, USER롤이 있어야 한다. // user2는 ADMIN or USER Role이 없으므로 접근 못한다. .authorizeRequests().anyRequest().hasAnyRole("ADMIN", "USER") .and() // 접근권한이 없어 발생하는 403 ForBidden 오류 처리 .exceptionHandling() .accessDeniedPage("/WEB-INF/views/403.jsp") .and() .csrf().disable(); } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n security/config/WebAppInit.java
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
package security.config; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; /** * web.xml에 대응되는 자바기반 설정파일 생성 * * DispatcherServlet과 애플리케이션의 서블릿 컨텍스트내의 스프링 애플리케이션 컨텍스트를 설정. * * AbstractAnnotationConfigDispatcherServletInitializer는 두개의 자바빈 관리자를 생성하는데 * DispatcherServlet(자식 컨텍스트)과 ContextLoaderListener(부모 컨텍스트)를 생성. * * DispatcherServlet은 컨트롤러, 뷰 리졸버, 핸들러 매핑과 같은 웹 컴포넌트가 포함된 빈을 로딩 * ContextLoaderListener는 애플리케이션 내의 그 외의 다른 빈을 로딩 또는 DispatcherServlet이 * 여럿인 경우 한번에 설정을 로딩하기 위해 사용. */ public class WebAppInit extends AbstractAnnotationConfigDispatcherServletInitializer { // Root Web Application Context에 등록될 빈들 // Load database and spring security configuration @Override protected Class<?>[] getRootConfigClasses() { return new Class[] { AppConfig.class, WebSecurityConfig.class }; } // DispatcherServlet Context에 등록될 빈들 // Load spring web configuration @Override protected Class<?>[] getServletConfigClasses() { return new Class[] { DispatcherConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n security/model/User.java
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
package security.model; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import org.hibernate.annotations.Type; @Entity @Table(name = "USER") //테이블명 public class User { @Id @Column(name = "UNAME") private String uname; @Column(name = "PWD", nullable = false) private String pwd; // MySQL //@Column(name = "ENABLED", nullable = false) //private boolean enabled; //MariaDB @Type(type = "org.hibernate.type.NumericBooleanType") @Column(name = "ENABLED", nullable = false, columnDefinition = "TINYINT") private boolean enabled; //USER와 AUTH는 1:N 관계 @OneToMany(cascade = CascadeType.ALL, mappedBy = "user") private Set<Auth> auth = new HashSet<>(); public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public Set<Auth> getAuth() { return auth; } public void setAuth(Set<Auth> auth) { this.auth = auth; } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n security/model/Auth.java
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
package security.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name = "AUTH") //테이블명 public class Auth { @Id @Column(name = "ROLE") private String role; @ManyToOne @JoinColumn(name = "UNAME") private User user; public String getRole() { return role; } public void setRole(String role) { this.role = role; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n security/controller/SecurityController.java
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
package security.controller; import java.security.Principal; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @Controller public class SecurityContoller { @GetMapping("/") public String main(Model model, Principal principal, Authentication auth) { model.addAttribute("message1", "로그인 계정 : " + principal.getName()); model.addAttribute("message2", "부여받은 롤 : " + auth.getAuthorities()); return "main"; } @GetMapping("/admin") public String goAdmin(Model model, Principal principal, Authentication auth) { model.addAttribute("message1", "로그인 계정 : " + principal.getName()); model.addAttribute("message2", "부여받은 롤 : " + auth.getAuthorities()); return "admin"; } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n security/repository/UserDetailsDao.java
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
package security.repository; import security.model.User; public interface UserDetailsDao { User findUserByUsername(String uname); } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n security/repository/UserDetailsDaoImpl.java
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
package security.repository; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import security.model.User; @Repository public class UserDetailsDaoImpl implements UserDetailsDao { @Autowired private SessionFactory sessionFactory; @Override public User findUserByUsername(String uname) { return sessionFactory.getCurrentSession() .get(User.class, uname); } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n security/service/UserDetailsServiceImpl.java
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
package security.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.User.UserBuilder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import security.model.User; import security.repository.UserDetailsDao; /** * 스프링시큐리티의 UserDetailsService 인터페이스에는 DB에서 유저 정보를 불러오는 * 중요한 메소드가 존재하는데 loadUserByUsername() 메소드이다. * 이 메소드에서 유저 정보를 불러오는데, UserDetailsService 인터페이스를 구현하면 * loadUserByUsername() 메소드를 재정의하여 사용자의 정보를 가져온다. * * @author jclee * */ @Service("userDetailsService") public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private UserDetailsDao userDetailsDao; @Transactional(readOnly = true) @Override /** * UserDetails : 스프링시큐리티에서 사용자의 정보를 담는 인터페이스. * UserBuilder의 build 메소드를 통해 생성한다. */ public UserDetails loadUserByUsername(String uname) throws UsernameNotFoundException { User user = userDetailsDao.findUserByUsername(uname); UserBuilder builder = null; if (user != null) { // UserBuilder에 DB에서 읽은 정보를 넣고 UserDetails(사용자정보)를 생성한다. builder = org.springframework.security.core .userdetails.User.withUsername(uname); builder.disabled(!user.isEnabled()); builder.password(user.getPwd()); String[] authorities = user.getAuth() .stream().map(a -> a.getRole()).toArray(String[]::new); // 테이블에서 읽어온 정보를 토대로 UserDetails 인스턴스를 생성. builder.authorities(authorities); } else { throw new UsernameNotFoundException("User not found."); } return builder.build(); } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n WEB-INF/views/403.jsp
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
<%@ 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>스프링 시큐리티 로그인 실습</title> </head> <body> <h1>접근 권한이 없습니다.</h1> <form action="/" method="get"> <input value="Go Main" type="submit"> </form> </body> </html> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n WEB-INF/views/admin.jsp
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
<%@ 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>스프링 시큐리티 로그인 실습</title> </head> <body> <h1>관리자 페이지</h1> <h2>${message1}</h2> <h2>${message2}</h2> <form action="/logout" method="post"> <input value="Logout" type="submit"> </form> </body> </html> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n WEB-INF/views/login.jsp
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%> <%@taglib uri="http://www.springframework.org/tags" prefix="spring"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=EUC-KR"> <title>스프링 시큐리티 로그인 실습</title> </head> <body> <h4>로그인폼</h4> <form action='<spring:url value="/loginAction"/>' method="post"> <table> <tr> <td>사용자명</td> <td><input type="text" name="username"></td> </tr> <tr> <td>비밀번호</td> <td><input type="password" name="password"></td> </tr> <tr> <td><button type="submit">Login</button></td> </tr> </table> </form> <br/> </body> </html> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n WEB-INF/views/main.jsp
셀 전체 선택
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
열 너비 조절
행 높이 조절
<%@ 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>스프링 시큐리티 로그인 실습</title> </head> <body> <h2>${message1}</h2> <!-- 로그인계정 --> <h2>${message2}</h2> <!-- 부여받은권한 --> <form action="/logout" method="post"> <input value="Logout" type="submit"> </form> <form action="/admin" method="get"> <input value="Go! Admin Page~" type="submit"> </form> </body> </html> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
댓글 없음:
댓글 쓰기