반응형
package com.biz.book.auth;
import com.biz.book.mapper.AuthorityDao;
import com.biz.book.mapper.UserDao;
import com.biz.book.model.UserDetailsVO;
import lombok.RequiredArgsConstructor;
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;
/**
* spring security 프로젝트에서
* 사용자 인가와 권한을 관리하는 클래스
* UserDetailService 를 customizing
*
* Customizing
* 패키지형 솔루션을 가지고 있는 it 회사에서
* 어떤 회사에 솔루션을 판매하면서
* 회사의 실정, 업무환경, 여러가지 여건들을 요구분석하여
* 솔루션을 사용하는 회사에 최적화하는 것
* */
@RequiredArgsConstructor
@Service("userDetailServiceV1")
public class UserDetailServiceImplV1 implements UserDetailsService {
/**
* @Autowired 를 사용하여 객체를 주입받아서 사용해 왔는데
* @Autowired 로 주입받은 객체에 메로리 누수현상이 발생을 하더라
*
* 주입받을 객체를 final 로 선언을 해주는데
* final 로 선언한 객체는 반드시 생성자에서 객체 초기화(주입)을 해야한다
* 1. 주입받을 객체를 final 로 선언하고
* 2. 생성자의 매개변수를 통하여 객체를 초기화한다.
* 3. 주입받을 객체의 갯수가 늘거나 줄면 생성자를 또 다시 변경 해야하는 번거로움이 있다.
* 4. lombok 의 @RequiredArgsConstructor 를 사용하면 final 로 선언된
* 모든 필드변수들을 모아서 생성자로 만들어준다.
* */
private final UserDao userDao;
private final AuthorityDao authDao;
/**
* 이 프로젝트에서 사용할 member(user) 관련 table 에서 username 으로
* 사용자 정보를 SELECT 하고 사용자의 ROLL 정보를 기준으로 사용자의 권한을 설정하여
* 기능을 수행을 제한하는 설정을 하고
* 사용자의 여러 세부 정보를 vo 객체에 담아주는 역할 수행
* */
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetailsVO userDetailsVO = userDao.findById(username);
userDetailsVO = UserDetailsVO.builder()
.username(username)
.password("12341234")
.isEnabled(true)
.build();
if (userDetailsVO == null) {
throw new UsernameNotFoundException(username + "정보를 찾을 수 없음!");
}
return userDetailsVO;
}
}
<?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:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security-5.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<!-- spring security 에서 사용할 AuthenticationProvider 를 구현한 -->
<!-- 클래스를 bean 등록 -->
<bean id="authProvider" class="com.biz.book.auth.AuthProviderImpl" />
<!-- 커스터마이징 된 AuthorProvider 를 spring security 에서 사용하도록
security:authentication-manager 에 등록-->
<security:authentication-manager>
<security:authentication-provider ref="authProvider"/>
</security:authentication-manager>
<!-- spring security 의 핵심 설정 부분 -->
<!-- security:http -->
<!-- login form 설정 -->
<!-- login 방법 설정 -->
<!-- login 이 되었을때 인가, 권한 설정 -->
<!-- security:intercept 이란 -->
<!-- login 이 되었을때 URL 패턴에 따라 접근 권한을 세밀하게 부여 할 수 있다. -->
<!-- 접근할 URL 을 pattern 속성에 지정하고 -->
<!-- 접근할 권한이 있는가를 검사하도록 access 속성에 지정한다. -->
<!-- 패턴 지정에서 주의할 사항 -->
<!-- 패턴은 URL 의 단계가 깊을 수록 위쪽에 먼저 작성을 해주어야 한다. -->
<!-- 만약 /member/**, /user/a/b/c 순서로 패턴이 있을경우 /member/a/b/c 는 무시된다. -->
<!-- 이때는 /member/a/b/c, /member/** 순서로 나열해야 한다. -->
<security:http auto-config="true" use-expressions="true">
<security:form-login login-page="/login" username-parameter="username" password-parameter="password"/>
<security:logout logout-url="/logout"/>
<!--
로그인 하는 사용자가
hasRole 이 true 인 경우에만
/admin/** 으로 접속
-->
<security:intercept-url pattern="/admin/**" access="hasRole('ADMIN')"/>
<!-- 여러 Role 을 지정할땐 hasAnyRole(배열) 사용 -->
<!-- admin, user 둘다 권한 -->
<security:intercept-url pattern="/member/mypage" access="hasAnyRole('ADMIN', 'USER')"/>
<security:intercept-url pattern="/member/password" access="hasAnyRole('ADMIN', 'USER')"/>
<!--
위 mypage, password 페이지를 제외한
모든 /member/** 경로는 permitAll()
만약 /member/** 얘가 먼저인 경우 밑에
/member/mypage
/member/password
이 둘은 무시됨
그래서 security:intercept-url 은 작성할때 순서정하는게 중요함
-->
<security:intercept-url pattern="/member/**" access="permitAll()"/>
<security:intercept-url pattern="/books/**" access="hasAnyRole('ADMIN', 'USER')"/>
<!-- -->
<security:intercept-url pattern="/**" access="permitAll()"/>
</security:http>
</beans>
반응형
댓글