jwt filter
This commit is contained in:
27
codingtest/src/Test.java
Normal file
27
codingtest/src/Test.java
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
|
||||
public class Test {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(solution("ABABAAAAABA"));
|
||||
}
|
||||
|
||||
public static int solution(String name) {
|
||||
int len = name.length();
|
||||
int move = len-1;
|
||||
int answer = 0 ;
|
||||
|
||||
for(int i=0; i<len; ++i) {
|
||||
answer += Math.min(name.charAt(i) - 'A', 91 - name.charAt(i));
|
||||
|
||||
int next = i+1;
|
||||
while(next<len && name.charAt(next)=='A') {
|
||||
++next;
|
||||
}
|
||||
move = Math.min(move,i+len-next+Math.min(i,len-next));
|
||||
}
|
||||
answer += move;
|
||||
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.security.jwt.auth;
|
||||
|
||||
import com.security.jwt.model.User;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
public class PrincipalDetails implements UserDetails {
|
||||
|
||||
private User user;
|
||||
|
||||
public PrincipalDetails(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
|
||||
Collection<GrantedAuthority> authorities = new ArrayList<>();
|
||||
user.getRoleList().forEach(r -> {
|
||||
authorities.add(() -> r);
|
||||
});
|
||||
return authorities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return user.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return user.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.security.jwt.auth;
|
||||
|
||||
import com.security.jwt.model.User;
|
||||
import com.security.jwt.repository.UserRepository;
|
||||
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;
|
||||
|
||||
// http://localhost:8080/login
|
||||
// -> 스프링 시큐리티 기본 요청 주소이지만 formlogin을 disable로 설정하였기 때문에 동작 안함
|
||||
// -> UsernamePasswordAuthenticationFilter 등록해줘야한다.
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PrincipalDetailsService implements UserDetailsService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
System.out.println("시큐리티 로그인");
|
||||
User userEntity = userRepository.findByUsername(username);
|
||||
return new PrincipalDetails(userEntity);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ 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;
|
||||
@@ -13,7 +14,7 @@ public class FilterConfig {
|
||||
public FilterRegistrationBean<MyFilter1> filter1() {
|
||||
FilterRegistrationBean<MyFilter1> bean = new FilterRegistrationBean<>(new MyFilter1());
|
||||
bean.addUrlPatterns("/*");
|
||||
bean.setOrder(0); // 낮은 번호의 필터부터 실행 된다.
|
||||
bean.setOrder(1); // 낮은 번호의 필터부터 실행 된다.
|
||||
return bean;
|
||||
}
|
||||
|
||||
@@ -21,7 +22,15 @@ public class FilterConfig {
|
||||
public FilterRegistrationBean<MyFilter2> filter2() {
|
||||
FilterRegistrationBean<MyFilter2> bean = new FilterRegistrationBean<>(new MyFilter2());
|
||||
bean.addUrlPatterns("/*");
|
||||
bean.setOrder(1); // 낮은 번호의 필터부터 실행 된다.
|
||||
bean.setOrder(2); // 낮은 번호의 필터부터 실행 된다.
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<MyFilter3> filter3() {
|
||||
FilterRegistrationBean<MyFilter3> bean = new FilterRegistrationBean<>(new MyFilter3());
|
||||
bean.addUrlPatterns("/*");
|
||||
bean.setOrder(0); // 낮은 번호의 필터부터 실행 된다.
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package com.security.jwt.config;
|
||||
|
||||
import com.security.jwt.filter.MyFilter1;
|
||||
import com.security.jwt.filter.MyFilter3;
|
||||
import com.security.jwt.jwt.JwtAuthenticationFilter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.authentication.www.BasicAuthenticationFilter;
|
||||
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
|
||||
@Configuration
|
||||
@@ -19,12 +20,14 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// http.addFilterBefore(new MyFilter3(), SecurityContextPersistenceFilter.class);
|
||||
http.csrf().disable();
|
||||
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 세션 사용 X
|
||||
.and()
|
||||
.addFilter(corsFilter) // @CrossOrigin(인증X), 시큐리티 필터에 등록(인증O) 모든 요청이 corsFilter를 거친다.
|
||||
.formLogin().disable()
|
||||
.httpBasic().disable()
|
||||
.addFilter(new JwtAuthenticationFilter(authenticationManager())) // AuthenticationManager
|
||||
.authorizeRequests()
|
||||
.antMatchers("/api/v1/user/**")
|
||||
.access("hasRole('ROLE_USER') or hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
|
||||
|
||||
@@ -12,23 +12,8 @@ public class MyFilter1 implements Filter {
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
|
||||
throws IOException, ServletException {
|
||||
|
||||
HttpServletRequest req = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse res = (HttpServletResponse) servletResponse;
|
||||
System.out.println("필터1");
|
||||
|
||||
// 토큰이 넘어오면
|
||||
if(req.getMethod().equals("POST")) {
|
||||
System.out.println("POST 요청됨");
|
||||
String headerAuth = req.getHeader("Authorization");
|
||||
System.out.println(headerAuth);
|
||||
|
||||
if (headerAuth != null && headerAuth.equals("cos")) {
|
||||
filterChain.doFilter(req, res);
|
||||
} else {
|
||||
PrintWriter out = res.getWriter();
|
||||
out.println("인증 안됨");
|
||||
}
|
||||
} else {
|
||||
filterChain.doFilter(req, res);
|
||||
}
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
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 MyFilter3 implements Filter {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
|
||||
throws IOException, ServletException {
|
||||
|
||||
HttpServletRequest req = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse res = (HttpServletResponse) servletResponse;
|
||||
|
||||
// id, pw 정상적으로 들어와서 로그인이 완료 되면 토큰을 만들어주고 응답
|
||||
// 요청할 때 마다 header에 Authorization에 value 값으로 토큰이 넘어온다.
|
||||
// 넘어온 토큰이 내가 만든 토큰이 맞는지 검증만 하면 된다. ( RSA, HS256 )
|
||||
if(req.getMethod().equals("POST")) {
|
||||
System.out.println("POST 요청됨");
|
||||
String headerAuth = req.getHeader("Authorization");
|
||||
System.out.println(headerAuth);
|
||||
|
||||
if (headerAuth != null && headerAuth.equals("cos")) {
|
||||
filterChain.doFilter(req, res);
|
||||
} else {
|
||||
PrintWriter out = res.getWriter();
|
||||
out.println("인증 안됨");
|
||||
}
|
||||
} else {
|
||||
filterChain.doFilter(req, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.security.jwt.jwt;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
// 스프링 시큐리티 에서 UsernamePasswordAuthenticationFilter는
|
||||
// /login 요청해서 username, password를 전송하면 (post) 동작한다.
|
||||
@RequiredArgsConstructor
|
||||
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
|
||||
|
||||
private final AuthenticationManager authenticationManager;
|
||||
|
||||
// /login 요청을 하면 로그인 시도를 위해서 실행되는 함수
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||
throws AuthenticationException {
|
||||
System.out.println("JwtAuthenticationFilter : 로그인 시도중");
|
||||
|
||||
// 1. username, password 를 받는다.
|
||||
|
||||
// 2. 정상인지 로그인 시도를 한다.
|
||||
// authenticationManager 로 로그인 시도를 하면
|
||||
// -> PrincipalDetailsService가 호출
|
||||
// -> loadUserByUsername() 메소드 실행
|
||||
|
||||
// 3. PrincipalDetials 를 세션에 담고 (권한 관리를 위해서)
|
||||
|
||||
// 4. JWT토큰을 만들어서 응답
|
||||
return super.attemptAuthentication(request, response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.security.jwt.repository;
|
||||
|
||||
import com.security.jwt.model.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
User findByUsername(String username);
|
||||
}
|
||||
Reference in New Issue
Block a user