로그인 실패시에 /로그인경로?error로 이동하고 아무런 에러표시가 발생하지않는다.
여러 로그인관련 오류를 표시해주겠다.
SecurityConfig 수정
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig{
private final AuthenticationFailureHandler CustomAuthFailureHandler;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http
.csrf().disable()
.cors().disable()
.exceptionHandling()
.accessDeniedHandler(new CustomAccessDeniedHandler())
.and()
.authorizeHttpRequests()
.antMatchers("/", "/auth/login", "/auth/signup", "/item/detail/**").permitAll()
.antMatchers("/item/item_reg").hasAuthority("SELLER")
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/", true).permitAll()
.loginPage("/auth/login")
.loginProcessingUrl("/login")
.usernameParameter("email")
.failureHandler(CustomAuthFailureHandler)
.and()
.logout()
.logoutSuccessUrl("/");
return http.build();
}
/**
*
* @return css, js 인증예외처리
*/
@Bean
public WebSecurityCustomizer customizer(){
return web -> web.ignoring().antMatchers("/css/**", "/js/**");
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
private final AuthenticationFailureHandler CustomAuthFailureHandler와
formLogin에 .failureHandler(CustomAuthFailureHandler)가 추가되었다.
CustomAuthFailureHandler 작성
@Component
public class CustomAuthFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
String message;
if(exception instanceof BadCredentialsException)
message = "비밀번호가 맞지않습니다.";
else if (exception instanceof InternalAuthenticationServiceException)
message = "관리자에게 문의하십시오";
else if (exception instanceof UsernameNotFoundException)
message = "계정이 존재하지 않습니다";
else if (exception instanceof AuthenticationCredentialsNotFoundException)
message = "인증이 거부되었습니다";
else
message = "알수없는 이유로 로그인에 실패하였습니다";
message = URLEncoder.encode(message, "UTF-8");
setDefaultFailureUrl("/auth/login?error=true&exception="+message);
super.onAuthenticationFailure(request, response, exception);
}
}
onAuthenticationFilure를 오버라이딩하여 작성한다.
한글 인코딩이 깨지는것을 방지하여 UTF-8로 인코딩해준다.
setDefaultFailureUrl은 에러가 발생했을시 이동할 URL을 설정해준다.
AuthController 수정
@Controller
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {
private final MemberService memberService;
@GetMapping("/login")
public String login(@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "exception", required = false) String exception,
Model model){
model.addAttribute("error", error);
model.addAttribute("exception", exception);
return "auth/login";
}
...
}
파라미터로 error과 exception을 받아주고 model에 담아 html로 보내준다.
login.html 추가
<span class="mt-3">
<div th:if="${error}">
<p id="valid" class="alert alert-danger" th:text="${exception}"></p>
</div>
</span>
타임리프를 이용해 출력해준다.
결과