본문 바로가기

기록/projects

메타데이터_MMS

SMALL

진행 기간

2021.04.10 ~ 2021.11.30

Github Link

https://github.com/Metadata-21-hf197/back.git

프로젝트 개요

프로젝트 설명

2021 한이음 멘토링 프로젝트로 수행한 웹 애플리케이션 프로젝트 입니다.

데이터의 표준데이터라고 할 수 있는 메타데이터 구성과 데이터 표준화, 모델 관리 등을 통해 데이터를 활용을 위한 표준을 시스템으로 구축합니다. 사용자가 편리하게 도구를 활용할 수 있도록 웹 페이지의 형태로 개발하였습니다.

주요 기능

  • 사전 기능 : 보안과 관련한 단어, 용어, 도메인의 사전 검색 기능
  • 결재 관리 : 데이터 모델과 연동된 도메인, 단어, 용어의 추가, 수정 및 삭제
  • 기여 내역 조회 : 데이터 모델과 연동된 도메인, 단어, 용어의 추가, 수정 및 삭제, 신청과 승인, 반려 처리
  • 로그인 기능 : 인가된 사용자만 시스템 접근 가능

상세 화면

메인 화면
수정 신청을 위한 화면
도메인과 코드 정보
관리자 승인 화면

 


설계

프로젝트 설계

DB 설계

 

상세 개발 내용

회원가입

메인페이지에서 회원가입 폼까지 이동하고, DB에 넣을 유저 정보를 파라미터로 컨트롤러에 전달한다.

컨트롤러에서는 파라미터를 객체로 매퍼까지 전달하여 DB에 넣고 결과를 반환한다.

리턴값은 모두 map객체에 저장하여 key-value 타입으로 프론트로 전달한다.

 

@Transactional
    @PostMapping("/user/join")
    @ResponseBody
    public Map<String, Object> insert(@RequestParam("memberName") String memberName,
                                      @RequestParam("password") String password,
                                      @RequestParam("email") String email,
                                      @RequestParam("userRole") String userRole) {
        User user = new User();
        user.setMemberName(memberName);
        user.setPassword(password);
        user.setEmail(email);
        user.setUserRole(userRole);
        userService.insertUser(user);
        //return result

        Map<String, Object> returnMap = new HashMap<String, Object>();
        returnMap.put("result", "success");

        return returnMap;
    }
<insert id="insertUser" parameterType="com.example.md_back.model.User">
        INSERT INTO User(memberName, password, email, enrollDate, userRole, quitStatus, userRole)
        VALUES ( #{memberName}, #{password}, #{email}, now(), #{userRole}, False, #{userRole})
</insert>

 

로그인

 

//UserConfig
@Override
    protected void configure(HttpSecurity http) throws Exception {
       //URI 설정
                .formLogin()
                .loginPage("/user/login")
                .loginProcessingUrl("/user/login")
                .defaultSuccessUrl("/table/word") //main으로 수정
                .successHandler(new LoginSuccessHandler())
                .failureHandler(new LoginFailHandler())
                .permitAll()

                //logout
                .and()
                .logout()
                .logoutUrl("/templates/user/logout")
                .logoutSuccessUrl("/")
                .invalidateHttpSession(true)
                .permitAll();
    }
//AuthProvider
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String id = authentication.getName();
        String password = authentication.getCredentials().toString();
        return authenticate(id, password);
    }

public Authentication authenticate(String id, String password) throws org.springframework.security.core.AuthenticationException {
        List<GrantedAuthority> grantedAuthorityList = new ArrayList<GrantedAuthority>();

        LoginDTO principal = (LoginDTO) userService.loadUserByUsername(id);
        User pUser = principal.getUser();
        principal.setUsername(pUser.getMemberName());
        if(principal == null) {
            throw new UsernameNotFoundException("wrongid");
        } else if(principal != null && !principal.getPassword().equals(password)) {
            throw new BadCredentialsException("wrongpw");
        }

        grantedAuthorityList.add(new SimpleGrantedAuthority(principal.getUser().getUserRole()));

        return new MyAuthentication(id, password, grantedAuthorityList, principal);
    }

 

인증

@AuthenticationPrincipal 을 사용하기 위해 customArgumentResolver를 구현해야 한다.

어노테이션에서 principal 객체가 아닌 기본 UserDetails 객체를 받아오는 것 같았다.

상세한 구현 내용은 블로그로 기록해두었다.

[Spring Security] @AuthenticationPrincipal과 ArgumentResolver

 

[Spring Security] @AuthenticationPrincipal과 ArgumentResolver

스프링 시큐리티를 구현하며 가장 어려웠던 점은 커스텀한 객체를 사용하여 메소드도 그에 맞게 변환하는 과정이었다. 기존 컨트롤러에서 인증된 객체를 가져오는 메소드로 다음과 같은 방식

sillutt.tistory.com

 

//WebConfig
@Bean
    public CustomArgumentResolver customArgumentResolver() {
        return new CustomArgumentResolver();
    }


    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(customArgumentResolver());
    }
public class CustomArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        Class<?> parameterType = methodParameter.getParameterType();
        return LoginDTO.class.equals(parameterType);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter,
                                  ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest,
                                  WebDataBinderFactory webDataBinderFactory) throws Exception {
        Object principal = null;
        MyAuthentication authentication =
                (MyAuthentication) SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null ) {
            principal = authentication.principal;
        }
        if(principal == null || principal.getClass() == String.class) {
            return null;
        }

        return principal;
    }

}

마무리

인원 감소로 인한 개발 규모가 축소되어 원래 계획한 내용보다 적은 분량을 진행해서 아쉬웠다. 대신 작은 규모에서도 최대한 기능을 개발하고, 남은 작업량에 따라 다른 기능을 추가하기도 해서 프로젝트를 완료하게 되었다.

다른 프로젝트에서 사용해본 스프링 시큐리티를 조금 더 자세하게 사용해볼 수 있었고, 특히 어노테이션을 활용하기 위한 커스텀을 하면서 객체의 흐름에 대해 조금 더 자세히 공부할 수 있는 기회가 되었다. 또, 기존에 스프링과 mybatis를 연동하여 프로젝트를 진행했어서 이번 프로젝트에서도 사용할 기술을 논의할때 조금 더 근거를 가지고 어필할 수 있었다.

SMALL

'기록 > projects' 카테고리의 다른 글

Earth AS  (0) 2021.03.14
[Spring Web Project] 농산물 직거래 웹 서비스  (0) 2020.07.15
[Java MVC] MVC 기반 웹 플랫폼 개발 (팀)  (0) 2020.05.23
모바일 프로젝트 [한줄일기]  (0) 2020.01.09