spring security 권한, 로그인, 로그아웃

이태규·2022년 4월 5일
0

spring

목록 보기
42/64

MemberDetailServiceImpl.java

UserDetailService의 interface를 imlpement 한거임.

package com.example.service;

import java.util.Collection;

import com.example.dto.MemberDTO;
import com.example.mapper.MemberMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class MemberDetailServiceImpl implements UserDetailsService {

    @Autowired
    MemberMapper mMapper;

    // 로그인에서 입력하는 정보중에서 아이디를 받음
    // MemberMapper를 이용해서 정보를 가져와서 UserDetails
    // userdetailservice에서 미리 설계가 되어 있음.
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("username" + username);
        MemberDTO member = mMapper.memberEmail(username);
        System.out.println("--------------------------" + member);

        // 권한 정보를 문자열 배열로 만듦.
        String[] strRole = { member.getUrole() };

        // String 배열 권한을 collection<Granted ...> 타입으로 변환함
        Collection<GrantedAuthority> role = AuthorityUtils.createAuthorityList(strRole);
        // 권한을 여러개 줄 수 있다 customer, seller, admin 이렇게

        // 아이디, 암호, 권한들 ...
        User user = new User(member.getUemail(), member.getUpw(), role);

        // 암호화를 했기 때문에 안 됨.

        return user;
    }

}

리턴타입이 메일, 패스워드, 권한을 담아야함.
권한은 여러개를 담을 수 있음.

SecurityConfig.java

package com.example.config;

import com.example.service.MemberDetailServiceImpl;

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.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // 1. 직접 만든 detailService 객체 가져오기
    @Autowired
    MemberDetailServiceImpl mService;

    // 2. 암호화 방법 객체 생성 @Bean은 서버 구동시 자동으로 객체 생성됨
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 3. 직접만든 dtailsService에 암호화 방법 적용
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(mService)
                .passwordEncoder(bCryptPasswordEncoder());
    }

AuthenticationManagerBuilder는 HttpSecurity에 포함된 거임.
아래에서 HttpSecurity http를 통해서 위에서 담은걸 쓰는거임


    // 기존기능을 제거한 후 필요한 것을 추가
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // 페이지별 접근권한 설정
        http.authorizeRequests()
                .antMatchers("/security_admin", "/security_admin/**")
                .hasAnyAuthority("ADMIN")
                .antMatchers("/security_seller", "/security_seller/**")
                .hasAnyAuthority("ADMIN", "SELLER")
                .antMatchers("/security_customer", "/security_customer/**")
                .hasAnyAuthority("CUSTOMER")
                .anyRequest().permitAll();

        // 로그인 페이지 설정, 단 post는 직접 만들지 않음.
        http.formLogin()
                .loginPage("/member/security_login")
                .loginProcessingUrl("/member/security_loginaction")
                .usernameParameter("uemail")
                .passwordParameter("upw")
                .defaultSuccessUrl("/security_home", true)
                .permitAll();

        // 로그아웃 페이지 설정, url에 맞게 post로 호출하면 딤
        http.logout()
                .logoutUrl("/member/security_logout")
                .logoutSuccessUrl("/security_home")
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .permitAll();

        // 접근권한불가 403
        http.exceptionHandling().accessDeniedPage("/security_403");

        // super.configure(http);
        // super가 부모의 기능이다.
        // 이걸 뺴버리면 부모기능을 안쓰겠다.

        // h2 console db사용을 위해서 임시로
        // 나중에 빼야함. 보안을 위해
        http.csrf().disable();
        http.headers().frameOptions().sameOrigin();

    }
    // extends가 안되는 상황에서 securityconfig에 컨트롤 .을 써서 불렀음
}

antMatchers

antMatchers("/login**", "/web-resources/**", "/actuator/**")

특정 리소스에 대해서 권한을 설정합니다.

permitAll

antMatchers("/login**", "/web-resources/**", "/actuator/**").permitAll() 

antMatchers 설정한 리소스의 접근을 인증절차 없이 허용한다는 의미 입니다.

hasAnyRole

antMatchers("/admin/**").hasAnyRole("ADMIN")

리소스 admin으로 시작하는 모든 URL은 인증후 ADMIN 레벨의 권한을 가진 사용자만 접근을 허용한다는 의미입니다.

anyRequest

anyRequest().authenticated()

모든 리소스를 의미하며 접근허용 리소스 및 인증후 특정 레벨의 권한을 가진 사용자만 접근가능한 리소스를 설정하고 그외 나머지 리소스들은 무조건 인증을 완료해야 접근이 가능하다는 의미입니다.

formLogin

http.formLogin();  

로그인 페이지와 기타 로그인 처리 및 성공 실패 처리를 사용하겠다는 의미 입니다.

loginPage

loginPage("/login-page") 

사용자가 따로 만든 로그인 페이지를 사용하려고 할때 설정합니다.

따로 설정하지 않으면 디폴트 URL이 “/login”이기 때문에 “/login”로 호출하면 스프링이 제공하는 기본 로그인페이지가 호출됩니다.

loginProcessingUrl

loginProcessingUrl("/login-process") 

로그인 즉 인증 처리를 하는 URL을 설정합니다. “/login-process” 가 호출되면 인증처리를 수행하는 필터가 호출됩니다.

defaultSuccessUrl

defaultSuccessUrl("/main")

정상적으로 인증성공 했을 경우 이동하는 페이지를 설정합니다.

설정하지 않는경우 디폴트값은 “/” 입니다.

profile
한 걸음씩 나아가자

0개의 댓글