UsernamePasswordAuthenticationFilter config

This commit is contained in:
haerong22
2020-12-15 17:35:52 +09:00
parent 8e90d6b380
commit 647dc6793c
8 changed files with 83 additions and 19 deletions

View File

@@ -1,12 +1,14 @@
package com.security.jwt.auth;
import com.security.jwt.model.User;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
@Data
public class PrincipalDetails implements UserDetails {
private User user;

View File

@@ -19,7 +19,7 @@ public class PrincipalDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("시큐리티 로그인");
System.out.println("PrincipalDetailsService의 loadUserByUsername()");
User userEntity = userRepository.findByUsername(username);
return new PrincipalDetails(userEntity);
}

View File

@@ -2,7 +2,6 @@ package com.security.jwt.config;
import com.security.jwt.filter.MyFilter1;
import com.security.jwt.filter.MyFilter2;
import com.security.jwt.filter.MyFilter3;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -26,12 +25,12 @@ public class FilterConfig {
return bean;
}
@Bean
public FilterRegistrationBean<MyFilter3> filter3() {
FilterRegistrationBean<MyFilter3> bean = new FilterRegistrationBean<>(new MyFilter3());
bean.addUrlPatterns("/*");
bean.setOrder(0); // 낮은 번호의 필터부터 실행 된다.
return bean;
}
// @Bean
// public FilterRegistrationBean<MyFilter3> filter3() {
// FilterRegistrationBean<MyFilter3> bean = new FilterRegistrationBean<>(new MyFilter3());
// bean.addUrlPatterns("/*");
// bean.setOrder(0); // 낮은 번호의 필터부터 실행 된다.
// return bean;
// }
}

View File

@@ -1,14 +1,14 @@
package com.security.jwt.config;
import com.security.jwt.filter.MyFilter3;
import com.security.jwt.jwt.JwtAuthenticationFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.filter.CorsFilter;
@Configuration
@@ -18,6 +18,11 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final CorsFilter corsFilter;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// http.addFilterBefore(new MyFilter3(), SecurityContextPersistenceFilter.class);

View File

@@ -1,12 +1,21 @@
package com.security.jwt.controller;
import com.security.jwt.model.User;
import com.security.jwt.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class RestApiController {
private final UserRepository userRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@GetMapping("/home")
public String home() {
return "<h1>home</h1>";
@@ -16,4 +25,12 @@ public class RestApiController {
public String token() {
return "<h1>token</h1>";
}
@PostMapping("join")
public String join(@RequestBody User user) {
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
user.setRoles("ROLE_USER");
userRepository.save(user);
return "회원가입완료";
}
}

View File

@@ -1,10 +1,7 @@
package com.security.jwt.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class MyFilter1 implements Filter {

View File

@@ -1,13 +1,20 @@
package com.security.jwt.jwt;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.security.jwt.auth.PrincipalDetails;
import com.security.jwt.model.User;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
// 스프링 시큐리티 에서 UsernamePasswordAuthenticationFilter는
// /login 요청해서 username, password를 전송하면 (post) 동작한다.
@@ -22,16 +29,53 @@ public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilte
throws AuthenticationException {
System.out.println("JwtAuthenticationFilter : 로그인 시도중");
// 1. username, password 를 받는다.
try {
// BufferedReader br = request.getReader();
// String input = null;
// while((input = br.readLine())!=null) {
// System.out.println(input);
//
// }
ObjectMapper om = new ObjectMapper();
User user = om.readValue(request.getInputStream(), User.class);
System.out.println(user);
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
// PrincipalDetailsService 의 loadUserByUsername() 메소드 실행 후
// 정상이면 authentication이 리턴됨.
// DB에 있는 username과 password가 일치한다.
Authentication authentication = authenticationManager.authenticate(authenticationToken);
PrincipalDetails principalDetails= (PrincipalDetails) authentication.getPrincipal();
System.out.println("로그인 완료 : " + principalDetails.getUser().getUsername()); // 값이 있다면 로그인 완료
// authentication 객체를 return 하면 session영역에 저장됨. => 로그인 됨
// JWT를 사용하면서 굳이 세션을 만들 필요가 없지만
// 리턴의 이유는 권한 관리를 security가 대신 해주기 때문
return authentication;
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("========================================");
// 1. username, password 를 받는다.
// 2. 정상인지 로그인 시도를 한다.
// authenticationManager 로 로그인 시도를 하면
// -> PrincipalDetailsService가 호출
// -> loadUserByUsername() 메소드 실행
// 3. PrincipalDetials 를 세션에 담고 (권한 관리를 위해서)
// 4. JWT토큰을 만들어서 응답
return super.attemptAuthentication(request, response);
return null;
}
// attemptAuthentication 메소드 실행 후 인증이 정상적으로 되었으면
// successfulAuthentication 메소드 실행
// JWT 토큰을 만들어서 request요청한 사용자에게 JWT토큰을 response한다.
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
System.out.println("인증 완료 후 successfulAuthentication 실행");
super.successfulAuthentication(request, response, chain, authResult);
}
}

View File

@@ -16,7 +16,7 @@ spring:
jpa:
hibernate:
ddl-auto: create #create update none
ddl-auto: update #create update none
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
show-sql: true