728x90
반응형
1. 서론
- 저번 포스팅에서는 로그인 성공 이후 처리에 대해 알아보았습니다.
이번에는 로그인 실패시, 알림창 띄우는 방법에 대해 알아보도록 하겠습니다.
2. 본론
SecurityConfig.java
package com.example.springsecurity.security;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
@Configuration
@EnableWebSecurity
@Slf4j
@AllArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final AuthenticationSuccessHandler customSuccessHandler;
private final AuthenticationFailureHandler customFailureHandler;
private final AuthenticationDetailsSource authenticationDetailsSource;
private final UserDetailsService userDetailsService;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
// String password = passwordEncoder().encode("1111");
//
// auth.inMemoryAuthentication().withUser("user").password(password).roles("USER");
// auth.inMemoryAuthentication().withUser("manager").password(password).roles("MANAGER");
// auth.inMemoryAuthentication().withUser("admin").password(password).roles("ADMIN");
// auth.userDetailsService(userDetailsService);
auth.authenticationProvider(authenticationProvider());
}
@Bean
public AuthenticationProvider authenticationProvider() {
return new CustomAuthenticationProvider();
}
@Override
// js, css, image 설정은 보안 설정의 영향 밖에 있도록 만들어주는 설정.
public void configure(WebSecurity web) throws Exception {
web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}
@Bean
// BCryptPasswordEncoder는 Spring Security에서 제공하는 비밀번호 암호화 객체입니다.
// Service에서 비밀번호를 암호화할 수 있도록 Bean으로 등록합니다.
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/","/loginUser","/login*").permitAll()
.antMatchers("/user").hasRole("USER")
.antMatchers("/manager").hasRole("MANAGER")
.antMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login") // controller mapping
.loginProcessingUrl("/login_proc") // th:action="@{/login_proc}"
.authenticationDetailsSource(authenticationDetailsSource) // 추가 파라메터 설정작업시, 설정해주기
.defaultSuccessUrl("/")
.successHandler(customSuccessHandler)
.failureHandler(customFailureHandler) // 실패 핸들러
.permitAll();
}
}
- 실패 핸들러를 적용해줍니다.
CustomAuthenticationFailureHandler.java
package com.example.springsecurity.security;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
String msg = "Invaild Username or Password";
if(exception instanceof BadCredentialsException){
}else if(exception instanceof InsufficientAuthenticationException){
msg = "Invalid Secret Key";
}
setDefaultFailureUrl("/login?error=true&exception="+msg);
super.onAuthenticationFailure(request,response,exception);
}
}
- 예외처리 진행해주고, 에러 메세지를 띄워줍니다.
loginController.java
@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 "user/login/login";
}
에러가 있다면, model에 반영하여 넘겨준다.
login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/header :: header"></head>
<body>
<div class="container">
<div th:replace="fragments/bodyHeader :: bodyHeader"></div>
<h1>로그인</h1>
<div th:if="${param.error}">
<p th:text="${exception}" class="alert alert-danger"></p>
</div>
<form th:action="@{/login_proc}" method="post">
<input th:type="hidden" th:value="secret" name="secret_key">
<div class="form-group">
<label th:for="username">이메일</label>
<input type="text" name="username" class="form-control" placeholder="이메일 입력해주세요">
</div>
<div class="form-group">
<label th:for="password">비밀번호</label>
<input type="password" class="form-control" name="password" placeholder="비밀번호">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<br/>
<div th:replace="fragments/footer :: footer"></div>
</div>
</body>
</html>
${param.error}가 있다면, 예외처리를 출력해줍니다.
3. 결론
위에서 본 내용처럼 유저 정보가 잘못 되었을 때, 커스터마이징 된 알람을 띄울 수 있게 되었습니다.
728x90
반응형
'Dev > SpringBoot' 카테고리의 다른 글
14. [Spring Boot] URL별 접근권한 DB에서 가져와서 처리하기(1) (3) | 2020.06.17 |
---|---|
13. [springboot] 스프링부트 접근 불가 처리 (0) | 2020.06.13 |
11. [springboot] 스프링부트 로그인 성공 이후 처리 (0) | 2020.06.12 |
10. [springboot] 스프링부트 간단한 로그인/로그아웃 예제 (1) | 2020.06.11 |
9. [springboot] 간단 커스텀 로그인 예제 (2) | 2020.06.11 |