본문 바로가기
Java/Spring

Spring) Spring Security - 설정 및 관련 설정 구체화 (설명 포함)

by 박채니 2022. 9. 10.
안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.

 

Spring Security

- 사용자 인증, 권한, 보안처리를 간단하지만 강력하게 구현

 

인증(Authentication) : 접근한 유저를 식별하고, 애플리케이션에 접근할 수 있는 지 검사

- 접근 주체(Principal) : 보안 시스템이 작동되고 있는 애플리케이션에 접근하는 유저

- Credentials : 특정 리소스에 접근하려는 사용자가 인증을 위해 제공하는 비밀번호

 

인가(Authorization) : 인증된 유저가 애플리케이션의 기능을 이용할 수 있는지 검사

- 권한(Authoriities) : 인증된 유저가 가진 권한 목록

 

 

security 설정

 

pom.xml

#7. spring-security 관련 의존

<!-- #7. spring-security 관련 의존 -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>${org.springframework.security-version}</version>        
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>${org.springframework.security-version}</version>        
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>${org.springframework.security-version}</version>        
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglibs</artifactId>
    <version>${org.springframework.security-version}</version>        
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
    <version>${org.springframework.security-version}</version>        
</dependency>

 

web.xml

#7.2 security filter chain 등록

(security의 시작점 → 해당 필터 주석하면 security 이용 안됨)

<!-- #7.2 security filter chain 등록 -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

 

security-context.xml

#7.3 인증/권한 관련 설정

<!-- #7.3 인증/권한 관련 설정 -->
<http auto-config="true"> <!-- 로그인폼, 기타 인증 처리, 표현식 관련 사용할 수 있도록 -->
    <intercept-url pattern="/**" access="isAuthenticated()"/> <!-- 인증되었을때만 접근! -->
</http>

<authentication-manager> <!-- provider 관리 -->
    <authentication-provider>
        <user-service>
            <user 
                name="honggd" 
                password="$2a$10$G7F3EfcXE8wJWUAsCznaoOqttim4MwJBNlWey5yuL5ZRMwRSdPvEi" 
                authorities="ROLE_USER"/> <!-- 메모리상에서 관리! -->
        </user-service>
        <password-encoder ref="bcryptPasswordEncoder"/>
    </authentication-provider> <!-- 인증관련 처리(인증주체) -->
</authentication-manager>

모든 요청에 대해서 인증이 되었을 때만 접근 할 수 있도록 설정하였으며, 테스트용이므로 DB가 아닌 메모리 상에서 user를 관리해보도록 하겠습니다.

 

 

security가 제공해주는 로그인 폼이며, 현재 모든 요청에 대해 인증 처리가 필요하기 때문에 어느 페이지에 가든 해당 로그인 창이 나타납니다.

설정해둔 honggd, 1234 (bcryptPasswordEncoder처리) 를 입력 후 로그인하면 아래와 같이 메인 페이지가 나타납니다.

(세션 어딘가에서 security가 인증 정보를 관리해주고 있음!)

 

header.jsp

<!-- 권한체크 -->
<sec:authorize access="hasRole('ADMIN')">
    <li class="nav-item"><a class="nav-link" href="${pageContext.request.contextPath}/admin/memberList.do">관리자</a></li>
</sec:authorize>

<sec:authorize access="isAnonymous()"> <!-- 인증하지 않은 상태 -->
    <button class="btn btn-outline-success my-2 my-sm-0" type="button" onclick="location.href='${pageContext.request.contextPath}/member/memberLogin.do';">로그인</button>
    &nbsp;
    <button class="btn btn-outline-success my-2 my-sm-0" type="button" onclick="location.href='${pageContext.request.contextPath}/member/memberEnroll.do';">회원가입</button>			    			    
</sec:authorize>

<sec:authorize access="isAuthenticated()"> <!-- 인증완료된 상태 -->
    <span>
        <a href="${pageContext.request.contextPath}/member/memberDetail.do">
            <sec:authentication property="principal.username"/> <!-- 갖고있는 인증정보의 id -->
            <sec:authentication property="authorities"/> <!-- 권한 -->
        </a>님, 안녕하세요😊
    </span>
    &nbsp;
    <button class="btn btn-outline-success my-2 my-sm-0" type="button" onclick="location.href='${pageContext.request.contextPath}/member/memberLogout.do';">로그아웃</button>			    
</sec:authorize>

sec:authorize로 권한 체크!

hasRole() → 해당 권한을 갖고 있는 지 체크

isAnonymous() → 인증되지 않은 상태

isAuthenticated() → 인증 완료된 상태

 

sec:authentication로 인증 정보 접근!

property="principal.username" → 인증 정보의 id값

property="authorities" → 권한 정보

 

간혹 security의 jstl jar파일을 찾을 수 없다는 에러가 발생하는데 이는, lib에 직접 링크해주면 해결됩니다.

C:\Users\사용자\.m2\repository\org\springframework\security\spring-security-taglibs\5.3.3.RELEASE 로 이동하여 jar파일을 복사 후 lib 파일 아래에 링크!

 


security 설정 구체화

- intercept-url은 구체적 → 일반적인 설정순으로 작성해야함

<http security="none" pattern="/resources/**"/> <!-- security X -->

<!-- intercept-url은 구체적 -> 일반적인 설정순으로 작성 -->	
<http auto-config="true"> <!-- 로그인폼, 기타 인증 처리, 표현식 관련 사용할 수 있도록 -->
    <intercept-url pattern="/" access="permitAll"/> <!-- 모두 접근 가능! -->
    <intercept-url pattern="/index.jsp" access="permitAll"/>
    <intercept-url pattern="/member/memberEnroll.do" access="isAnonymous()"/> <!-- 인증 안되었을때만 접근 -->
    <intercept-url pattern="/admin/**" access="hasRole('ADMIN')"/> <!-- 관리자만 접근가능 -->

    <intercept-url pattern="/**" access="isAuthenticated()"/> <!-- 인증되었을때만 접근! -->
</http>

permitAll → 모두 접근 가능

isAnonymous() → 인증 안 되었을때만 접근 가능

isAuthenticated() → 인증 되었을때만 접근 가능

 

 

honggd로 로그인 후 /member/memberEnroll.do 접근 시 (인증 처리된 후 인증 안 되었을 때만 접근 가능한 url 접근 시)

403 오류 발생!! (security 관련 오류)

 

honggd로 로그인 후 /admin/memberList.do 접근 시 (해당 권한을 갖고 있지 않은 사람이 접근 시)

마찬가지로 403 오류가 발생됩니다.

 

admin user 추가

<user 
    name="admin" 
    password="$2a$10$G7F3EfcXE8wJWUAsCznaoOqttim4MwJBNlWey5yuL5ZRMwRSdPvEi" 
    authorities="ROLE_USER, ROLE_ADMIN"/>

 

admin 로그인 후 /admin/memberList.do 접근 시 (해당 권한을 가진 사람이 접근 시)

 

 

※ security logout 설정 하지 않은 상태에서 로그인 하는 방법

- url 주소 뒤에 /logout

http://localhost:9090/spring2/logout