본문 바로가기
프로젝트/SpringSecurity

[Spring Security] 2. 로그인

by dantriss 2023. 6. 29.

유튜브에서 스프링시큐리티를 심화교육하면서 조금더 레벨업 하고자 한다.

IDE : IntelliJ

언어 : Java 8

스프링부트 버전 : 2.7.13

DB : MySQL

빌드관리 도구 : Maven

OS : iOS

참고유튜브 : 메타코딩


스프링시큐리티를 통해서 로그인하는 기능을 작성해보자

우선 loginForm.html에서 사용자가 입력한 username 과 password를 /login 으로 post형식으로 보내준다.

<form action="/login" method="POST">
    <input type="text" name="username" placeholder="id"/>
    <br>
    <input type="password" name="password" placeholder="password"/>
    <button>sing in</button>

</form>

 

SecurityConfig에서 loginProcessingUrl에 /login으로 작성해주면 /login으로 오는 주소를 시큐리티가 낚아채서 대신 로그인을 해준다.

그후 기본 페이지로 "/" 로 이동하게 설정해준다.

@Bean
    public SecurityFilterChain configure(HttpSecurity http) throws Exception{

        http.authorizeRequests()
                .antMatchers("/user/**").authenticated()
                .antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")
                .antMatchers("/manager/**").access("hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
                .anyRequest().permitAll()
                .and()
                .formLogin()
                    .loginPage("/loginForm")
                    .loginProcessingUrl("/login")
                    .defaultSuccessUrl("/")
                .and()
                    .csrf().disable();

        return http.build();

    }

 

auth 패키지 하위로 PrincipalDetails 와 PrincipalDetailsService 클래스를 생성해준다.

 

principalDetails에 userDetails를 오버라이딩 해준다.

 

그후 ctrl+o를 눌러서 오버라이딩메서드를 추가해준다.

 

User객체를 컴포지션해준 후 생성자를 생성해서 User를 파라메터로 넣어준다.

getAuthorities에 권한을 넣어줘야하는데 타입이 collection 여서 user.getRole을 그대로 넣어줄 수 없기 때문에

아래와 같은 방법으로 넣어준다.

오버라이딩 해준부분에 각각 getUsername, getPassword 등등 넣어줘야하고 계정 만료부분엔 True로 변경해주어야한다.

public class PrincipalDetails implements UserDetails {

    private User user;

    public PrincipalDetails(User user){
        this.user=user;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {

        Collection<GrantedAuthority> collection = new ArrayList<>();
        collection.add(new GrantedAuthority() {
            @Override
            public String getAuthority() {
                return user.getRole();
            }
        });

        return collection;
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

 

PrincipalDetailService로 이동해서 userRepository를 Autowired 해서 username을 기준으로 해당 유저가 가입되어있는 유저인지 찾아주기 위해 findByUsername으로 네이밍쿼리를 작성할 준비를 해준다.

만약 해당 유저가 가입되어있는 유저라면 유저의 정보를 리턴해주고 아니라면 null이 리턴이 될 것이다.

 

userRepository는 단순한 CRUD만 해주기 때문에 username을 통해서 회원정보를 찾는 네이밍쿼리을 활용해 작성해준다

해당 쿼리로 "SELECT * FROM user WHERE username =1?;" 라는 쿼리는 대체할 수 있다. 

 

테스트를 진행해보면 로그인이 되면서 "http://localhost:8088/"으로 이동하는걸 확인할 수 있다.

댓글