KDT/WEB

240326 WEB - 보안 5

001cloudid 2024. 3. 26. 12:50
728x90

보안

권한

memberMapper

	<insert id="insertMemberAuth">
		insert into tbl_member_auth
		values(#{userid}, #{auth}) 
	</insert>

 

com.itwillbs.domain에 AuthDTO.java 생성

package com.itwillbs.domain;

public class AuthDTO {
	private String userid;
	private String auth;
	
	@Override
	public String toString() {
		return "AuthDTO [userid=" + userid + ", auth=" + auth + "]";
	}

	public String getUserid() {
		return userid;
	}
	
	public void setUserid(String userid) {
		this.userid = userid;
	}
	
	public String getAuth() {
		return auth;
	}
	
	public void setAuth(String auth) {
		this.auth = auth;
	}
	
	
}

 

SampleService.java

	public void insertMember(MemberDTO memberDTO) {
		System.out.println("SampleService insertMember()");
		
		//regdate, updatedate, enable
		memberDTO.setRegdate(new Timestamp(System.currentTimeMillis()));
		memberDTO.setUpdatedate(new Timestamp(System.currentTimeMillis()));
//		memberDTO.setEnable("1");
		
		sampleDAO.insertMember(memberDTO);
		
		AuthDTO authDTO = new AuthDTO();
		
		if(memberDTO.getUserid().equals("admin")) {
			authDTO.setUserid(memberDTO.getUserid());
			authDTO.setAuth("ROLE_ADMIN");
		}else {
			authDTO.setUserid(memberDTO.getUserid());
			authDTO.setAuth("ROLE_MEMBER");
		}
		sampleDAO.insertMemberAuth(authDTO);
		
	}

 

SampleDAO.java

	public void insertMemberAuth(AuthDTO authDTO) {
		System.out.println("SampleDAO inserMemberAuth()");
		System.out.println(authDTO);
		sqlSession.insert(namespace+".insertMemberAuth",authDTO);
	}

 

회원가입 후 권한 확인

그림 1

 

인증 사용

security-context

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:security="http://www.springframework.org/schema/security"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">


<!-- authentication-manager 인증매니저 
     <= provider manager 
     <= 이용 authentication-provider : 인증작업
     <= UserdetailService : 인증된 정보에 권한에 대한 정보를 같이 전달 
                          : 사용자의 정보와 사용자가 가진 권한의 정보를 처리해서 반환
                          
        UserdetailService(CachingUserDetailService, InMemoryUserDetailsManager,JdbcDaoImpl, JdbcUserDetailsManager,
        				  LdapUserDetailsManager, LdapUserDetailsService 클래스 제공)                  

JDBC
1) 지정된 형식 테이블 생성
create table users(
      username varchar(50) not null primary key,
      password varchar(50) not null,
      enabled char(1) default '1');

      
 create table authorities (
      username varchar(50) not null,
      authority varchar(50) not null,
      constraint fk_authorities_users foreign key(username) references users(username));
      
 create unique index ix_auth_username on authorities (username,authority);


insert into users (username, password) values ('user00','pw00');
insert into users (username, password) values ('member00','pw00');
insert into users (username, password) values ('admin00','pw00');

insert into authorities (username, authority) values ('user00','ROLE_USER');
insert into authorities (username, authority) values ('member00','ROLE_MANAGER');
insert into authorities (username, authority) values ('member00','ROLE_MEMBER');
insert into authorities (username, authority) values ('admin00','ROLE_MEMBER');  
insert into authorities (username, authority) values ('admin00','ROLE_MANAGER'); 
insert into authorities (username, authority) values ('admin00','ROLE_ADMIN');


2) 기존 데이터베이스 이용

                          
                          -->

<bean id="customAccessDenied" 
class="com.itwillbs.security.CustomAccessDeniedHandler"></bean>

<bean id="customLoginSuccess"
class="com.itwillbs.security.CustomLoginSuccessHandler"></bean>

<!-- 인증 X -->
<!-- <bean id="CustomNoOpPasswordEncoder"  -->
<!-- class="com.itwillbs.security.CustomNoOpPasswordEncoder"></bean> -->

<!-- 인증 O -->
<bean id="bcryptPasswordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>

<security:http>
	<security:intercept-url pattern="/sample/all" access="permitAll"/>
	
	<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')"/>
	
	<security:intercept-url pattern="/sample/admin" access="hasRole('ROLE_ADMIN')"/>

<!-- 	http://localhost:8080/secu/login -->

