본문 바로가기
프로젝트/Spring Boot 블로그프로젝트

[블로그프로젝트] 14. 스프링시큐리티로 로그인하기

by dantriss 2023. 4. 4.

유튜브에서 블로그 만들기 프로젝트를 따라하면서 나의 스킬을 조금더 레벨업 하고자 한다.

IDE : IntelliJ

언어 : Java

DB : MySQL

빌드관리 도구 : Maven

OS : iOS

참고유튜브 : 메타코딩


 

인증이 필요 없는 사용자들도 볼 수 있는 페이지들은 앞에 /auth를 붙이고 그 외의 페이지들은 로그인해서 해당되는 사용자들만 볼 수 있게 처리해보자. 우선 UserController에 주소들을 변경한다.

Slf4j는 로그를 찍어보기 위해서 사용한 어노테이션, 해당 프로젝트에서 진행사황과는 연관이 없다.

package com.blog.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

//인증이 안된 사용자들이 출입할 수 있는 경로를 /auth/**로 통일
// 그냥 주소가 "/"  이면 index.jsp 허용
// static 이하에 있는 /js/**,/css/**, /image/**
@Controller
public class UserController {

    @RequestMapping(value = "/auth/loginForm")
    public String joinForm(){
        
        return "user/loginForm";
    }

    @GetMapping("/auth/signForm")
    public String signForm(){
       
        return "user/signForm";
    }

   
}

 

 

다음은 UserApiController의 주소들을 변경하자.

기존에 사용했던 로그인 방식은 지워도 되는데 약간 아까?워서 주석으로 막았다.

package com.blog.controller.api;

import com.blog.DTO.ResponseDTO;
import com.blog.service.UserService;
import com.blog.table.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserApiController {

    @Autowired
    private UserService userService;


    @PostMapping("/auth/joinProc")
    public ResponseDTO<Integer> save(@RequestBody User user){

            userService.회원가입(user);
        return new ResponseDTO<Integer>(HttpStatus.OK.value(),1);
    }


}

 

컨트롤러부분에서 로그인을 삭제했으니 이제 서비스단에서의 기존 로그인 방식을 삭제하자.

UserService에 있는 기존 로그인 방식을 삭제하거나 주석으로 막자.

그 후 UserRepository에 있는 쿼리도 주석으로 막거나 삭제하자.

 

 

그다음으로 바꿔야 할 부분은 loginForm.jsp

Form 밖에 있던 button을 Form 안으로 이동하고  Form에 주소를 직접 추가한다.

그리고 각각 name 값들을 추가해준다.

JQuary에서 값들을 사용하지 않을 것이기 때문에 <script src="/js/user.js"></script> 는 주석으로 막거나 삭제하면 된다.

 

 

이제 header.jsp파일을 확인해보자.

로그인할 때, 회원가입을 할 때 둘다 인증되지 않은 유저도 가능해야하기 때문에 /auth를 추가적으로 붙여준다.

 

마지막으로 user.js파일을 확인해보자.

로그인은 이제 JQuary를 통해서 하지 않기 때문에 user.js에서 해당 기능을 삭제해준다.

 

그리고 회원가입은 인증되지 않은 사용자도 가능하기에 주소를 /api/joinForm -> /auth/JoinProc로 변경해주자.

 

com/blog/하위에 config 폴더생성해서 SecurityConfig.java 클래스 생성

 

 

requestMathcers 대신 antMatchers 사용가능 두개 모두 HTTP 요청의 패턴을 매칭 시킬 때 사용되지만, 

단순히 URL 패턴을 매칭시킬때는 antMatchers 좀더 복잡한 요청을 매칭할 때 requestMatchers를 사용해야하지만,

현재 pom.xml에서 springSecurity 버전을 맞추면 나도 antMachers도 사용이 가능하지만 Too many redrects 에러가 발생해서 antMatchers대신 requestMatchers 사용중 그래도 계속 같은 에러가 발생해서  anyReqeuest()와 authenticated()를 주석으로 

막고 모든 접속인원의 인증을 받지 않으니 해당 에러가 발생하지 않음.

하지만 필요한 부분이라 대책 강구중.

package com.blog.config;

import com.blog.config.auth.PrincipalDetailService;
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.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;





@Configuration // 빈등록
@EnableWebSecurity // 시큐리티 필터등록
@EnableGlobalMethodSecurity(prePostEnabled = true) //특정 주소로 접근을 하면 권한 및 인증을 미리 체크
public class SecurityConfig  {

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

        http    .csrf().disable()
                .authorizeRequests()
                .antMatchers("/auth/**","/","/js/**","/image/**","/css/**").permitAll()
                .anyRequest()
                .authenticated() // 로그인 페이지에 대한 접근을 허용 // 모든 다른 요청은 인증된 사용자만 접근 가능
            .and()
                .formLogin()
                    .loginPage("/auth/loginForm")
                    .loginProcessingUrl("/auth/loginProc") // 스프링 시큐리티가 해당 주소로 요청오는 로그인을 가로채서 대신 로그인 해줌
                    .defaultSuccessUrl("/") // 로그인 페이지는 /login 으로 설정
                .failureUrl("/")//실패할 때 이동할 url 주소
                .and()
                    .logout();
        return http.build();
    }





}

 

 

에러 확인을 위해서 로그를 찍어보면 controller 부분에서 무한 반복되고 있는 상황 확인.

 

검색해본결과대로 진행해도 문제가 해결되고 있지 않음

1. .permitAll()로 인증되지 않은 사용자가 접속하려고 해도 모두 허용하게 한다 -> 처음부터 .permitAll()은 사용중이였음.

2. pom.xml에서 spring security 버전을 맞추고 호환성 체크 -> 버전 5.6.0 입력 후 Maven 재시작-> antMatcher 사용가능 하지만  java.lang.NoClassDefFoundError 발생 -> Maven clean 후 intelliJ 재시작 ->  java.lang.NoClassDefFoundError 발생

3. antMatchers 대신 requestMatchers 사용하면서 .anyRequest().authenticated() 주석으로 막은 후 진행중

 

현재 3번 상태로 진행하면서 나중에 검색해서 해결하자고 생각하여 진도를 나가는 중간 중간에 검색해서 다시 해보지만 며칠째

해결이 되지 않아서 현재 진행상황이라도 글로 남기고자 블로그에 글 작성.

 

잘 진행이 되시는 분이라면 주소가 /auth/loginForm으로 접속시 로그인하는 창이 잘 나올걸로 예상.

댓글