차근차근/Spring Security

알쏭달쏭 스프링 시큐리티 - 작성중

예쁜꽃이피었으면 2022. 2. 4. 13:46

 

일단 새로 맡게된 프로젝트에 스프링 시큐리티가 적용되어 있어서 공부중이다..

많이 들어봤지만..직접하려니 생각보다 알쏭달쏭하다..

이번에 찾아보면서 알게된 건..스프링 하위 프레임워크라는 것이다.

이전까지는 부트처럼 하나의 프레임워크라고 생각했는데

기존의 프로젝트에도 추가를 할 수 있는 부분이었다. 

 

우선 내가 이해한 바로는

개발을 하면서 사용자에 대한 권한처리를 일일이 했던 부분들을

스프링 시큐리티를 사용하면 더 편하게 할 수 있다고 한다.

 

사용자 비밀번호 암호화 같은 경우.. 더 이해가 필요한 부분인데.. (https://godekdls.github.io/Spring%20Security/features/#511-authentication-support)

처음에는 솔티드를 직접 구현하지 않고

제공되는 암호화 방식(적응형 단방향 함수 예 : bcry.pt , PBKDF2, scry.pt, argon2..)을 사용하면된다..라고 생각했었는데

또..어떤 블로그에서는

스프링 시큐리티에서 제공되는 암호화 + 솔티드 / 스프링 시큐리티에서 제공되는 암호화 + sha-256

를 사용하기도 해서 필요에 따라 만들어 쓰면 되는 부분 같다.

+ 스프링 스큐리티 5.0버전 이전에는 DelegatingPasswordEncoder를 쓰면된다.. =>'-' 공부하고 내용 수정할 예정,,

 

https://velog.io/@corgi/Spring-Security-PasswordEncoder%EB%9E%80-4kkyw8gi

비밀번호의 강도를 설정할 수 있다고 한다.. 기본값은 10

 


https://to-dy.tistory.com/70?category=720806

 

Spring Security Filter 추가

1. 필터 이름을 임의로 변경안된다. => 필터의 이름은 반드시 springSecurityFilterChain이어야 한다.

스프링 시큐리티 내에서 클래스를 찾기 위해 지정한 이름이여서 변경하거나 오타가 발생하면 안된다.

2. url 에서도 확장자가 붙는 스타일이 아니 때문에 마음대로 변경해서는 안된다. => 모든 패턴을 의미하는 /*로 사용

 

Spring Security 설정 파일
...
<http auto-config="true" use-expressions="false">
	<intercept-url pattern="/**" access="ROLE_USER" />
</http>
...

1. 모든 URL을 접속(/**)하기 위해서는 ROLE_USER권한이 필요하다는 뜻.

index페이지 및 모든 페이지에 들어갈 수 있는 사람은 로그인을 한 사람, 즉 권한(ROLE_USER)을  가진 사람만 들어올 수 있다는 뜻이다. 

 

서버 실행

서버를 실행하면 뜨는 /login은 spring security에서 제공하는 기본 로그인 페이지이다.

index페이지가 뜨지 않고 바로 로그인페이지가 뜨는 이유는, context-security에서 모든 URL(/**)에 접속하기 위해서는 권한이 ROLE_USER여야 한다고 정했기 때문이다.

 

 


검색어 : spring security db권한 설정 

 

https://jungeunlee95.github.io/java/2019/07/18/3-SpringSecurity-Authorization(%EA%B6%8C%ED%95%9C)-%EC%84%A4%EC%A0%95(ROLE),-TagLib-authorize-%EC%B6%94%EA%B0%80/

 

3 Spring Security - Authorization(권한) 설정(ROLE), TagLib authorize 추가 · 콩정의 개발 정리 블로그

3 Spring Security - Authorization(권한) 설정(ROLE), TagLib authorize 추가 18 Jul 2019 | Java Spring SpringSecurity Authorization [ 목차 ] Authorization(권한) 설정하기 - ROLE 지난 포스팅 [1] 테이블 수정 ROLE을 아래의 형태로

jungeunlee95.github.io

 

 

https://to-dy.tistory.com/75

 

Spring Security - 경로에 따른 접근 권한 설정

스프링 시큐리티에서는 권한에 따라 접근 가능한 경로를 제한할 수 있다. 그럼 권한에 따라 다른 링크를 보여준다면, 접근 가능한 경로를 제한할 수 있는 것 아닌가? 라는 생각을 할 수도 있다

to-dy.tistory.com

 

https://egovframe.go.kr/wiki/doku.php?id=egovframework:%EA%B6%8C%ED%95%9C%EA%B4%80%EB%A6%AC 

 

egovframework:권한관리 [eGovFrame]

시스템 구축시 스프링의 보안 메카니즘을 적용하기 위해 Spring Security 에서 관리하는 권한(Authority)을 정의한다. 따라서 시스템 담당자는 시스템 사용자에게 권한을 부여하기 위해 권한을 정의하

egovframe.go.kr

 

 

https://to-dy.tistory.com/86

 

Spring Security - 인증 절차 인터페이스 구현 (1) UserDetailsService, UserDetails

UserDetailsService 인터페이스는 DB에서 유저 정보를 가져오는 역할을 한다. 해당 인터페이스의 메소드에서 DB의 유저 정보를 가져와서 AuthenticationProvider 인터페이스로 유저 정보를 리턴하면, 그 곳

to-dy.tistory.com

 

https://sjh836.tistory.com/165

 

spring security 파헤치기 (구조, 인증과정, 설정, 핸들러 및 암호화 예제, @Secured, @AuthenticationPrincipal,

참조문서 https://docs.spring.io/spring-security/site/docs/4.2.7.RELEASE/reference/htmlsingle/#getting-started http://springsource.tistory.com/80 https://okky.kr/article/382738 1. 스프링 시큐리티란?..

sjh836.tistory.com

 

https://developersp.tistory.com/6

 

Spring 3.1.1 Security 로그인 및 로그인 권한 설정

Spring 3.1.1 기반으로 Security 로그인 및 로그인 권한 설정을 해보겠습니다. 가장 먼저 pom.xml에 Spring Security와 Spring Security Taglibs을 추가합니다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19..

developersp.tistory.com

 

    <!-- DB에서 불러올 사용자 정보 및 권한 설정  -->
    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="customAuthenticationProvider" /> <!-- 권한 설정할 커스텀 Bean -->
        <security:authentication-provider user-service-ref="customUserDetailsService"> <!-- 사용자 정보 설정할 커스텀 Bean -->
            <security:password-encoder ref="passwordEncoder"> <!-- 로그인 비밀번호 암호화 인코딩 Bean -->
                <security:salt-source ref="saltSource" /> <!-- 로그인 비밀번호 암호화 salt Bean -->
            </security:password-encoder>
        </security:authentication-provider>
    </security:authentication-manager>
    
    <!-- 권한 설정할 커스텀 Bean -->    
    <bean id="customAuthenticationProvider" class="com.parksc.myHome.security.CustomAuthenticationProvider">
    </bean>
    
    <!-- 사용자 정보 설정할 커스텀 Bean -->
    <bean id="customUserDetailsService" class="com.parksc.myHome.security.CustomUserDetailsService">
    </bean>

 

 

1. authentication-manager 는 인증과 관련된 정보를 설정하는 태그 => "인증관리자"

2. authentication-provider 는 인증에 대한 정보를 제공하는 제공자를 지정하는 태그  => "인증제공자"

 

질문 . 

authentication-provider ref
authentication-provider user-service-ref 태그에서

ref와 user-service-ref의 차이는? 


1. ref 
'AuthenticationProvider'를 구현하는 스프링 빈에 대한 참조를 정의
2. user-service-ref 
표준 bean 요소 또는 사용자 지정 사용자 서비스 요소를 사용하여 생성할 수 있는 UserDetailsService를 구현하는 빈에 대한 참조




https://docs.spring.io/spring-security/site/docs/4.0.1.RELEASE/reference/htmlsingle/#nsa-authentication-provider

38.3.2 <authentication-provider>

Unless used with a ref attribute, this element is shorthand for configuring a DaoAuthenticationProvider. DaoAuthenticationProvider loads user information from a UserDetailsService and compares the username/password combination with the values supplied at login. The UserDetailsService instance can be defined either by using an available namespace element ( jdbc-user-service or by using the user-service-ref attribute to point to a bean defined elsewhere in the application context). You can find examples of these variations in the namespace introduction.

Parent Elements of <authentication-provider>

<authentication-provider> Attributes

  • ref Defines a reference to a Spring bean that implements `AuthenticationProvider `.

If you have written your own AuthenticationProvider implementation (or want to configure one of Spring Security’s own implementations as a traditional bean for some reason, then you can use the following syntax to add it to the internal `ProviderManager’s list:

<security:authentication-manager>
<security:authentication-provider ref="myAuthenticationProvider" />
</security:authentication-manager>
<bean id="myAuthenticationProvider" class="com.something.MyAuthenticationProvider"/>
  • user-service-ref A reference to a bean that implements UserDetailsService that may be created using the standard bean element or the custom user-service element.

Child Elements of <authentication-provider>


authentication-provider 사용 예 

https://docs.spring.io/spring-security/site/docs/4.0.1.RELEASE/reference/htmlsingle/#ns-auth-providers 여기에 4.2.5 Using other Authentication Providers

 


 


<http auti-config="true" use-expressions="true" access-decision-manager-ref="myAccessDecisionManagerBean">
	<intercept-url pattern="/**" access="hasAnyAuthority('ADMIN','USER')"/>
    ..
</http>

1. access-decision-manager-ref 메서드 보안은 웹 보안과 동일한 AccessDecisionManager 구성을 사용하지만 이 속성을 사용하여 재정의할 수 있다. 
기본적으로 AffirmativeBased 구현은 RoleVoter 및 AuthentifiedVoter와 함께 사용한다.

2. intercept-url

특정한 URL에 접근할 때 인터셉터를 이용해서 접근을 제한하는 설정을 하는 경우 

pattern : url의 패턴

access : 권한 체크

* pattern과 access는 반드시 intercept-ulr에서 지정해야하는 필수속성이다.

 

질문 . 
사용자 권한을 authorities에 담는 것 까지는 알겠음.. (ADMIN, USER..이런거)
근데 이걸 담아 둔다고 해서.. intercept-url에서 그냥 쓰면되는건가?


위의 코드에서.. access-decision-manager-ref="myAccessDecisionMajagerBean" 이 부분..을 더 알아봐야 할 것 같다.



https://doing7.tistory.com/15

인증과 권한에 대한 처리는 AuthenticationManager
->AuthenticationProvider->UserDetailsService의 과정을 거치게 된다. 

<security:http>
	<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')" />
	<security:intercept-url pattern="/sample/admin" access="hasRole('ROLE_ADMIN')" />
    
	<security:form-login login-page="/customLogin"/> 
</security:http>
 
<security:authentication-manager>
	<security:authentication-provider>
		<security:user name="member" password="{noop}member" authorities="ROLE_MEMBER"/>
		<security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN"/>
    
	</security:authentication-provider>
</security:authentication-manager>​

9. 스프링 시큐리티 회원정보 이용하기

principal은 UserDetailsService에서 반환된 객체이다.

스프링 시큐리티에서 사용하는 표현식은 다음과 같다.

표현식  
hasRole([role])
hasAuthority
해당 권한이 있으면 true
hasAnyRole([role,role2])
hasAnyAuthority
여러 권한 중에서 하나라도 해당하는 권한이 있으면 true
principal 현재 사용자 정보를 의미
permitAll 모든 사용자
isAnomymous() 익명의 사용자(로그인을 하지 않은 경우)
denyAll 모든 사용자 거부
isAuthenticated() 인증된 사용자라면 true
isFullyAuthenticated() remember-me로 인증된 것이 아닌 인증된 사용자의 경우

이는 JSP에서 스프링 시큐리티를 사용할때 다음과 같이 이용할 수 있다.

<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %>

<sec:authorize access="isAnonymous()">
	<a href="/mypage/customlogin">Login</a>
</sec:authorize>

<sec:authorize access="isAuthenticated()">
	<a href="/mypage/logout">Logout</a>
</sec:authorize>

또한 컨트롤러에서 @PreAuthorize와 함께 다음과 같이 사용할 수도 있다.



https://developersp.tistory.com/6

getAuthorities()는 해당 사용자의 권한을 GrantedAuthority나 GrantedAuthority의 자식 클래스를 제네릭으로 갖는 컬렉션을 반환하는 메소드입니다. 제 코드에서는 SimpleGrantedAuthority라는 메소드를 사용하여 myGrant를 생성하여 리스트에 담은것을 반환하도록 하였습니다.

 

Context에서 변경할 수 있지만 기본적으로 Spring Security의 권한은 "ROLE_"로 시작하므로, 사용자가 갖는 최종 권한은 ADMIN, USER가 아닌 ROLE_ADMIN, ROLE_USER가 됩니다. (ADMIN과 USER는 제가 DB에 저장하는 권한인 grant_name입니다.) 



 

반응형