<!-- 	<security:form-login/> -->
		<security:form-login login-page="/sample/customLogin"
		authentication-success-handler-ref="customLoginSuccess"/>
		
		<security:logout logout-url="/sample/customLogout" invalidate-session="true"/>
	
<!-- 	HTTP 상태 403 – 금지됨 => 페이지 연결-->
<!-- 	<security:access-denied-handler error-page="/sample/accessError"/> -->
<security:access-denied-handler ref="customAccessDenied"/>

<!-- 		csrf 토큰  : 서버에 세션에 저장, 브라우저에 전송 된 csrf 토큰 검사하는 방식 
			csrf 토큰 생성을 비활성화, 쿠키를 이용해서 처리-->
<!-- 			<security:csrf disabled="true"/> -->
	
</security:http>

<security:authentication-manager>

<security:authentication-provider>

<!--  	<security:user-service>
     	There is no PasswordEncoder mapped for the id "null" 
		noop : PasswordEncoder 없이 사용
		<security:user name="member" password="{noop}member" authorities="ROLE_MEMBER"/>
		<security:user name="admin" password="{noop}admin" authorities="ROLE_MEMBER, ROLE_ADMIN"/>
	</security:user-service>
-->
<!-- 	<security:jdbc-user-service data-source-ref="dataSource"/> -->
		
<!-- 	<security:password-encoder ref="CustomNoOpPasswordEncoder"/> -->

<security:jdbc-user-service data-source-ref="dataSource" 
users-by-username-query="select userid, userpw, enabled from tbl_member where userid = ?"
authorities-by-username-query="select userid, auth from tbl_member_auth where userid = ?"/>
<security:password-encoder ref="bcryptPasswordEncoder"/>

</security:authentication-provider>

</security:authentication-manager>

</beans>

 

admin 권한을 가진 아이디로 로그인하고 sample/member 이동 시 accessError로 이동됨

-> admin이 member 권한이 없음

	<select id="getMember" resultType="map">
		select a.userid, a.userpw, a.username, a.enabled, a.regdate,a.updatedate, b.auth
		from tbl_member a join tbl_member_auth b
		on a.userid = b.userid
		where a.userid = #{userid}
	</select>

 

SampleDAO

	public Map<String, Object> getMember(MemberDTO memberDTO) {
		System.out.println("SampleDAO getMember()");
		System.out.println(memberDTO);
		
		return sqlSession.selectOne(namespace+".getMember", memberDTO);
	}

 

SampleService

	public Map<String, Object> getMember(MemberDTO memberDTO) {
		System.out.println("SampleService getMember()");
		System.out.println(memberDTO);
		
		return sampleDAO.getMember(memberDTO);
		
	}

 

security 패키지 안에 CustomUserDetailsService

package com.itwillbs.security;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class CustomUserDetailsService implements UserDetailsService{

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		System.out.println("CustomUserDetailsService loadUserByUsername()");
		System.out.println(username);
		
		return null;
	}

}

 

security-context

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:security="http://www.springframework.org/schema/security"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">


<!-- authentication-manager 인증매니저 
     <= provider manager 
     <= 이용 authentication-provider : 인증작업
     <= UserdetailService : 인증된 정보에 권한에 대한 정보를 같이 전달 
                          : 사용자의 정보와 사용자가 가진 권한의 정보를 처리해서 반환
                          
        UserdetailService(CachingUserDetailService, InMemoryUserDetailsManager,JdbcDaoImpl, JdbcUserDetailsManager,
        				  LdapUserDetailsManager, LdapUserDetailsService 클래스 제공)                  

JDBC
1) 지정된 형식 테이블 생성
create table users(
      username varchar(50) not null primary key,
      password varchar(50) not null,
      enabled char(1) default '1');

      
 create table authorities (
      username varchar(50) not null,
      authority varchar(50) not null,
      constraint fk_authorities_users foreign key(username) references users(username));
      
 create unique index ix_auth_username on authorities (username,authority);


insert into users (username, password) values ('user00','pw00');
insert into users (username, password) values ('member00','pw00');
insert into users (username, password) values ('admin00','pw00');

insert into authorities (username, authority) values ('user00','ROLE_USER');
insert into authorities (username, authority) values ('member00','ROLE_MANAGER');
insert into authorities (username, authority) values ('member00','ROLE_MEMBER');
insert into authorities (username, authority) values ('admin00','ROLE_MEMBER');  
insert into authorities (username, authority) values ('admin00','ROLE_MANAGER'); 
insert into authorities (username, authority) values ('admin00','ROLE_ADMIN');


