# 7. Spring Security 4 JDBC 를 이용한 로그인 인증방법

* 인터넷에 너무 복잡하게 하시는 것 같아 간단하게 쓰실 분들에게 좋을 것 같습니다.

## 시나리오

SpringSecurity4 를 이용하여 JDBC 로그인을 손쉽게 구현을 해봅니다.

JPA, BCrypt 를 사용하였습니다.

* Spring Security Config 가 제일 중요합니다.

## Member Model

```
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String mid;
    private String mpw;  

    @OneToMany(cascade=CascadeType.ALL,fetch = FetchType.EAGER)
    @JoinColumn(name="mem_no")
    private List<MemberRole> roles;
```

Member 모델에는 다음과 같이 mid(유저 아이디) , mpw(유저 패스워드), Role(권한) => 저는 권한을 여러개 주고 싶어서 이렇게 한것이기 때문에 상황에 맞게 바꾸시면 됩니다

## Member Role

```
public class MemberRole {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long fno;

    private String roleName;
}
```

Member Role은 Member의 권한을 나타냅니다.

* SpringBoot role 조건

  DB에 저장하실 때는 ROLE\_ADMIN, ROLE\_MEMBER 와 같이 저장하셔야 합니다.

SecurityConfig 하단에서 더 설명합니다.

## Login View

```
<form method="post" action="/login">
    <input type="text" id="username" name="username">
    <input type="password" id="password" name="password">
    <input type="submit">
</form>
```

로그인 뷰는 다음과 같이 합니다.

## Controller

```
    @RequestMapping("/login")
    public void login() {

    }
    // 로그인 실패처리 
    @GetMapping("/login?error")
    public String fail() throws IOException{
        return "redirect:/?error";
    }
```

본인의 경우 다음과 같이 Controller를 구성하였습니다.

## Spring Security Config \*\*

```
@Override
public void configure(HttpSecurity http) throws Exception {        

  http.authorizeRequests().formLogin().loginPage("/")
    .loginProcessingUrl("/login").permitAll()
    .failureUrl("/?error") // default
    .usernameParameter("username")
        .passwordParameter("password")
    .permitAll()
    .defaultSuccessUrl("/admin/home")
}

@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    final String usernameQuery = "select mid as username,mpw as password,enabled from {Member테이블 이름} where mid=?";
    final String authQuery = "select a.mid as username,b.role_name as authority from {Member테이블 이름} as a , {MemberRole 테이블 이름} as b where a.id=b.mem_no and a.mid=?";
    auth.jdbcAuthentication()
        .dataSource(dataSource)
        .usersByUsernameQuery(usernameQuery)
        .authoritiesByUsernameQuery(authQuery)
        .passwordEncoder(passwordEncoder());    
}

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}
```

URL에 대한 권한을 설정할 때 hasRole("{권한}") 함수를 사용하게 되는데 이때, {권한}에는 ADMIN,MEMBER 등등이 사용됩니다.

하지만 DB에 저장하실때는 'ROLE\_' 을 꼭 붙여야 됩니다.!!

다음 코드를 확인하셔서 진행하시는 프로젝트를 성공하시기 바랍니다. 감사합니다.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://djunnni.gitbook.io/springboot/2019-10-05.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
