Spring/Spring

0109 Spring - Security (2) Custom Login

jeoniee 2023. 2. 3. 03:32
728x90
반응형
CSRF (Cross-Site Request Forgery) 공격 & 토큰 
-> 스프링 시큐리티에서는 POST 방식으로 정보 전달 시 반드시 CSRF 토큰을 사용해야 한다. 

CSRF 토큰 ? 
사이트 간 위조 방지를 위한 토큰 값.

서버에서 정보 요청을 받아들일 때 사전 조건 검사가 없음 



A(공격자) > B(한테 메일 보냄) > 링크 클릭 (B 사용자가 로그인한 페이지 정보 해킹)
                   < 토큰 정보 가져옴


 

 

security-context.xml

   <!-- security-context.xml 시큐리티 관련 설정정보 -->
	<security:http>
	    <security:intercept-url pattern="/sec/all" access="permitAll"/>
	    <security:intercept-url pattern="/sec/member" access="hasRole('ROLE_MEMBER')"/>
	    <security:intercept-url pattern="/sec/admin" access="hasRole('ROLE_ADMIN')"/>
	    
	    <security:intercept-url pattern="/order/*" access="hasRole('ROLE_MEMBER')"/>
	    
	   
<!-- 		<security:form-login/> (기본값) --> 
 	<security:form-login login-page="/customLogin"/>

 

homecontroller 매핑

//로그인 페이지 
	@RequestMapping(value="/customLogin", method=RequestMethod.GET)
	public void customLogin() throws Exception{
		logger.debug("/customLogin 호출! -> /views/customLogin.jsp 이동");
	}
}//class

 

 

customLogin.jsp

<h1>customLogin.jsp</h1>
	
	<fieldset>
		<form action="/login" method="post">
			아이디 : <input type="text" name="username"><br>
			비번 : <input type="password" name="password"><br>
			<input type="submit" value="로그인">
			
			<!--  -->
			<input type="hidden" 
			name="${_csrf.parameterName }" 
			value="${_csrf.token }">
		</form>
	</fieldset>

security-context.xml 을 기본값으로 해줌 

		<security:form-login/> 
<!--  	<security:form-login login-page="/customLogin"/> -->

 

 

 

<security:csrf disabled="true"/>

 

 

 

익명객체

public class CustomLoginSuccessHandler implements AuthenticationSuccessHandler{

	private static final Logger mylog = LoggerFactory.getLogger(CustomLoginSuccessHandler.class);
	
	@Override
	public void onAuthenticationSuccess(
			HttpServletRequest request, 
			HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		
		mylog.debug("onAuthenticationSuccess() 호출 ");
		
		List<String> roleNames = new ArrayList<String>();
		
		authentication.getAuthorities().forEach(authority ->{
			roleNames.add(authority.getAuthority());
		});

		authentication.getAuthorities().forEach(
			new Consumer<GrantedAuthority>() {
			@Override
			public void accept(GrantedAuthority authority) {
				roleNames.add(authority.getAuthority());
			}
		});
	}
	//로그인 후 권한에 따른 페이지 이동 
	
}

 

 

람다표현식

authority -> { 
            roleNames.add(authority.getAuthority());
}

 

@Override
	public void onAuthenticationSuccess(
			HttpServletRequest request, 
			HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		
		mylog.debug("onAuthenticationSuccess() 호출 ");
		
		List<String> roleNames = new ArrayList<String>();
		
		// ctrl + 1  람다식 <-> 익명클래스 변경 단축키 
		authentication.getAuthorities().forEach(authority ->{
			roleNames.add(authority.getAuthority());
		});

		
//		authentication.getAuthorities().forEach(
//			new Consumer<GrantedAuthority>() {
//			@Override
//			public void accept(GrantedAuthority authority) {
//				roleNames.add(authority.getAuthority());
//			}
//		});
		
		
		mylog.debug(roleNames+"");
		
		//로그인 후 접근 권한에 따른 페이지 이동 
		if(roleNames.contains("ROLE_ADMIN")) {
			response.sendRedirect("/sec/admin");
			return;
		}
		
		if(roleNames.contains("ROLE_MEMBER")) {
			response.sendRedirect("/sec/member");
			return;
		}
		
		response.sendRedirect("/sec/all");
	}
	
	
}

 

 

 

 

 

pospring-test 추가

<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
728x90
반응형