2) 기존 데이터베이스 이용

                          
                          -->

<bean id="customAccessDenied" 
class="com.itwillbs.security.CustomAccessDeniedHandler"></bean>

<bean id="customLoginSuccess"
class="com.itwillbs.security.CustomLoginSuccessHandler"></bean>

<bean id="customUserDetailsService"
class="com.itwillbs.security.CustomUserDetailsService"></bean>

<!-- 인증 X -->
<!-- <bean id="CustomNoOpPasswordEncoder"  -->
<!-- class="com.itwillbs.security.CustomNoOpPasswordEncoder"></bean> -->

<!-- 인증 O -->
<bean id="bcryptPasswordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>

<security:http>
	<security:intercept-url pattern="/sample/all" access="permitAll"/>
	
	<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')"/>
	
	<security:intercept-url pattern="/sample/admin" access="hasRole('ROLE_ADMIN')"/>

<!-- 	http://localhost:8080/secu/login -->

<!-- 	<security:form-login/> -->
		<security:form-login login-page="/sample/customLogin"
		authentication-success-handler-ref="customLoginSuccess"/>
		
		<security:logout logout-url="/sample/customLogout" invalidate-session="true"/>
	
<!-- 	HTTP 상태 403 – 금지됨 => 페이지 연결-->
<!-- 	<security:access-denied-handler error-page="/sample/accessError"/> -->
<security:access-denied-handler ref="customAccessDenied"/>

<!-- 		csrf 토큰  : 서버에 세션에 저장, 브라우저에 전송 된 csrf 토큰 검사하는 방식 
			csrf 토큰 생성을 비활성화, 쿠키를 이용해서 처리-->
<!-- 			<security:csrf disabled="true"/> -->
	
</security:http>

<security:authentication-manager>

<security:authentication-provider 
user-service-ref="customUserDetailsService">

<!--  	<security:user-service>
     	There is no PasswordEncoder mapped for the id "null" 
		noop : PasswordEncoder 없이 사용
		<security:user name="member" password="{noop}member" authorities="ROLE_MEMBER"/>
		<security:user name="admin" password="{noop}admin" authorities="ROLE_MEMBER, ROLE_ADMIN"/>
	</security:user-service>
-->
<!-- 	<security:jdbc-user-service data-source-ref="dataSource"/> -->
		
<!-- 	<security:password-encoder ref="CustomNoOpPasswordEncoder"/> -->

<!-- <security:jdbc-user-service data-source-ref="dataSource"  -->
<!-- users-by-username-query="select userid, userpw, enabled from tbl_member where userid = ?" -->
<!-- authorities-by-username-query="select userid, auth from tbl_member_auth where userid = ?"/> -->



<security:password-encoder ref="bcryptPasswordEncoder"/>

</security:authentication-provider>

</security:authentication-manager>

</beans>

 

 

domain 패키지에 CustomUser 클래스 생성

package com.itwillbs.domain;

import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

public class CustomUser extends User {

	private Map<String, Object> member;
	
	public CustomUser(String username, String password, Collection<? extends GrantedAuthority> authorities) {
		super(username, password, authorities);
		System.out.println("CustomUser CustomUser() 생성자");
	}

	public CustomUser(Map<String, Object> map) {
		super(map.get("userid"), map.get("password"), map.get("auth").collect(Collectors.toList()));
		System.out.println("CustomUser CustomUser() 생성자2");
		
		this.member= map;
	}

}

 

CustomUserDetailsService

package com.itwillbs.security;

import java.util.Map;

import javax.inject.Inject;

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;

import com.itwillbs.domain.CustomUser;
import com.itwillbs.domain.MemberDTO;
import com.itwillbs.service.SampleService;
@Service
public class CustomUserDetailsService implements UserDetailsService{

	@Inject
	private SampleService sampleService;
	
	
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		System.out.println("CustomUserDetailsService loadUserByUsername()");
		System.out.println(username);
		
		MemberDTO memberDTO = new MemberDTO();
		memberDTO.setUserid(username);
		
		Map<String, Object> map = sampleService.getMember(memberDTO);
		
		return map == null ? null : new CustomUser(map);
	}

}

 

memberMapper 파일 수정

 

728x90

'KDT > WEB' 카테고리의 다른 글

WEB - 테스트 1, 롬복 1  (0) 2024.04.03
240328 Web - 보안 6  (0) 2024.03.28
240325 WEB - 보안 4  (0) 2024.03.25
240322 WEB - 보안 3  (0) 2024.03.22
240319 WEB - 보안 2  (0) 2024.03.19