티스토리 뷰
먼저, 로그인 페이지를 만들어줍니다.
컨트롤러에 로그인 페이지를 생성해주세요.
// Controller
@RequestMapping("/login")
public String login() throws Exception {
return "login";
}
연결된 로그인 html파일에는 다음과 같이 "username"과 "password"가 있어야 합니다.
method는 무조건 post여야하구요!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
</head>
<body>
<h2>Login</h2>
<form action="/login" method="post">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<label for="username">Username:</label>
<input type="text" id="username" name="username" required><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required><br>
<!-- input fields for username and password -->
<button type="submit">Login</button>
</form>
</body>
</html>
이제 로그인페이지를 통해 로그인한 사용자의 ID를 토대로 DB에서 사용자권한정보를 가져와야합니다.
이 부분은 spring security를 이용합니다.
spring security를 pom.xml에 추가해줍니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
그리고 DB 사용자정보 테이블에서 사용자ID를 토대로 사용자정보를 가져오는 UserService를 만들어놓습니다.
사용자가 로그인페이지에서 로그인 시, 로그인한 USER_ID를 토대로 권한을 가져오는 서비스입니다.
// ID -> 사용자정보 조회
public List<UserDTO> getUserInfo(String USER_ID)throws Exception {
return UserDAO.getUserInfo(USER_ID);
}
이제 사용자가 로그인 시, 사용자권한정보를 가져오는 UserDetailsService를 만듭니다.
사용자가 로그인버튼을 누르면 loadUserByUsername이 실행됩니다.
저는 비밀번호없이 로그인하게끔 만들어놓았기에 비밀번호는 "1111"로 고정해놓았습니다.
userDetails = builder.username(userInfo.get(0).getUser_id()) <- 이부분에서 사용자권한정보를 가져오면 됩니다.
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import dto.UserDTO;
import service.UserService;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails userDetails = null;
System.out.println(username);
List<UserDTO> userInfo;
try {
userInfo = userService.getUserInfo(username);
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
org.springframework.security.core.userdetails.User.UserBuilder builder =
org.springframework.security.core.userdetails.User.builder().passwordEncoder(encoder::encode);
if (userInfo.size() > 0) {
userDetails = builder.username(userInfo.get(0).getUser_id())
.password("1111") // 비밀번호 없음
.roles(userInfo.get(0).getAuth())
.build();
}else {
// 계정정보가 없는 경우
throw new UsernameNotFoundException("User not found with username: " + username);
}
} catch (Exception e) {
System.out.println(e);
throw new UsernameNotFoundException("Exception occurred while loading user by username", e);
}
return userDetails;
}
}
마지막으로 spring security의 configuration을 만들어줍니다.
CORS설정 이라고 주석처리되어있는 부분을 삽입하지 않으면 로그인버튼을 눌러도 302에러가 뜨면서 계속 GET으로만 요청이 들어오더라구요. CORS 설정을 꼭 넣어주세요.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
import javax.sql.DataSource;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
//CORS 설정
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedOrigins(Arrays.asList("http://localhost:80"));
config.setAllowedMethods(Arrays.asList("HEAD","POST","GET","DELETE","PUT"));
config.setAllowedHeaders(Arrays.asList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.cors().configurationSource(corsConfigurationSource())
.and()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.defaultSuccessUrl("/", true) // 로그인 성공 시 "/"로 리다이렉트
.and()
.logout()
.permitAll();
http.csrf().disable();
http.headers().frameOptions().disable();
}
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
이제 로그인페이지에서 로그인 버튼을 누르면, UserDetailsServiceImpl에서 출력해놓았던
System.out.println(username); <- 요부분이 콘솔창에 출력되고, 사용자권한별로 페이지접속이 가능해집니다.
이제 권한별 페이지접속 설정을 해봅니다.
SecurityConfig파일에서 페이지 접속을 설정하는 부분입니다.
권한별 URL을 설정해주면 됩니다.
.antMatchers("/login", "/css/**", "/js/**", "/font/**", "/images/**").permitAll() // "/" 및 스태틱자원들의 경로는 모두에게 허용
.antMatchers("/manage/**").hasRole("ADMIN") // ADMIN 권한 필요
.anyRequest().authenticated() // 그 외의 리소스는 인증된 사용자만 허용
- 컨트롤러에서 사용자ID, 권한정보 가져오는 방법
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// 사용자 ID
String USER_ID = authentication.getName();
// 권한정보
String Authority = authentication.getAuthorities();
로그아웃기능에 대해서는 아래 링크를 눌러주세요
[java] spring security 로그아웃기능 만들기 (+자동로그아웃)
https://domdom.tistory.com/660
'프로그래밍 > Java' 카테고리의 다른 글
[spring boot] WAS를 JBoss(wildfly) 사용한 개발환경 만들기-1 (21) | 2023.12.02 |
---|---|
[java] spring security 로그아웃기능 만들기 (+자동로그아웃) (15) | 2023.12.01 |
[springboot] DTO에 추가된 필드 중 null값인 필드는 보이지않게 하는 방법 (2) | 2023.11.13 |
[java] mybatis 사용된 쿼리 및 가져온 데이터 출력 조회 (0) | 2023.09.20 |
Geoserver GIS서비스 개발방법 1 (postgre + geoserver + openlayers) (0) | 2023.08.16 |