minlog
article thumbnail

 

Spring-Security를 사용한 암호화

 

1. configure(HttpSecurity http)를 오버라이딩하여  Secuirty  권한설정 추가

📑 SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    ...
}
@Override
protected void configure(HttpSecurity http) throws Exception {
    CharacterEncodingFilter filter = new CharacterEncodingFilter();
    filter.setEncoding("UTF-8");
    filter.setForceEncoding(true);
    http.addFilterBefore(filter,CsrfFilter.class);	
   
    http
         .authorizeRequests()
              .antMatchers("/")
              .permitAll()
              .and()
         .formLogin()
              .loginPage("/memLoginForm.do")
              .loginProcessingUrl("/memLogin.do")
              .permitAll()
              .and()
         .logout()
              .invalidateHttpSession(true)
              .logoutSuccessUrl("/")
              .and()
         .exceptionHandling().accessDeniedPage("/access-denied");     
}

1) 요청에따른 권한을 확인하여 서비스 하는 부분 

java기능 구현이 아닌 스프링 내부의 프레임워크(시큐리티)가 알아서 인증절차를 실행 해준다.

  • authorizeRequests( ) : 리소스의 접근
    • antMatchers("/").permitAll( ) : antMatchers 설정한 리소스의 접근을 인증절차 없이 허용 한다는 의미
  • formLogin( ) : 로그인 페이지와 기타 로그인 처리 및 성공 실패 처리를 사용하겠다는 의미
    • loginPage("사용자가 지정한 URI") : 사용자가 따로 만든 로그인 페이지를 사용
    • loginProcessingUrl("사용자가 지정한 URI") : 사용자가 따로 만든 로그인 페이지를 사용
    • defaultSuccessUrl("/") : 정상적으로 인증성공 했을 경우 이동하는 페이지를 설정
    • permitAll( ) : 모든요청
    • and ( ) : 그리고  
  • logout( ) : 로그아웃을 지원하는 메서드
    • invalidateHttpSession(true) : 세션을 제거해준다. (중간에서 보안을 연결해주는 서비스 와 연결)
    • logoutSuccessUrl: 로그아웃 처리 성공 처리 후 이동(/)
    • accessDeniedPage : 로그아웃을 안하고 접근시 권한이 없다는 오류페이지로 이동

 

* 오류페이지로 넘겨주는 컨트롤러와 화면 생성

📑 MemberController.java

@GetMapping("/access-denied")
 public String showAccessDenied() {
    return "access-denied";
 }

📑access-denied.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
  <h2>Access Denied - You are not authorized to access this resource.</h2>
  <hr>
  <a href="${pageContext.request.contextPath}/">Back to Home Page</a>
</body>
</html>

 

 

 

2. 데이터베이스에 회원인증처리 클래스 생성 (로그인 요청시 실행)

데이터베이스에 존재하는 회원인지 인증해주는 역할을 한다.

 

📑 MemberUserDetailsService.java

package kr.board.security;
...
public class MemberUserDetailsService implements UserDetailsService {

	@Autowired
	private MemberMapper memberMapper;
	
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// 로그인 처리 하기
		Member mvo=memberMapper.memLogin(username);
		//-->UserDetails -> implements--->User -> extends--->MemberUser
		if(mvo != null) {
			return new MemberUser(mvo); // new MemberUser(mvo); // Member, AuthVO
		}else {
	   	   throw new UsernameNotFoundException("user with username" + username + "does not exist."); 	
		}
	}

}

1) UserDetailsService 를 상속 받는 클레스 생성한다.

- 파라미터로 username (사용자 아이디)를 받아준다.  * 사용자 아이디의 변수명은 무조건 username으로 설정해주어야한다.

 

2) DB에 존재하는 회원인지 확인

- MemberMapper.java >  memLogin( ) 메서드를 실행하여 DB에 있는 회원인지 확인한다.

- 반환 받는 값이 없다면 MemberUser 겍체에 회원정보를 넘겨준다.

 

 

 

 

3. 권한정보( User ) 를 상속 받아 회원정보( Member/authVo )  함께 저장하는 클래스 생성

📑 MemberUser.java

public class MemberUser extends User{
    private Member member;
    public MemberUser(String username, String password,
    Collection<? extends GrantedAuthority> authorities) {
    	super(username, password, authorities);
    } 
    public MemberUser(Member vo) { 
        // User클래스에 생성자를 호출하는 코드 작성
        super(vo.getMemId(), vo.getMemPwd(), vo.getAuthList().stream()
        .map(auth->new SimpleGrantedAuthority(auth.getAuth())).
        collect(Collectors.toList()));
        System.out.println("User 생성자 호출");
        this.member=vo;
    }
    public Member getMember() {
   		return member;
    }
    public void setMember(Member member) {
    	this.member = member;
    }
}

1) 생성자 1번  : 객체를 생성할때 권한정보( 슈퍼클래스 : User )에 사용자의 정보를 넘겨준다. 

Collection < ? extends GrantedAuthority > authorities

- GrantedAuthority : 권한정보를 부여받은 임의(?)의 객체를 받아서 권한정보( 슈퍼클래스 : User ) 에 값을 넘겨준다. 

 

 

2) 생성자 2번 : (1번 로그인 요청시)실행된 메서드에서 MemberUser를 생성하고 고객의 정보(vo)를 파라미터로 받았다.   

- 전달 받은 고객의 정보(vo)객체에 들어있는 사용자의 아이디 , 패스워드, 사용자 권한리스트(auth)를 권한정보( 슈퍼클래스 : User )에 넘겨준다. 

- 전달 시 사용자 권한 리스트를 stream으로 각각의 객체를 순회하여 권한정보를 문자열로 저장 ( SimpleGrantedAuthority )

  • stream : for문처럼 안에 데이터를 순회하면서 병렬처리를 해준다.
  • map : 요소들을 특정조건에 해당하는 값으로 변환

- collectors.toList() : 받은 문자열을 리스트 형식으로 나누어준다. 

- 선언한 member 필드에 파라미터로 받아온 값을 넣어 회원정보를 사용할 수 있게 해준다. 

 

 

 

 

 

 

 

4. View에서 스프링 시큐리티 사용

 

<c:set var="mvo" value="${SPRING_SECURITY_CONTEXT.authentication.principal}"/>
<c:set var="auth" value="${SPRING_SECURITY_CONTEXT.authentication.authorities}"/>

1) principal : 회원정보

2) authorities : 권한정보

 

profile

minlog

@jimin-log

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!