Security
This commit is contained in:
14
pom.xml
14
pom.xml
@@ -50,6 +50,20 @@
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.querydsl/querydsl-apt -->
|
||||
<dependency>
|
||||
<groupId>com.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.querydsl/querydsl-jpa -->
|
||||
<dependency>
|
||||
<groupId>com.querydsl</groupId>
|
||||
<artifactId>querydsl-jpa</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.security.basic.configure;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
|
||||
|
||||
@Configuration
|
||||
@EnableJpaAuditing
|
||||
public class JpaConfiguration {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
||||
@Bean
|
||||
public JPAQueryFactory jpaQueryFactory () {
|
||||
return new JPAQueryFactory(em);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebMvcConfigure implements WebMvcConfigurer {
|
||||
public class WebMvcConfiguration implements WebMvcConfigurer {
|
||||
|
||||
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
|
||||
"classpath:/static/", "classpath:/public/", "classpath:/", "classpath:/resources/", "classpath:/META-INF/resources/", "classpath:/META-INF/resources/webjars/"
|
||||
@@ -1,12 +1,15 @@
|
||||
package com.security.basic.persistence.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Collection;
|
||||
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@Table(name = "privileges")
|
||||
@@ -19,7 +22,7 @@ public class Privilege {
|
||||
|
||||
private String name;
|
||||
|
||||
@ManyToMany(mappedBy = "privileges")
|
||||
@ManyToMany(mappedBy = "privileges", fetch = FetchType.EAGER)
|
||||
private Collection<Role> roles;
|
||||
|
||||
public Privilege(final String name) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.security.basic.persistence.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.*;
|
||||
@@ -19,7 +21,7 @@ public class Role {
|
||||
|
||||
private String name;
|
||||
|
||||
@ManyToMany(mappedBy = "roles")
|
||||
@ManyToMany(mappedBy = "roles", fetch = FetchType.EAGER)
|
||||
private Collection<User> users;
|
||||
|
||||
@ManyToMany
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.security.basic.persistence.model;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Collection;
|
||||
@@ -10,6 +8,8 @@ import java.util.Collection;
|
||||
|
||||
@Entity
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@Table(name = "users")
|
||||
|
||||
@@ -39,12 +39,12 @@ public class WebSecurityConfigure {
|
||||
//permitAll시 해당 url에 대한 인증 정보를 요구하지 않는다.
|
||||
//authenticated시 해당 url에는 인증 정보를 요구한다.(로그인 필요)
|
||||
//hasAnyRole시 해당 url에는 특정 권한 정보를 요구한다.
|
||||
// http
|
||||
// .authorizeRequests()
|
||||
// .antMatchers("/login", "/home").permitAll()
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/home").permitAll()
|
||||
// .antMatchers("/user").hasAnyRole("USER", "ADMIN")
|
||||
// .antMatchers("/admin").hasAnyRole("ADMIN")
|
||||
// .anyRequest().authenticated();
|
||||
.anyRequest().authenticated();
|
||||
|
||||
http
|
||||
.authorizeHttpRequests()
|
||||
|
||||
@@ -9,7 +9,9 @@ import com.security.basic.persistence.model.User;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.security.basic.web.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
@RequiredArgsConstructor
|
||||
public class UserController {
|
||||
|
||||
@GetMapping("/home")
|
||||
public String home() {
|
||||
return "/home";
|
||||
}
|
||||
|
||||
@PreAuthorize("hasRole('USER')")
|
||||
@GetMapping("/user")
|
||||
public String user() {
|
||||
return "/user";
|
||||
}
|
||||
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping("/admin")
|
||||
public String admin() {
|
||||
return "/admin";
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAnyAuthority('READ','WRITE')")
|
||||
@GetMapping("/read")
|
||||
public String read() {
|
||||
return "/read";
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAnyAuthority('WRITE')")
|
||||
@GetMapping("/write")
|
||||
public String write() {
|
||||
return "/write";
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
# Server Port
|
||||
server.port=8008
|
||||
|
||||
# DataSource Setting
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/basic_security?autoReconnect=true
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
server.port=8008
|
||||
|
||||
# JPA Setting
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.generate-ddl=false
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
|
||||
spring.jpa.properties.hibernate.format_sql=true
|
||||
spring.jpa.properties.hibernate.id.new_generator_mappings=false
|
||||
|
||||
# Logging
|
||||
spring.output.ansi.enabled=always
|
||||
|
||||
# Redis
|
||||
spring.data.redis.repositories.enabled=false
|
||||
#Thymeleaf
|
||||
spring.thymeleaf.cache=false
|
||||
spring.thymeleaf.check-template-location=true
|
||||
spring.thymeleaf.prefix=classpath:/templates/
|
||||
spring.thymeleaf.suffix=.html
|
||||
|
||||
# Security
|
||||
spring.main.allow-bean-definition-overriding=true
|
||||
17
src/main/resources/templates/admin.html
Normal file
17
src/main/resources/templates/admin.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html lang="kr" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta data-n-head="true" name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<title>SecurityExample</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ADMIN</h1>
|
||||
<script type="text/javascript">
|
||||
// window.setTimeout(document.getElementById('loginForm').submit(), 1);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
17
src/main/resources/templates/expired.html
Normal file
17
src/main/resources/templates/expired.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html lang="kr" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta data-n-head="true" name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<title>SecurityExample</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>EXPIRED</h1>
|
||||
<script type="text/javascript">
|
||||
// window.setTimeout(document.getElementById('loginForm').submit(), 1);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
17
src/main/resources/templates/home.html
Normal file
17
src/main/resources/templates/home.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html lang="kr" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta data-n-head="true" name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<title>SecurityExample</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>HOME</h1>
|
||||
<script type="text/javascript">
|
||||
// window.setTimeout(document.getElementById('loginForm').submit(), 1);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
17
src/main/resources/templates/read.html
Normal file
17
src/main/resources/templates/read.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html lang="kr" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta data-n-head="true" name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<title>SecurityExample</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>READ</h1>
|
||||
<script type="text/javascript">
|
||||
// window.setTimeout(document.getElementById('loginForm').submit(), 1);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
17
src/main/resources/templates/user.html
Normal file
17
src/main/resources/templates/user.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html lang="kr" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta data-n-head="true" name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<title>SecurityExample</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>USER</h1>
|
||||
<script type="text/javascript">
|
||||
// window.setTimeout(document.getElementById('loginForm').submit(), 1);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
17
src/main/resources/templates/write.html
Normal file
17
src/main/resources/templates/write.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html lang="kr" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta data-n-head="true" name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<title>SecurityExample</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>WRITE</h1>
|
||||
<script type="text/javascript">
|
||||
// window.setTimeout(document.getElementById('loginForm').submit(), 1);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user