Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- SPC
- Eclipse
- Android
- xPlatform
- plugin
- IntelliJ
- SSL
- Express
- MSSQL
- tomcat
- R
- JavaScript
- Spring
- NPM
- mybatis
- GIT
- vaadin
- 보조정렬
- window
- 공정능력
- table
- SQL
- es6
- mapreduce
- Python
- hadoop
- Java
- react
- Sqoop
- Kotlin
Archives
- Today
- Total
DBILITY
spring boot security jdbcdatasource 본문
반응형
이전에는 inMemory와 사용자 정의 인증을 살펴보았다.
이번에는 jdbcAuthentication을 사용해 보자.
dependancy를 추가한다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
application.properties에 h2 database설정 및 관련 테이블과 데이터 생성을 추가한다.
#mem base
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=- 1;DB_CLOSE_ON_EXIT=FALSE
#file base
#spring.datasource.url=jdbc:h2:file:/data/testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.datasource.initialization-mode=always
spring.datasource.schema=classpath*:schema.sql
spring.datasource.data=classpath*:data.sql
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
schema.sql
CREATE TABLE IF NOT EXISTS Member (
username VARCHAR(20) NOT NULL,
password VARCHAR(255) NOT NULL,
enabled BOOLEAN NOT NULL,
PRIMARY KEY(username)
);
CREATE TABLE IF NOT EXISTS Role (
username VARCHAR(20) NOT NULL,
authority VARCHAR(20) NOT NULL,
FOREIGN KEY(username) REFERENCES Member(username)
);
data.sql
INSERT INTO Member VALUES ('master','{bcrypt}$2a$10$MPuZy36Gzf9awY7czwUWAOAJmDZ1EA6tIsJEf6p/XHuzt8R532pSm',1);
INSERT INTO Member VALUES ('clerk','{noop}1234',1);
INSERT INTO Role VALUES ('master','ADMIN');
INSERT INTO Role VALUES ('master','USER');
INSERT INTO Role VALUES ('clerk','USER');
spring 5.0에선 password encoding시 PasswordEncoderFactories.createDelegatingPasswordEncoder를 사용하게 되는 게 구현 소스를 참고하자.
default는 BCryptPasswordEncoder를 사용한다.{noop}는 plaintext로 저장된 것이다.
ManuallySecurityConfiguration.java
package com.dbility.spring.cloud.security.config;
import javax.sql.DataSource;
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.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
@Configuration
@EnableWebSecurity
public class ManuallySecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.passwordEncoder(passwordEncoder())
.dataSource(dataSource)
.usersByUsernameQuery("select username,password,enabled from Member where username=?")
.authoritiesByUsernameQuery("select username,authority from Role where username=?")
.rolePrefix("ROLE_");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/nosecurity/datetime")
.permitAll()
.antMatchers("/h2-console/**").hasRole("ADMIN")
.anyRequest()
.authenticated()
.and()
.csrf().ignoringAntMatchers("/h2-console/**")
.and()
.headers().addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN))
.frameOptions().disable()
.and()
.httpBasic()
.and()
.formLogin();
}
@Bean(name = "passwordEncoder")
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
ManuallyErrorController.java
package com.dbility.spring.cloud.security.controller;
import java.util.HashMap;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
public class ManuallyErrorController implements ErrorController {
private static final String PATH = "/error";
@Override
public String getErrorPath() {
return PATH;
}
@RequestMapping(value = PATH)
public HashMap<String, Object> handleError(HttpServletRequest request) {
HashMap<String, Object> retMap = new HashMap<String, Object>();
Object statusCode = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
HttpStatus status = HttpStatus.valueOf(Integer.valueOf(statusCode.toString()));
Exception exception = (Exception)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
retMap.put("StatusCode", statusCode);
retMap.put("StatusMessage", status);
retMap.put("ErrorMessage", exception != null ? exception.getMessage(): "NA");
if(log.isDebugEnabled()) {
log.debug("Error --> {}", retMap);
}
return retMap;
}
}
권한이 없는 경로에 접근시 다음과 같이 json data가 반환된다.
{"ErrorMessage":"NA","StatusCode":403,"StatusMessage":"FORBIDDEN"}
반응형
'java > spring cloud' 카테고리의 다른 글
spring boot security mybatis (0) | 2019.09.23 |
---|---|
spring boot security (0) | 2019.09.18 |
Authentication is required but no CredentialsProvider has been registered (0) | 2019.09.18 |
spring boot actuator + prometheus + grafana visualization (0) | 2019.09.16 |
spring boot actuator + embedded mongodb (0) | 2019.09.04 |
Comments