{"componentChunkName":"component---src-templates-blog-post-js","path":"/springboot/스프링-부트-spring-security를-활용한-인증-및-권한부여/","result":{"data":{"site":{"siteMetadata":{"title":"Bottlehs Tech Blog","description":"웹·앱·AI 개발자 전병훈(bottlehs)의 기술 블로그. AI·LLM, JavaScript·Vue, Spring Boot, 알고리즘, 블록체인 실무 가이드를 다룹니다","siteUrl":"https://www.bottlehs.dev","author":{"name":"Jeon Byung Hun","summary":"개발을 즐기는 bottlehs - Engineer, MS, AI, FE, BE, OS, IOT, Blockchain, 설계, 테스트"},"social":{"github":"bottlehs","codepen":"bottlehs"}}},"markdownRemark":{"id":"1ea4453c-07ea-5d53-beef-1b152d171cbb","excerpt":"스프링 부트 Spring Security를 활용한 인증 및 권한부여 Spring Security…","html":"<p><img src=\"/assets/springboot.png\" alt=\"스프링 부트 Spring Security를 활용한 인증 및 권한부여\" title=\"스프링 부트 Spring Security를 활용한 인증 및 권한부여\"></p>\n<h2 id=\"spring-security스프링-시큐리티\" style=\"position:relative;\"><a href=\"#spring-security%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0\" aria-label=\"spring security스프링 시큐리티 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Spring Security(스프링 시큐리티)</h2>\n<p>스프링 시큐리티는 스프링 기반의 애플리케이션의 보안(인증과 권한,인가 등)을 담당하는 스프링 하위 프레임워크이다. 주로 서블릿 필터와 이들로 구성된 필터체인으로의 위임모델을 사용한다. 그리고 보안과 관련해서 체계적으로 많은 옵션을 제공해주기 때문에 개발자 입장에서는 일일이 보안관련 로직을 작성하지 않아도 된다.</p>\n<h2 id=\"보안-용어\" style=\"position:relative;\"><a href=\"#%EB%B3%B4%EC%95%88-%EC%9A%A9%EC%96%B4\" aria-label=\"보안 용어 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>보안 용어</h2>\n<p>스프링 시큐리티를 접하기 이전 밑에서 나열할 보안 용어들은 정말 필수로 숙지하면 도움이 된다.</p>\n<ul>\n<li>접근 주체(Principal) : 보호된 리소스에 접근하는 대상</li>\n<li>인증(Authentication) : 보호된 리소스에 접근한 대상에 대해 이 유저가 누구인지, 애플리케이션의 작업을 수행해도 되는 주체인지 확인하는 과정(ex. Form 기반 Login)</li>\n<li>인가(Authorize) : 해당 리소스에 대해 접근 가능한 권한을 가지고 있는지 확인하는 과정(After Authentication, 인증 이후)</li>\n<li>권한 : 어떠한 리소스에 대한 접근 제한, 모든 리소스는 접근 제어 권한이 걸려있다. 즉, 인가 과정에서 해당 리소스에 대한 제한된 최소한의 권한을 가졌는지 확인.</li>\n</ul>\n<h2 id=\"인증-아키텍쳐\" style=\"position:relative;\"><a href=\"#%EC%9D%B8%EC%A6%9D-%EC%95%84%ED%82%A4%ED%85%8D%EC%B3%90\" aria-label=\"인증 아키텍쳐 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>인증 아키텍쳐</h2>\n<p>아래는 Form 로그인에 대한 플로우 이다.</p>\n<h3 id=\"spring-security-authentication-architecture\" style=\"position:relative;\"><a href=\"#spring-security-authentication-architecture\" aria-label=\"spring security authentication architecture permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Spring Security Authentication Architecture</h3>\n<p><img src=\"/assets/spring-security-authentication-architecture.png\" alt=\"Spring Security Authentication Architecture\" title=\"Spring Security Authentication Architecture\"></p>\n<ol>\n<li>사용자가 Form을 통해 로그인 정보를 입력하고 인증 요청을 보낸다.</li>\n<li>AuthenticationFilter(사용할 구현체 UsernamePasswordAuthenticationFilter)가 HttpServletRequest에서 사용자가 보낸 아이디와 패스워드를 인터셉트한다. 프론트 단에서 유효성검사를 할 수도 있지만, 안전을 위해서 다시 한번 사용자가 보낸 아이디와 패스워드의 유효성 검사를 한다. HttpServletRequest에서 꺼내온 사용자 아이디와 패스워드를 진짜 인증을 담당할 AuthenticationManager 인터페이스(구현체 - ProviderManager)에게 인증용 객체(UsernamePasswordAuthenticationToken)로 만들어줘서 위임한다.</li>\n<li>AuthenticationFilter에게 인증용 객체(UsernamePasswordAuthenticationToken)을 전달받는다.</li>\n<li>실제 인증을 할 AuthenticationProvider에게 Authentication객체(UsernamePasswordAuthenticationToken)을 다시 전달한다.</li>\n<li>DB에서 사용자 인증 정보를 가져올 UserDetailsService 객체에게 사용자 아이디를 넘겨주고 DB에서 인증에 사용할 사용자 정보(사용자 아이디, 암호화된 패스워드, 권한 등)를 UserDetails(인증용 객체와 도메인 객체를 분리하지 않기 위해서 실제 사용되는 도메인 객체에 UserDetails를 상속하기도 한다.)라는 객체로 전달 받는다.</li>\n<li>AuthenticationProvider는 UserDetails 객체를 전달 받은 이후 실제 사용자의 입력정보와 UserDetails 객체를 가지고 인증을 시도한다.</li>\n<li>\n<ol start=\"8\">\n<li>\n<ol start=\"9\">\n<li>\n<ol start=\"10\">\n<li>인증이 완료되면 사용자 정보를 가진 Authentication 객체를 SecurityContextHolder에 담은 이후 AuthenticationSuccessHandle를 실행한다.(실패시 AuthenticationFailureHandler를 실행한다.)</li>\n</ol>\n</li>\n</ol>\n</li>\n</ol>\n</li>\n</ol>\n<h3 id=\"spring-security-filter\" style=\"position:relative;\"><a href=\"#spring-security-filter\" aria-label=\"spring security filter permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Spring Security Filter</h3>\n<p><img src=\"/assets/spring-security-filter.png\" alt=\"Spring Security Filter\" title=\"Spring Security Filter\"></p>\n<ul>\n<li>SecurityContextPersistenceFilter : SecurityContextRepository에서 SecurityContext를 가져오거나 저장하는 역할을 한다.</li>\n<li>LogoutFilter : 설정된 로그아웃 URL로 오는 요청을 감시하며, 해당 유저를 로그아웃 처리</li>\n<li>\n<p>(UsernamePassword)AuthenticationFilter : (아이디와 비밀번호를 사용하는 form 기반 인증) 설정된 로그인 URL로 오는 요청을 감시하며, 유저 인증 처리</p>\n<ul>\n<li>AuthenticationManager를 통한 인증 실행</li>\n<li>인증 성공 시, 얻은 Authentication 객체를 SecurityContext에 저장 후 AuthenticationSuccessHandler 실행</li>\n<li>인증 실패 시, AuthenticationFailureHandler 실행</li>\n</ul>\n</li>\n<li>DefaultLoginPageGeneratingFilter : 인증을 위한 로그인폼 URL을 감시한다.</li>\n<li>BasicAuthenticationFilter : HTTP 기본 인증 헤더를 감시하여 처리한다.</li>\n<li>RequestCacheAwareFilter : 로그인 성공 후, 원래 요청 정보를 재구성하기 위해 사용된다.</li>\n<li>SecurityContextHolderAwareRequestFilter : HttpServletRequestWrapper를 상속한 SecurityContextHolderAwareRequestWapper 클래스로 HttpServletRequest 정보를 감싼다. SecurityContextHolderAwareRequestWrapper 클래스는 필터 체인상의 다음 필터들에게 부가정보를 제공한다.</li>\n<li>AnonymousAuthenticationFilter : 이 필터가 호출되는 시점까지 사용자 정보가 인증되지 않았다면 인증토큰에 사용자가 익명 사용자로 나타난다.</li>\n<li>SessionManagementFilter : 이 필터는 인증된 사용자와 관련된 모든 세션을 추적한다.</li>\n<li>ExceptionTranslationFilter : 이 필터는 보호된 요청을 처리하는 중에 발생할 수 있는 예외를 위임하거나 전달하는 역할을 한다.</li>\n<li>FilterSecurityInterceptor : 이 필터는 AccessDecisionManager 로 권한부여 처리를 위임함으로써 접근 제어 결정을 쉽게해준다.</li>\n</ul>\n<h3 id=\"authentication\" style=\"position:relative;\"><a href=\"#authentication\" aria-label=\"authentication permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Authentication</h3>\n<p>접근 주체는 Authentication 객체를 생성한다. 이 객체는 SecurityContext(내부 메모리)에 보관되고 사용되어진다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">interface</span> <span class=\"token class-name\">Authentication</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Principal</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">Serializable</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token class-name\">Collection</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token operator\">?</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">GrantedAuthority</span><span class=\"token punctuation\">></span></span> <span class=\"token function\">getAuthorities</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Authentication 저장소에 의해 인증된 사용자의 권한 목록</span>\n    <span class=\"token class-name\">Object</span> <span class=\"token function\">getCredentials</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 비밀번호</span>\n    <span class=\"token class-name\">Object</span> <span class=\"token function\">getDetails</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 사용자 상세정보</span>\n    <span class=\"token class-name\">Object</span> <span class=\"token function\">getPrincipal</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// ID</span>\n    <span class=\"token keyword\">boolean</span> <span class=\"token function\">isAuthenticated</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">//인증 여부</span>\n    <span class=\"token keyword\">void</span> <span class=\"token function\">setAuthenticated</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">boolean</span> isAuthenticated<span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">IllegalArgumentException</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3 id=\"authenticationmanager\" style=\"position:relative;\"><a href=\"#authenticationmanager\" aria-label=\"authenticationmanager permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>AuthenticationManager</h3>\n<p><img src=\"/assets/spring-security-authentication-manager.png\" alt=\"Spring Security Authentication Manager\" title=\"Spring Security Authentication Manager\"></p>\n<p>유저의 요청을 AuthenticationFilter에서 Authentication 객체로 변환해 AuthenticationManager(ProviderManager)에게 넘겨주고, AuthenticationProvider(DaoAuthenticationProvider)가 실제 인증을 한 이후에 인증이 완료되면 Authentication객체를 반환해준다.</p>\n<ul>\n<li>AbstractAuthenticationProcessingFilter : 웹 기반 인증요청에서 사용되는 컴포넌트로 POST 폼 데이터를 포함하는 요청을 처리한다. 사용자 비밀번호를 다른 필터로 전달하기 위해서 Authentication 객체를 생성하고 일부 프로퍼티를 설정한다.</li>\n<li>AuthenticationManager : 인증요청을 받고 Authentication을 채워준다.</li>\n<li>AuthenticationProvider : 실제 인증이 일어나고 만약 인증 성공시 Authentication 객체의 authenticated = true로 설정해준다.</li>\n</ul>\n<p>Spring Security 는 ProviderManager 라는 AuthenticationManager 인터페이스의 유일한 구현체를 제공한다. ProviderManager 는 하나 또는 여러 개의 AuthenticationProvider 구현체를 사용할 수 있다. AuthenticationProvider는 많이 사용되고 ProviderManager(AuthenticationManager 의 구현체) 와도 잘 통합되기 때문에 기본적으로 어떻게 동작하는 지 이해하는 것이 중요하다.</p>\n<h3 id=\"password-authentication\" style=\"position:relative;\"><a href=\"#password-authentication\" aria-label=\"password authentication permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Password Authentication</h3>\n<p><img src=\"/assets/spring-security-password-authentication.png\" alt=\"Spring Security Password Authentication\" title=\"Spring Security Password Authentication\"></p>\n<p>DaoAuthenticationProvider 는 UserDetailsService 타입 오브젝트로 위임한다. UserDetailsService 는 UserDetails 구현체를 리턴하는 역할을 한다. UserDetails 인터페이스는 이전에 설명한 Authentication 인터페이스와 상당히 유사하지만 서로 다른 목적을 가진 인터페이스이므로 헷갈리면 안된다.</p>\n<ul>\n<li>Authentication : 사용자 ID, 패스워드와 인증 요청 컨텍스트에 대한 정보를 가지고 있다. 인증 이후의 사용자 상세정보와 같은 UserDetails 타입 오브젝트를 포함할 수도 있다.</li>\n<li>UserDetails : 이름, 이메일, 전화번호와 같은 사용자 프로파일 정보를 저장하기 위한 용도로 사용한다.</li>\n</ul>\n<h3 id=\"authentication-exception\" style=\"position:relative;\"><a href=\"#authentication-exception\" aria-label=\"authentication exception permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Authentication Exception</h3>\n<p>인증과 관련된 모든 예외는 AuthenticationException 을 상속한다. AuthenticationException 은 개발자에게 상세한 디버깅 정보를 제공하기위한 두개의 멤버 필드를 가지고 있다.</p>\n<ul>\n<li>authentication : 인증 요청관련 Authentication 객체를 저장하고 있다.</li>\n<li>extraInformation : 인증 예외 관련 부가 정보를 저장한다. 예를 들어 UsernameNotFoundException 예외는 인증에 실패한 유저의 id 정보를 저장하고 있다.</li>\n</ul>\n<h2 id=\"구현\" style=\"position:relative;\"><a href=\"#%EA%B5%AC%ED%98%84\" aria-label=\"구현 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>구현</h2>\n<p>Spring Security 를 활용한 예제를 구현할 것이다.</p>\n<h3 id=\"사전-세팅\" style=\"position:relative;\"><a href=\"#%EC%82%AC%EC%A0%84-%EC%84%B8%ED%8C%85\" aria-label=\"사전 세팅 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>사전 세팅</h3>\n<p>프로젝트에서 사용할 Dependency들을 build.gradle에 추가한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"groovy\"><pre class=\"language-groovy\"><code class=\"language-groovy\">dependencies <span class=\"token punctuation\">{</span>\n    implementation <span class=\"token string\">'org.mariadb.jdbc:mariadb-java-client'</span>\n    implementation <span class=\"token string\">'org.springframework.boot:spring-boot-starter-data-jpa'</span>\n\n    implementation <span class=\"token string\">'org.springframework.boot:spring-boot-starter-security'</span>\n\n    implementation <span class=\"token string\">'org.springframework.boot:spring-boot-starter-thymeleaf'</span>\n    implementation <span class=\"token string\">'org.springframework.boot:spring-boot-starter-web'</span>\n\n    compileOnly <span class=\"token string\">'org.projectlombok:lombok'</span>\n    annotationProcessor <span class=\"token string\">'org.projectlombok:lombok'</span>\n\n    <span class=\"token function\">testImplementation</span><span class=\"token punctuation\">(</span><span class=\"token string\">'org.springframework.boot:spring-boot-starter-test'</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        exclude group<span class=\"token punctuation\">:</span> <span class=\"token string\">'org.junit.vintage'</span><span class=\"token punctuation\">,</span> module<span class=\"token punctuation\">:</span> <span class=\"token string\">'junit-vintage-engine'</span>\n    <span class=\"token punctuation\">}</span>\n    testImplementation <span class=\"token string\">'org.springframework.security:spring-security-test'</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>정적 자원을 제공하는 클래스를 생성하여 아래와 같이 설정한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Configuration</span>\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">WebMvcConfig</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">WebMvcConfigurer</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> <span class=\"token constant\">CLASSPATH_RESOURCE_LOCATIONS</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token string\">\"classpath:/static/\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"classpath:/public/\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"classpath:/\"</span><span class=\"token punctuation\">,</span>\n            <span class=\"token string\">\"classpath:/resources/\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"classpath:/META-INF/resources/\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"classpath:/META-INF/resources/webjars/\"</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">addViewControllers</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">ViewControllerRegistry</span> registry<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token comment\">// /에 해당하는 url mapping을 /common/test로 forward한다.</span>\n        registry<span class=\"token punctuation\">.</span><span class=\"token function\">addViewController</span><span class=\"token punctuation\">(</span> <span class=\"token string\">\"/\"</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">setViewName</span><span class=\"token punctuation\">(</span> <span class=\"token string\">\"forward:/index\"</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token comment\">// 우선순위를 가장 높게 잡는다.</span>\n        registry<span class=\"token punctuation\">.</span><span class=\"token function\">setOrder</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Ordered</span><span class=\"token punctuation\">.</span><span class=\"token constant\">HIGHEST_PRECEDENCE</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">addResourceHandlers</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">ResourceHandlerRegistry</span> registry<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        registry<span class=\"token punctuation\">.</span><span class=\"token function\">addResourceHandler</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/**\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">addResourceLocations</span><span class=\"token punctuation\">(</span><span class=\"token constant\">CLASSPATH_RESOURCE_LOCATIONS</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>SpringSecurity에 대한 기본적인 설정들을 추가한다. SpringSecurity에 대한 설정 클래스에서는 아래와 같이 설정 한다.</p>\n<ul>\n<li>configure 메소드를 통해 정적 자원들에 대해서는 Security를 적용하지 않음을 추가한다.</li>\n<li>configure 메소드를 통해 어떤 요청에 대해서는 로그인을 요구하고, 어떤 요청에 대해서 로그인을 요구하지 않을지 설정한다.</li>\n<li>form 기반의 로그인을 활용하는 경우 로그인 URL, 로그인 성공시 전달할 URL, 로그인 실패 URL 등에 대해서 설정한다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">package</span> <span class=\"token namespace\">com<span class=\"token punctuation\">.</span>mang<span class=\"token punctuation\">.</span>example<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">.</span>security</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>boot<span class=\"token punctuation\">.</span>autoconfigure<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>servlet<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">PathRequest</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>context<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">Bean</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>context<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">Configuration</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span>web<span class=\"token punctuation\">.</span>builders<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">HttpSecurity</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span>web<span class=\"token punctuation\">.</span>builders<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">WebSecurity</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span>web<span class=\"token punctuation\">.</span>configuration<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">EnableWebSecurity</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span>web<span class=\"token punctuation\">.</span>configuration<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">WebSecurityConfigurerAdapter</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>crypto<span class=\"token punctuation\">.</span>bcrypt<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">BCryptPasswordEncoder</span></span><span class=\"token punctuation\">;</span>\n\n<span class=\"token annotation punctuation\">@Configuration</span>\n<span class=\"token annotation punctuation\">@EnableWebSecurity</span>\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">WebSecurityConfig</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">WebSecurityConfigurerAdapter</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token comment\">// 정적 자원에 대해서는 Security 설정을 적용하지 않음.</span>\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">configure</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">WebSecurity</span> web<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        web<span class=\"token punctuation\">.</span><span class=\"token function\">ignoring</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">requestMatchers</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">PathRequest</span><span class=\"token punctuation\">.</span><span class=\"token function\">toStaticResources</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">atCommonLocations</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">protected</span> <span class=\"token keyword\">void</span> <span class=\"token function\">configure</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">HttpSecurity</span> http<span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">Exception</span> <span class=\"token punctuation\">{</span>\n        http<span class=\"token punctuation\">.</span><span class=\"token function\">csrf</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">disable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">authorizeRequests</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// /about 요청에 대해서는 로그인을 요구함</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">antMatchers</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/about\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">authenticated</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// /admin 요청에 대해서는 ROLE_ADMIN 역할을 가지고 있어야 함</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">antMatchers</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/admin\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">hasRole</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"ADMIN\"</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// 나머지 요청에 대해서는 로그인을 요구하지 않음</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">anyRequest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">permitAll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">and</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// 로그인하는 경우에 대해 설정함</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">formLogin</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// 로그인 페이지를 제공하는 URL을 설정함</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">loginPage</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/user/loginView\"</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// 로그인 성공 URL을 설정함</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">successForwardUrl</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/index\"</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// 로그인 실패 URL을 설정함</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">failureForwardUrl</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/index\"</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">permitAll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">and</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">addFilterBefore</span><span class=\"token punctuation\">(</span><span class=\"token function\">customAuthenticationFilter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">UsernamePasswordAuthenticationFilter</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token annotation punctuation\">@Bean</span>\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">BCryptPasswordEncoder</span> <span class=\"token function\">bCryptPasswordEncoder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">BCryptPasswordEncoder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"language-text\">/about</code> 에 대해서는 로그인이 성공한 경우에만 접근가능하고, <code class=\"language-text\">/admin</code>에 대해서는 로그인 후에 ROLE_ADMIN 역할을 갖고 있는 경우에만 접근가능하도록 설정해준다.</p>\n<h3 id=\"로그인-요청\" style=\"position:relative;\"><a href=\"#%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%9A%94%EC%B2%AD\" aria-label=\"로그인 요청 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>로그인 요청</h3>\n<p>사용자는 로그인 하기 위해 아이디와 비밀번호를 입력해서 로그인 요청을 하게 된다.</p>\n<h3 id=\"userpasswordauthenticationtoken-발급\" style=\"position:relative;\"><a href=\"#userpasswordauthenticationtoken-%EB%B0%9C%EA%B8%89\" aria-label=\"userpasswordauthenticationtoken 발급 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>UserPasswordAuthenticationToken 발급</h3>\n<p>전송이 오면 AuthenticationFilter로 요청이 먼저 오게 되고, 아이디와 비밀번호를 기반으로 UserPasswordAuthenticationToken을 발급해준다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">lombok<span class=\"token punctuation\">.</span>extern<span class=\"token punctuation\">.</span>log4j<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">Log4j2</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>authentication<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">AuthenticationManager</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>authentication<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">UsernamePasswordAuthenticationToken</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>core<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">Authentication</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>core<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">AuthenticationException</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>web<span class=\"token punctuation\">.</span>authentication<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">UsernamePasswordAuthenticationFilter</span></span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">javax<span class=\"token punctuation\">.</span>servlet<span class=\"token punctuation\">.</span>http<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">HttpServletRequest</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">javax<span class=\"token punctuation\">.</span>servlet<span class=\"token punctuation\">.</span>http<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">HttpServletResponse</span></span><span class=\"token punctuation\">;</span>\n\n<span class=\"token annotation punctuation\">@Log4j2</span>\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">CustomAuthenticationFilter</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">UsernamePasswordAuthenticationFilter</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">CustomAuthenticationFilter</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">AuthenticationManager</span> authenticationManager<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">super</span><span class=\"token punctuation\">.</span><span class=\"token function\">setAuthenticationManager</span><span class=\"token punctuation\">(</span>authenticationManager<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">Authentication</span> <span class=\"token function\">attemptAuthentication</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">HttpServletRequest</span> request<span class=\"token punctuation\">,</span> <span class=\"token class-name\">HttpServletResponse</span> response<span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">AuthenticationException</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">UsernamePasswordAuthenticationToken</span> authRequest <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">UsernamePasswordAuthenticationToken</span><span class=\"token punctuation\">(</span>request<span class=\"token punctuation\">.</span><span class=\"token function\">getParameter</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"userEmail\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> request<span class=\"token punctuation\">.</span><span class=\"token function\">getParameter</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"userPw\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">setDetails</span><span class=\"token punctuation\">(</span>request<span class=\"token punctuation\">,</span> authRequest<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">getAuthenticationManager</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">authenticate</span><span class=\"token punctuation\">(</span>authRequest<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>제작한 Filter를 이제 적용시켜야 하므로 UsernamePasswordAuthenticationFilter 필터 이전에 적용시켜야 한다. 그리고 해당 CustomAuthenticationFilter가 수행된 후에 처리될 Handler 역시 Bean으로 등록하고 CustomAuthenticationFilter의 핸들러로 추가해주어야 하는데, 해당 코드들은 WebSecurityConfig에 아래와 같이 추가해줄 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>core<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">Authentication</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>core<span class=\"token punctuation\">.</span>context<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">SecurityContextHolder</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>web<span class=\"token punctuation\">.</span>authentication<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">SavedRequestAwareAuthenticationSuccessHandler</span></span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">javax<span class=\"token punctuation\">.</span>servlet<span class=\"token punctuation\">.</span>http<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">HttpServletRequest</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">javax<span class=\"token punctuation\">.</span>servlet<span class=\"token punctuation\">.</span>http<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">HttpServletResponse</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">java<span class=\"token punctuation\">.</span>io<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">IOException</span></span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">CustomLoginSuccessHandler</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">SavedRequestAwareAuthenticationSuccessHandler</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">onAuthenticationSuccess</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">HttpServletRequest</span> request<span class=\"token punctuation\">,</span> <span class=\"token class-name\">HttpServletResponse</span> response<span class=\"token punctuation\">,</span>\n                                        <span class=\"token class-name\">Authentication</span> authentication<span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">IOException</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">SecurityContextHolder</span><span class=\"token punctuation\">.</span><span class=\"token function\">getContext</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">setAuthentication</span><span class=\"token punctuation\">(</span>authentication<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        response<span class=\"token punctuation\">.</span><span class=\"token function\">sendRedirect</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/about\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>CustomLoginSuccessHandler는 AuthenticationProvider를 통해 인증이 성공될 경우 처리되는데, 이번 예제에서는 /about 요청으로 redirect되도록 해준다. 그리고 토큰을 사용하지 않고 세션을 활용하는 지금 예제같은 경우에는 성공하여 반환된 Authentication 객체를 SecurityContextHolder의 Contetx에 저장해준다. 나중에 사용자의 정보를 꺼낼 경우에도 SecurityContextHolder의 context에서 조회하면 된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">package</span> <span class=\"token namespace\">com<span class=\"token punctuation\">.</span>mang<span class=\"token punctuation\">.</span>example<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">.</span>security</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>boot<span class=\"token punctuation\">.</span>autoconfigure<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>servlet<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">PathRequest</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>context<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">Bean</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>context<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">Configuration</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span>web<span class=\"token punctuation\">.</span>builders<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">HttpSecurity</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span>web<span class=\"token punctuation\">.</span>builders<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">WebSecurity</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span>web<span class=\"token punctuation\">.</span>configuration<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">EnableWebSecurity</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>config<span class=\"token punctuation\">.</span>annotation<span class=\"token punctuation\">.</span>web<span class=\"token punctuation\">.</span>configuration<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">WebSecurityConfigurerAdapter</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token import\"><span class=\"token namespace\">org<span class=\"token punctuation\">.</span>springframework<span class=\"token punctuation\">.</span>security<span class=\"token punctuation\">.</span>crypto<span class=\"token punctuation\">.</span>bcrypt<span class=\"token punctuation\">.</span></span><span class=\"token class-name\">BCryptPasswordEncoder</span></span><span class=\"token punctuation\">;</span>\n\n<span class=\"token annotation punctuation\">@Configuration</span>\n<span class=\"token annotation punctuation\">@EnableWebSecurity</span>\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">WebSecurityConfig</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">WebSecurityConfigurerAdapter</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token comment\">// 정적 자원에 대해서는 Security 설정을 적용하지 않음.</span>\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">configure</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">WebSecurity</span> web<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        web<span class=\"token punctuation\">.</span><span class=\"token function\">ignoring</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">requestMatchers</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">PathRequest</span><span class=\"token punctuation\">.</span><span class=\"token function\">toStaticResources</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">atCommonLocations</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">protected</span> <span class=\"token keyword\">void</span> <span class=\"token function\">configure</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">HttpSecurity</span> http<span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">Exception</span> <span class=\"token punctuation\">{</span>\n        http<span class=\"token punctuation\">.</span><span class=\"token function\">csrf</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">disable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">authorizeRequests</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// /about 요청에 대해서는 로그인을 요구함</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">antMatchers</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/about\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">authenticated</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// /admin 요청에 대해서는 ROLE_ADMIN 역할을 가지고 있어야 함</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">antMatchers</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/admin\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">hasRole</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"ADMIN\"</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// 나머지 요청에 대해서는 로그인을 요구하지 않음</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">anyRequest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">permitAll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">and</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// 로그인하는 경우에 대해 설정함</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">formLogin</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// 로그인 페이지를 제공하는 URL을 설정함</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">loginPage</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/user/loginView\"</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// 로그인 성공 URL을 설정함</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">successForwardUrl</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/index\"</span><span class=\"token punctuation\">)</span>\n                <span class=\"token comment\">// 로그인 실패 URL을 설정함</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">failureForwardUrl</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/index\"</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">permitAll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">and</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">addFilterBefore</span><span class=\"token punctuation\">(</span><span class=\"token function\">customAuthenticationFilter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">UsernamePasswordAuthenticationFilter</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token annotation punctuation\">@Bean</span>\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">BCryptPasswordEncoder</span> <span class=\"token function\">bCryptPasswordEncoder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">BCryptPasswordEncoder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token annotation punctuation\">@Bean</span>\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">CustomAuthenticationFilter</span> <span class=\"token function\">customAuthenticationFilter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">Exception</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">CustomAuthenticationFilter</span> customAuthenticationFilter <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">CustomAuthenticationFilter</span><span class=\"token punctuation\">(</span><span class=\"token function\">authenticationManager</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        customAuthenticationFilter<span class=\"token punctuation\">.</span><span class=\"token function\">setFilterProcessesUrl</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/user/login\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        customAuthenticationFilter<span class=\"token punctuation\">.</span><span class=\"token function\">setAuthenticationSuccessHandler</span><span class=\"token punctuation\">(</span><span class=\"token function\">customLoginSuccessHandler</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        customAuthenticationFilter<span class=\"token punctuation\">.</span><span class=\"token function\">afterPropertiesSet</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> customAuthenticationFilter<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token annotation punctuation\">@Bean</span>\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">CustomLoginSuccessHandler</span> <span class=\"token function\">customLoginSuccessHandler</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">CustomLoginSuccessHandler</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>CustomAuthenticationFilter를 빈으로 등록하는 과정에서 UserName파라미터와 UserPassword파라미터를 설정할 수 있다. 이러한 과정을 거치면 UsernamePasswordToken이 발급되게 된다.</p>\n<p>자세한 소스 코드는 ”<a href=\"https://github.com/bottlehs/springboot-vue-starter-kit\">https://github.com/bottlehs/springboot-vue-starter-kit</a>” 참고 하길 바란다.</p>","tableOfContents":"<ul>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#spring-security%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0\">Spring Security(스프링 시큐리티)</a></li>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#%EB%B3%B4%EC%95%88-%EC%9A%A9%EC%96%B4\">보안 용어</a></li>\n<li>\n<p><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#%EC%9D%B8%EC%A6%9D-%EC%95%84%ED%82%A4%ED%85%8D%EC%B3%90\">인증 아키텍쳐</a></p>\n<ul>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#spring-security-authentication-architecture\">Spring Security Authentication Architecture</a></li>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#spring-security-filter\">Spring Security Filter</a></li>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#authentication\">Authentication</a></li>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#authenticationmanager\">AuthenticationManager</a></li>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#password-authentication\">Password Authentication</a></li>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#authentication-exception\">Authentication Exception</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#%EA%B5%AC%ED%98%84\">구현</a></p>\n<ul>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#%EC%82%AC%EC%A0%84-%EC%84%B8%ED%8C%85\">사전 세팅</a></li>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%9A%94%EC%B2%AD\">로그인 요청</a></li>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-spring-security%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9D%B8%EC%A6%9D-%EB%B0%8F-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC/#userpasswordauthenticationtoken-%EB%B0%9C%EA%B8%89\">UserPasswordAuthenticationToken 발급</a></li>\n</ul>\n</li>\n</ul>","wordCount":{"words":891},"fields":{"slug":"/springboot/스프링-부트-spring-security를-활용한-인증-및-권한부여/","image":"/assets/springboot.png","faq":[]},"frontmatter":{"title":"스프링 부트 Spring Security를 활용한 인증 및 권한부여","date":"2021년 4월 8일","dateISO":"2021-04-08T22:19:29.537Z","updatedISO":null,"category":"springboot","description":"스프링 시큐리티는 스프링 기반의 애플리케이션의 보안(인증과 권한,인가 등)을 담당하는 스프링 하위 프레임워크이다. 주로 서블릿 필터와 이들로 구성된 필터체인으로의 위임모델을 사용한다. 그리고 보안과 관련해서 체계적으로 많은 옵션을 제공해주기 때문에 개발자 입장에서는 일일이 보안관련 로직을 작성하지 않아도 된다.","tags":["스프링","스프링부트","Spring","SpringBoot","Java","프레임워크","스프링부트구조","아키텍쳐","Spring Security"]}}},"pageContext":{"slug":"/springboot/스프링-부트-spring-security를-활용한-인증-및-권한부여/","previous":{"fields":{"slug":"/springboot/스프링-부트-message-source를-활용한-exception-처리/"},"frontmatter":{"title":"스프링 부트 MessageSource를 활용한 Exception 처리","tags":["스프링","스프링부트","Spring","SpringBoot","Java","프레임워크","스프링부트구조","아키텍쳐","MessageSource"]}},"next":{"fields":{"slug":"/springboot/스프링-부트-unit-test/"},"frontmatter":{"title":"스프링 부트 Unit Test","tags":["스프링","스프링부트","Spring","SpringBoot","Java","프레임워크","스프링부트구조","아키텍쳐","Junit"]}}}},"staticQueryHashes":["213619243","3262363727"]}