로그인 기능 작업중.
parent
40318e86ef
commit
8738a08189
|
|
@ -62,7 +62,7 @@ function EgovLoginContent(props) {
|
|||
const submitFormHandler = (e) => {
|
||||
console.log("EgovLoginContent submitFormHandler()");
|
||||
|
||||
const loginUrl = "/auth/login"
|
||||
const loginUrl = "/login"
|
||||
const requestOptions = {
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
|
|
|||
|
|
@ -101,30 +101,4 @@ public class EgovLoginApiController extends BaseController {
|
|||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 로그아웃한다.
|
||||
* @return resultVO
|
||||
* @exception Exception
|
||||
*/
|
||||
@Operation(
|
||||
summary = "로그아웃",
|
||||
description = "로그아웃 처리(JWT,일반 관계 없이)",
|
||||
tags = {"EgovLoginApiController"}
|
||||
)
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(responseCode = "200", description = "로그아웃 성공"),
|
||||
})
|
||||
@GetMapping(value = "/logout")
|
||||
public ResultVO actionLogoutJSON(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
ResultVO resultVO = new ResultVO();
|
||||
|
||||
new SecurityContextLogoutHandler().logout(request, response, null);
|
||||
|
||||
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
|
||||
resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());
|
||||
|
||||
return resultVO;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package com.dbnt.kcscbackend.config.security;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Slf4j
|
||||
public class JsonUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
|
||||
|
||||
private static final String DEFAULT_LOGIN_REQUEST_URL = "/login"; // /login/oauth2/ + ????? 로 오는 요청을 처리할 것이다
|
||||
private static final String HTTP_METHOD = "POST"; //HTTP 메서드의 방식은 POST 이다.
|
||||
private static final String CONTENT_TYPE = "application/json";//json 타입의 데이터로만 로그인을 진행한다.
|
||||
private static final AntPathRequestMatcher DEFAULT_LOGIN_PATH_REQUEST_MATCHER =
|
||||
new AntPathRequestMatcher(DEFAULT_LOGIN_REQUEST_URL, HTTP_METHOD); //=> /login 의 요청에, POST로 온 요청에 매칭된다.
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public JsonUsernamePasswordAuthenticationFilter(ObjectMapper objectMapper,
|
||||
AuthenticationSuccessHandler authenticationSuccessHandler, // 로그인 성공 시 처리할 핸들러
|
||||
AuthenticationFailureHandler authenticationFailureHandler // 로그인 실패 시 처리할 핸들러
|
||||
) {
|
||||
|
||||
super(DEFAULT_LOGIN_PATH_REQUEST_MATCHER); // 위에서 설정한 /oauth2/login/* 의 요청에, GET으로 온 요청을 처리하기 위해 설정한다.
|
||||
|
||||
this.objectMapper = objectMapper;
|
||||
setAuthenticationSuccessHandler(authenticationSuccessHandler);
|
||||
setAuthenticationFailureHandler(authenticationFailureHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
|
||||
|
||||
if (request.getContentType() == null || !request.getContentType().equals(CONTENT_TYPE)) {
|
||||
throw new AuthenticationServiceException("Authentication Content-Type not supported: " + request.getContentType());
|
||||
}
|
||||
|
||||
LoginDto loginDto = objectMapper.readValue(StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8), LoginDto.class);
|
||||
|
||||
String username = loginDto.getUsername();
|
||||
String password = loginDto.getPassword();
|
||||
|
||||
if (username == null || password == null) {
|
||||
throw new AuthenticationServiceException("DATA IS MISS");
|
||||
}
|
||||
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
|
||||
// Allow subclasses to set the "details" property
|
||||
setDetails(request, authRequest);
|
||||
return this.getAuthenticationManager().authenticate(authRequest);
|
||||
}
|
||||
|
||||
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
|
||||
authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class LoginDto {
|
||||
String username;
|
||||
String password;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,27 @@
|
|||
package com.dbnt.kcscbackend.config.security;
|
||||
|
||||
import com.dbnt.kcscbackend.auth.entity.UserInfo;
|
||||
import com.dbnt.kcscbackend.auth.service.EgovLoginService;
|
||||
import com.dbnt.kcscbackend.config.jwt.EgovJwtTokenUtil;
|
||||
import com.dbnt.kcscbackend.config.jwt.JwtAuthenticationEntryPoint;
|
||||
import com.dbnt.kcscbackend.config.jwt.JwtAuthenticationFilter;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.ProviderManager;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
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.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
|
||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
|
|
@ -24,6 +34,7 @@ import org.springframework.web.cors.CorsConfiguration;
|
|||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
|
@ -39,10 +50,14 @@ import java.util.Arrays;
|
|||
*/
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@RequiredArgsConstructor
|
||||
public class SecurityConfig {
|
||||
|
||||
@Autowired
|
||||
private EgovJwtTokenUtil jwtTokenUtil;
|
||||
@Resource(name = "loginService")
|
||||
private UserDetailsService loginService;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
//Http Methpd : Get 인증예외 List
|
||||
private String[] AUTH_GET_WHITELIST = {
|
||||
|
|
@ -55,6 +70,7 @@ public class SecurityConfig {
|
|||
private String[] AUTH_WHITELIST = {
|
||||
"/",
|
||||
"/login/**",
|
||||
"/login",
|
||||
"/auth/login-jwt",//JWT 로그인
|
||||
"/auth/login",//일반 로그인
|
||||
"/auth/join",//회원가입
|
||||
|
|
@ -107,22 +123,26 @@ public class SecurityConfig {
|
|||
.antMatchers(AUTH_WHITELIST).permitAll()
|
||||
.antMatchers(HttpMethod.GET,AUTH_GET_WHITELIST).permitAll()
|
||||
.anyRequest().authenticated()
|
||||
).sessionManagement((sessionManagement) ->
|
||||
);
|
||||
http.sessionManagement((sessionManagement) ->
|
||||
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
)
|
||||
.cors().and()
|
||||
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)
|
||||
);
|
||||
|
||||
http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)
|
||||
.exceptionHandling(exceptionHandlingConfigurer ->
|
||||
exceptionHandlingConfigurer
|
||||
.authenticationEntryPoint(new JwtAuthenticationEntryPoint())
|
||||
)
|
||||
.cors().and()
|
||||
.formLogin().loginProcessingUrl("/auth/login")
|
||||
.successHandler(loginSuccessHandler())
|
||||
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
|
||||
.logoutSuccessUrl("/")
|
||||
.invalidateHttpSession(true)
|
||||
.deleteCookies("JSESSIONID");
|
||||
);
|
||||
|
||||
http.httpBasic().disable()
|
||||
.csrf().disable()
|
||||
.formLogin().disable();
|
||||
|
||||
// http.authorizeHttpRequests()
|
||||
// .requestMatchers(new AntPathRequestMatcher("/auth/login")).permitAll()
|
||||
// .anyRequest().authenticated();
|
||||
|
||||
http.cors().and().addFilterBefore(jsonUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
|
@ -138,5 +158,33 @@ public class SecurityConfig {
|
|||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationFailureHandler loginFailureHandler(){
|
||||
return (request, response, exception) -> {
|
||||
new DefaultRedirectStrategy().sendRedirect(request, response, "/login-error");
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JsonUsernamePasswordAuthenticationFilter jsonUsernamePasswordAuthenticationFilter() {
|
||||
JsonUsernamePasswordAuthenticationFilter jsonUsernamePasswordAuthenticationFilter = new JsonUsernamePasswordAuthenticationFilter(objectMapper, loginSuccessHandler(), loginFailureHandler());
|
||||
jsonUsernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManager());
|
||||
return jsonUsernamePasswordAuthenticationFilter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager() {
|
||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||
|
||||
provider.setPasswordEncoder(passwordEncoder());
|
||||
provider.setUserDetailsService(loginService);
|
||||
|
||||
return new ProviderManager(provider);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new Pbkdf2PasswordEncoder();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,4 +5,4 @@ Globals.pageUnit=10
|
|||
Globals.pageSize=10
|
||||
|
||||
#JWT secret key
|
||||
Globals.jwt.secret = egovframe
|
||||
Globals.jwt.secret = qWwMroux3QtiIJcPSIZARNTZEBBnWVH0jZ2Lx7tfFChCYi0ViZllo1bekZdiU0B3FRjJI7g90n0ha120dwlz8JZU8rOkmNCe9Uq0
|
||||
|
|
|
|||
Loading…
Reference in New Issue