Top 36 스프링 시큐리티 로그인 구현 The 158 Latest Answer

You are looking for information, articles, knowledge about the topic nail salons open on sunday near me 스프링 시큐리티 로그인 구현 on Google, you do not find the information you need! Here are the best content compiled and compiled by the https://chewathai27.com/to team, along with other related topics such as: 스프링 시큐리티 로그인 구현 스프링부트 시큐리티 로그인 예제, 스프링 시큐리티 깃 허브 로그인, spring security 회원가입, Spring boot security mybatis login, Spring boot Security 예제, Vue 스프링 시큐리티 로그인, 스프링 시큐리티 로그인 페이지 없애기, 스프링부트 시큐리티 로그인 세션


Spring Boot으로 웹 출시까지 #9. Spring Security를 이용한 로그인 처리
Spring Boot으로 웹 출시까지 #9. Spring Security를 이용한 로그인 처리


Spring Security 회원가입 / 로그인 구현 – Javabom

  • Article author: blog.javabom.com
  • Reviews from users: 48078 ⭐ Ratings
  • Top rated: 4.2 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about Spring Security 회원가입 / 로그인 구현 – Javabom Spring Security 회원가입 / 로그인 구현. 스프링 부트 환경에서 BCryptPasswordEncoder를 이용한 회원가입 암호화 / Spring Security를 이용한 로그인 구현 … …
  • Most searched keywords: Whether you are looking for Spring Security 회원가입 / 로그인 구현 – Javabom Spring Security 회원가입 / 로그인 구현. 스프링 부트 환경에서 BCryptPasswordEncoder를 이용한 회원가입 암호화 / Spring Security를 이용한 로그인 구현 …
  • Table of Contents:
Spring Security 회원가입 / 로그인 구현 - Javabom
Spring Security 회원가입 / 로그인 구현 – Javabom

Read More

Spring Boot spring security 로 로그인을 구현하자!

  • Article author: velog.io
  • Reviews from users: 1069 ⭐ Ratings
  • Top rated: 3.8 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about Spring Boot spring security 로 로그인을 구현하자! 시작 전 확인사항. gradle 추가. springsecurity 를 이용할 것이다. //스프링 시큐리티 관련 implementation ‘org.springframework … …
  • Most searched keywords: Whether you are looking for Spring Boot spring security 로 로그인을 구현하자! 시작 전 확인사항. gradle 추가. springsecurity 를 이용할 것이다. //스프링 시큐리티 관련 implementation ‘org.springframework … IntelliJ : 2020.3.2.communityspring boot : 2.6.1springsecurity 를 이용할 것이다.이 전 글에서 회원가입에 대해서 구현해 놓았다.로그인을 하려면 계정 가입된 데이터가 있어야 한다.📌 Spring Boot 회원가입 구현
  • Table of Contents:

SpringBoot

!!!이번 글에서는 회원가입 + 로그인까지 구현이 되어있다!!

Spring Boot spring security 로 로그인을 구현하자!
Spring Boot spring security 로 로그인을 구현하자!

Read More

Spring Boot | 로그인 구현하기 (Spring Security)

  • Article author: kitty-geno.tistory.com
  • Reviews from users: 30461 ⭐ Ratings
  • Top rated: 4.7 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about Spring Boot | 로그인 구현하기 (Spring Security) 이번 장에서는 스프링 시큐리티(Spring Security)를 이용한 로그인 처리, 로그아웃, 중복 로그인 처리, 로그인 정보 유지, 예외처리 등을 적용해본다. …
  • Most searched keywords: Whether you are looking for Spring Boot | 로그인 구현하기 (Spring Security) 이번 장에서는 스프링 시큐리티(Spring Security)를 이용한 로그인 처리, 로그아웃, 중복 로그인 처리, 로그인 정보 유지, 예외처리 등을 적용해본다. [스프링 부트 (Spring Boot)/게시판 만들기] – 1 | 스프링 부트 프로젝트 만들기 위의 과정을 통해 생성된 프로젝트입니다. 구성환경 SpringBoot, Gradle, Thymeleaf, Jpa(JPQL), Jar, MariaDB 이번 장에서는 스프..
  • Table of Contents:
[스프링 부트 (Spring Boot)게시판 만들기] – 1 스프링 부트 프로젝트 만들기

구성환경

buildgradle

로그인 HTML

엔티티(Entity)

컨트롤러(Controller)

서비스(Service)

리포지토리(Repository)

로그인 성공 핸들러

로그인 실패 핸들러

스프링 시큐리티 적용 WebSecurity

테스트

+ 사용자 인증 객체 가져오기

GitHub

태그

관련글

댓글6

공지사항

최근글

인기글

최근댓글

태그

전체 방문자

티스토리툴바

Spring Boot | 로그인 구현하기 (Spring Security)
Spring Boot | 로그인 구현하기 (Spring Security)

Read More

Spring Security 로그인 구현하기

  • Article author: developerbee.tistory.com
  • Reviews from users: 2352 ⭐ Ratings
  • Top rated: 4.2 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about Spring Security 로그인 구현하기 Spring Security 로그인 구현하기 · 로그인: /auth/login · 회원가입: /auth/signup · 대시보드: /dashboard (로그인한 사용자만 접근이 가능) · 관리자: / … …
  • Most searched keywords: Whether you are looking for Spring Security 로그인 구현하기 Spring Security 로그인 구현하기 · 로그인: /auth/login · 회원가입: /auth/signup · 대시보드: /dashboard (로그인한 사용자만 접근이 가능) · 관리자: / … Spring Security를 사용하여 로그인과 회원가입 기능을 구현하는 방법을 알아보겠습니다. 간단하게 Spring Security를 적용한 프로젝트는 다음 깃 레포지토리를 통해 확인할 수 있습니다. 해당 프로젝트는 현재 설..
  • Table of Contents:

티스토리 뷰

티스토리툴바

Spring Security 로그인 구현하기
Spring Security 로그인 구현하기

Read More

3-07 로그인과 로그아웃 – 점프 투 스프링부트

  • Article author: wikidocs.net
  • Reviews from users: 7496 ⭐ Ratings
  • Top rated: 3.8 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 3-07 로그인과 로그아웃 – 점프 투 스프링부트 SITE_USER 테이블에 저장된 사용자명(사용자 ID)과 비밀번호로 로그인을 하려면 복잡한 단계를 거쳐야 한다. 하지만 스프링 시큐리티를 사용 … …
  • Most searched keywords: Whether you are looking for 3-07 로그인과 로그아웃 – 점프 투 스프링부트 SITE_USER 테이블에 저장된 사용자명(사용자 ID)과 비밀번호로 로그인을 하려면 복잡한 단계를 거쳐야 한다. 하지만 스프링 시큐리티를 사용 … 온라인 책을 제작 공유하는 플랫폼 서비스
  • Table of Contents:

로그인 구현하기

로그아웃 구현하기

3-07 로그인과 로그아웃 - 점프 투 스프링부트
3-07 로그인과 로그아웃 – 점프 투 스프링부트

Read More

[Spring Security] 스프링 시큐리티 로그인, 회원가입 예제 – HoeStory

  • Article author: hoestory.tistory.com
  • Reviews from users: 22979 ⭐ Ratings
  • Top rated: 4.7 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about [Spring Security] 스프링 시큐리티 로그인, 회원가입 예제 – HoeStory [Spring Security] 스프링 시큐리티 로그인, 회원가입 예제. JeongHoeWoon 2022. 2. 11. 02:26. 스프링 시큐리티로 로그인과 회원가입을 하는 방법에 대해 알아 … …
  • Most searched keywords: Whether you are looking for [Spring Security] 스프링 시큐리티 로그인, 회원가입 예제 – HoeStory [Spring Security] 스프링 시큐리티 로그인, 회원가입 예제. JeongHoeWoon 2022. 2. 11. 02:26. 스프링 시큐리티로 로그인과 회원가입을 하는 방법에 대해 알아 … 스프링 시큐리티로 로그인과 회원가입을 하는 방법에 대해 알아보겠습니다. 먼저 시큐리티 의존성을 추가해줘야 됩니다. ※ bulid.gradle implementation ‘org.springframework.boot:spring-boot-starter-security..
  • Table of Contents:
[Spring Security] 스프링 시큐리티 로그인, 회원가입 예제 - HoeStory
[Spring Security] 스프링 시큐리티 로그인, 회원가입 예제 – HoeStory

Read More

Spring Security 로그인 구현 (part 1) – form login

  • Article author: wordbe.tistory.com
  • Reviews from users: 36961 ⭐ Ratings
  • Top rated: 3.6 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about Spring Security 로그인 구현 (part 1) – form login Spring Security 로그인 구현 (part 1) – form login. 많은 서비스에서는 특정 사용자별로 할 수 있는 일이 다릅니다. …
  • Most searched keywords: Whether you are looking for Spring Security 로그인 구현 (part 1) – form login Spring Security 로그인 구현 (part 1) – form login. 많은 서비스에서는 특정 사용자별로 할 수 있는 일이 다릅니다. Spring Security 로그인 구현 (part 1) – form login 많은 서비스에서는 특정 사용자별로 할 수 있는 일이 다릅니다. 예를 들어, 네이버 밴드의 멤버탭을 들어가면 Admin , Co-Admin 권한을 특정 사람에게 부여할..
  • Table of Contents:

회원가입 페이지 구성

Spring Security 구성

태그

관련글

댓글0

최근글

인기글

최근댓글

태그

전체 방문자

티스토리툴바

Spring Security  로그인 구현 (part 1) - form login
Spring Security 로그인 구현 (part 1) – form login

Read More

삽질중인 개발자 :: 스프링 시큐리티 DB를 이용한 로그인 구현 1 ( 회원 설정 및 일반 로그인 ) – 삽질중인 개발자

  • Article author: programmer93.tistory.com
  • Reviews from users: 724 ⭐ Ratings
  • Top rated: 4.1 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 삽질중인 개발자 :: 스프링 시큐리티 DB를 이용한 로그인 구현 1 ( 회원 설정 및 일반 로그인 ) – 삽질중인 개발자 spring security 로그인 (mariaDB) -. 스프링 시큐리티. 스프링 기반의 보안 관련 프레임워크이다. 스프링 시큐리티를 사용하면 보안에 관련된 옵션을 … …
  • Most searched keywords: Whether you are looking for 삽질중인 개발자 :: 스프링 시큐리티 DB를 이용한 로그인 구현 1 ( 회원 설정 및 일반 로그인 ) – 삽질중인 개발자 spring security 로그인 (mariaDB) -. 스프링 시큐리티. 스프링 기반의 보안 관련 프레임워크이다. 스프링 시큐리티를 사용하면 보안에 관련된 옵션을 … – spring security 로그인 (mariaDB) – 스프링 시큐리티 스프링 기반의 보안 관련 프레임워크이다. 스프링 시큐리티를 사용하면 보안에 관련된 옵션을 자동적으로 구현해주기에 우리가 어느정도 신경을 안써도 된..java, javascript, js,spring, spring boot, html, plugin, 자바, 자바스크립트, 스프링, 스프링 부트, 플러그인, 사용법, 예제, oracle, 오라클, sql신입 개발자의 개발 노트, 개발 노하우
  • Table of Contents:

네비게이션

스프링 시큐리티 DB를 이용한 로그인 구현 1 ( 회원 설정 및 일반 로그인 ) – 삽질중인 개발자

사이드바

검색

삽질중인 개발자 :: 스프링 시큐리티 DB를 이용한 로그인 구현 1 ( 회원 설정 및 일반 로그인 ) - 삽질중인 개발자
삽질중인 개발자 :: 스프링 시큐리티 DB를 이용한 로그인 구현 1 ( 회원 설정 및 일반 로그인 ) – 삽질중인 개발자

Read More

[Spring Security]로그인/회원가입 페이지 구현해보기

  • Article author: imgzon.tistory.com
  • Reviews from users: 708 ⭐ Ratings
  • Top rated: 4.6 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about [Spring Security]로그인/회원가입 페이지 구현해보기 이 모든 로직을 직접 구현하기 위해서는 많을 노력과 시간이 필요하지만, Spring Security를 활용하고 해당 프레임워크의 메커니즘을 지킨다면 비교적 … …
  • Most searched keywords: Whether you are looking for [Spring Security]로그인/회원가입 페이지 구현해보기 이 모든 로직을 직접 구현하기 위해서는 많을 노력과 시간이 필요하지만, Spring Security를 활용하고 해당 프레임워크의 메커니즘을 지킨다면 비교적 …  이번 게시물에서는 Spring Security 공부 차원에서 이를 활용하여 로그인 페이지, 회원가입 페이지가 있는 소규모 프로젝트를 만들어 볼 것이다.  전체 코드는 Github에서 확인해 볼 수 있다.  해당 게시물은..
  • Table of Contents:

2 Spring Security가 제공하는 기능

3 페이지 설계

4 의존성 추가

로그인 구현

회원가입 구현

로그아웃 구현

나머지 구현

후기

태그

댓글0

공지사항

최근글

인기글

최근댓글

전체 방문자

[Spring Security]로그인/회원가입 페이지 구현해보기
[Spring Security]로그인/회원가입 페이지 구현해보기

Read More

Spring Security를 이용한 회원 로그인 구현과 동작 원리 정리 (+SecurityFilterChain 기능 정리 )

  • Article author: sjparkk-dev1og.tistory.com
  • Reviews from users: 16052 ⭐ Ratings
  • Top rated: 4.1 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about Spring Security를 이용한 회원 로그인 구현과 동작 원리 정리 (+SecurityFilterChain 기능 정리 ) 로그인에 관한 흐름을 알아보기 전에 아직 인증이 되지 않은 상황에서의 요청에 대해서 먼저 알고가자. 스프링시큐리티를 이용하게 되면 모든 요청은 … …
  • Most searched keywords: Whether you are looking for Spring Security를 이용한 회원 로그인 구현과 동작 원리 정리 (+SecurityFilterChain 기능 정리 ) 로그인에 관한 흐름을 알아보기 전에 아직 인증이 되지 않은 상황에서의 요청에 대해서 먼저 알고가자. 스프링시큐리티를 이용하게 되면 모든 요청은 … 들어가며 어드민 페이지를 만들때 권한에 따라서 볼 수 있는 페이지와 볼 수 없는 페이지 또는 동작 등을 관리할 수 있다. 그렇기 때문에 현재 만들고 있는 어드민 페이지에 Spring Security를 이용하여 해당 기능..
  • Table of Contents:

관련글

댓글0

공지사항

최근글

인기글

최근댓글

태그

전체 방문자

티스토리툴바

Spring Security를 이용한 회원 로그인 구현과 동작 원리 정리 (+SecurityFilterChain 기능 정리 )
Spring Security를 이용한 회원 로그인 구현과 동작 원리 정리 (+SecurityFilterChain 기능 정리 )

Read More


See more articles in the same category here: 316+ tips for you.

Spring Boot spring security 로 로그인을 구현하자!

1. Version

💬

IntelliJ : 2020.3.2.community

spring boot : 2.6.1

2. 시작 전 확인사항

💬 gradle 추가

springsecurity 를 이용할 것이다.

implementation ‘org.springframework.boot:spring-boot-starter-security’ implementation ‘org.thymeleaf.extras:thymeleaf-extras-springsecurity5’

💬 사용할 DB 구축

💬 회원가입 내용

이 전 글에서 회원가입에 대해서 구현해 놓았다.

로그인을 하려면 계정 가입된 데이터가 있어야 한다.

📌 Spring Boot 회원가입 구현 해보자!

3. User Table 생성

💻 Create Table sql

CREATE TABLE ` TB_USER ` ( ` USER_NO ` int ( 11 ) NOT NULL AUTO_INCREMENT COMMENT ‘사용자번호’ , ` USER_ID ` varchar ( 255 ) NOT NULL COMMENT ‘아이디’ , ` USER_PW ` varchar ( 256 ) DEFAULT NULL COMMENT ‘비밀번호’ , ` USER_NAME ` varchar ( 255 ) NOT NULL COMMENT ‘사용자명’ , ` USER_AUTH ` varchar ( 255 ) NOT NULL COMMENT ‘권한’ , ` APPEND_DATE ` datetime DEFAULT NULL COMMENT ‘추가날짜’ , ` UPDATE_DATE ` datetime DEFAULT NULL COMMENT ‘수정날짜’ , PRIMARY KEY ( ` USER_NO ` ) ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8 ;

4. application.yml 설정

💬 application.yml 경로

src/main/resources/application.yml

💬 application.yml 내용

spring : datasource : url : “jdbc:mariadb://127.0.0.1:3306/simpleBoard” username : “karim” password : “karim” driver-class-name : “org.mariadb.jdbc.Driver” mybatis : mapper-locations : query/**/*.xml configuration : map-underscore-to-camel-case : true

5. 로그인 및 Html 페이지 생성

💬 html 페이지 경로

src/main/resources/templates/…html

💻 로그인 html 페이지 구현

login.html

< link rel = " stylesheet " href = " https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css " > < html xmlns: th = " http://www.thymeleaf.org " lang = " en " > < head > < meta charset = " UTF-8 " > < body > < div class = " container " > < h1 > 로그인 < form th: action = " @{/login_proc} " method = " post " > < div class = " form-group " > < label th: for = " username " > 아이디 < input type = " text " name = " username " class = " form-control " placeholder = " 아이디 입력해주세요 " > < div class = " form-group " > < label th: for = " password " > 비밀번호 < input type = " password " class = " form-control " name = " password " placeholder = " 비밀번호 입력해주세요 " > < button type = " submit " class = " btn btn-primary " > 로그인 < button type = " button " class = " btn btn-primary " onClick = " location.href='signUp' " > 회원 가입 < br />

💻 로그인 성공 후 html 페이지 구현

user_access.html

< html xmlns: th = " http://www.thymeleaf.org " lang = " en " > < head > < meta charset = " UTF-8 " > < title > user access < body > < h1 > !!!환영합니다!!! < div th: text = " ${info} " >

💻 로그인 실패 후 html 페이지 구현

asset_denied.html

< html xmlns: th = " http://www.thymeleaf.org " lang = " en " > < head > < meta charset = " UTF-8 " > < title > access denied < body > < h2 > !!!아이디 또는 비밀번호가 틀렸습니다!!!

!!!이번 글에서는 회원가입 + 로그인까지 구현이 되어있다!!

5. SecurityConfig 구현

💻 SecurityConfig 구현

페이지 권한을 위한 SecurityConfig를 구현한다. .antMatchers()

: 페이지에 접근할 수 있는 권한을 설정한다. .loginPage

: 로그인 페이지 .loginProcessingUrl

: 구현한 로그인 페이지 defaultSuccessUrl

: 로그인 성공 시 제공할 페이지 failureUrl

: 로그인 실패 시 제공할 페이지 csrf().disable()

: 사이트 간 요청 위조(Cross-Site Request Forgery) 공격 방지 기능 키기

package com . karim . simpleBoard . configuration ; import com . karim . simpleBoard . service . UserService ; import lombok . RequiredArgsConstructor ; 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 . bcrypt . BCryptPasswordEncoder ; @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfig extends WebSecurityConfigurerAdapter { private final UserService userService ; @Override protected void configure ( HttpSecurity http ) throws Exception { http . authorizeRequests ( ) . antMatchers ( “/login” , “/singUp” , “/access_denied” , “/resources/**” ) . permitAll ( ) / / USER , ADMIN 접근 허용 . antMatchers ( “/userAccess” ) . hasRole ( “USER” ) . antMatchers ( “/userAccess” ) . hasRole ( “ADMIN” ) . and ( ) . formLogin ( ) . loginPage ( “/login” ) . loginProcessingUrl ( “/login_proc” ) . defaultSuccessUrl ( “/user_access” ) . failureUrl ( “/access_denied” ) / / 인증에 실패했을 때 보여주는 화면 url , 로그인 form으로 파라미터값 error = true 로 보낸다 . . and ( ) . csrf ( ) . disable ( ) ; / / 로그인 창 } @Override public void configure ( AuthenticationManagerBuilder auth ) throws Exception { auth . userDetailsService ( userService ) . passwordEncoder ( new BCryptPasswordEncoder ( ) ) ; } }

6. User 객체 Vo 구현

💻 User 객체 Vo 구현

로그인 시 가져올 유저 정보 객체를 만든다. spring security의 인터페이스 UserDetails 를 상속 받는다.

package com . karim . simpleBoard . vo ; import lombok . Data ; import org . springframework . security . core . GrantedAuthority ; import org . springframework . security . core . authority . SimpleGrantedAuthority ; import org . springframework . security . core . userdetails . UserDetails ; import java . util . Collection ; import java . util . Collections ; @Data public class UserVo implements UserDetails { private int userNo ; private String userId ; private String userPw ; private String userName ; private String userAuth ; private String appendDate ; private String updateDate ; @Override public Collection < ? extends GrantedAuthority > getAuthorities ( ) { return Collections . singletonList ( new SimpleGrantedAuthority ( this . userAuth ) ) ; } @Override public String getPassword ( ) { return this . userPw ; } @Override public String getUsername ( ) { return this . userId ; } public String getUserName ( ) { return this . userName ; } @Override public boolean isAccountNonExpired ( ) { return true ; } @Override public boolean isAccountNonLocked ( ) { return true ; } @Override public boolean isCredentialsNonExpired ( ) { return true ; } @Override public boolean isEnabled ( ) { return true ; } }

💬 어노테이션 설명

@Data

@Getter, @Setter, @RequiredArgsConstructor, @ToString, @EqualsAndHashCode 어노테이션을 한꺼번에 설정해주는 어노테이션

7. Mapper 인터페이스 및 Xml 구현

💻 Mapper 인터페이스 구현

유저 정보를 DB에 가져오기 위한 Mapper 인터페이스 구현한다.

@Mapper public interface UserMapper { UserVo getUserAccount ( String userId ) ; void saveUser ( UserVo userVo ) ; }

💬 sql xml 구현

< mapper namespace = " com.karim.simpleBoard.mapper.UserMapper " > < select id = " getUserAccount " resultType = " com.karim.simpleBoard.vo.UserVo " > SELECT * FROM TB_USER WHERE USER_ID= #{userId} < insert id = " saveUser " parameterType = " com.karim.simpleBoard.vo.UserVo " > INSERT INTO TB_USER (USER_ID, USER_PW, USER_NAME, USER_AUTH, APPEND_DATE, UPDATE_DATE) VALUES(#{userId},#{userPw},#{userName},#{userAuth},#{appendDate},#{updateDate});

💬 xml 설명

id

@Mapper에서 정의한 이름을 동일하게 맞춰줘야 한다.

@Mapper에서 정의한 이름을 동일하게 맞춰줘야 한다. resultType

리턴타입의 자료형을 넣어준다.

8. Service 구현

💻 Service 구현

DAO를 호출하는 Service를 구현한다.

package com . karim . simpleBoard . service ; import com . karim . simpleBoard . mapper . UserMapper ; import com . karim . simpleBoard . vo . UserVo ; import lombok . RequiredArgsConstructor ; import org . springframework . security . core . userdetails . UserDetailsService ; import org . springframework . security . core . userdetails . UsernameNotFoundException ; import org . springframework . security . crypto . bcrypt . BCryptPasswordEncoder ; import org . springframework . stereotype . Service ; import org . springframework . transaction . annotation . Transactional ; import java . text . SimpleDateFormat ; import java . util . Date ; @Service @RequiredArgsConstructor public class UserService implements UserDetailsService { SimpleDateFormat format = new SimpleDateFormat ( “yyyy-MM-dd HH:mm:sss” ) ; Date time = new Date ( ) ; String localTime = format . format ( time ) ; private final UserMapper userMapper ; @Transactional public void joinUser ( UserVo userVo ) { BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder ( ) ; userVo . setUserPw ( passwordEncoder . encode ( userVo . getPassword ( ) ) ) ; userVo . setUserAuth ( “USER” ) ; userVo . setAppendDate ( localTime ) ; userVo . setUpdateDate ( localTime ) ; userMapper . saveUser ( userVo ) ; } @Override public UserVo loadUserByUsername ( String userId ) throws UsernameNotFoundException { UserVo userVo = userMapper . getUserAccount ( userId ) ; if ( userVo == null ) { throw new UsernameNotFoundException ( “User not authorized.” ) ; } return userVo ; } }

💬 어노테이션 설명

@RequiredArgsConstructor

생성자 자동 생성 및 final 변수를 의존관계를 자동으로 설정해 준다.

생성자 자동 생성 및 final 변수를 의존관계를 자동으로 설정해 준다. @Transactional

트랜잭션 보장이 된 메소드로 설정 해준다.

9. Controller 구현

💻 Controller 구현

package com . karim . simpleBoard . controller ; import com . karim . simpleBoard . service . UserService ; import com . karim . simpleBoard . vo . UserVo ; import lombok . RequiredArgsConstructor ; import org . springframework . security . core . Authentication ; import org . springframework . stereotype . Controller ; import org . springframework . ui . Model ; import org . springframework . web . bind . annotation . GetMapping ; import org . springframework . web . bind . annotation . PostMapping ; @Controller @RequiredArgsConstructor public class UserController { private final UserService userService ; @GetMapping public String root ( ) { return “redirect:/login” ; } @GetMapping ( “/login” ) public String login ( ) { return “login” ; } @GetMapping ( “/signUp” ) public String signUpForm ( ) { return “signUp” ; } @GetMapping ( “/access_denied” ) public String accessDenied ( ) { return “access_denied” ; } @PostMapping ( “/signUp” ) public String signUp ( UserVo userVo ) { userService . joinUser ( userVo ) ; return “redirect:/login” ; } @GetMapping ( “/user_access” ) public String userAccess ( Model model , Authentication authentication ) { UserVo userVo = ( UserVo ) authentication . getPrincipal ( ) ; model . addAttribute ( “info” , userVo . getUserId ( ) + “의 ” + userVo . getUserName ( ) + “님” ) ; return “user_access” ; } }

💬 어노테이션 설명

@RequiredArgsConstructor

생성자 자동 생성 및 final 변수를 의존관계를 자동으로 설정해 준다.

생성자 자동 생성 및 final 변수를 의존관계를 자동으로 설정해 준다. @GetMapping

@RequestMapping(Method=RequestMethod.GET)과 같다.

@RequestMapping(Method=RequestMethod.GET)과 같다. @PostMapping

@RequestMapping(Method=RequestMethod.POST)과 같다.

10. 실행

💻 WebApplication 구현

package com . karim . simpleBoard ; import org . springframework . boot . SpringApplication ; import org . springframework . boot . autoconfigure . SpringBootApplication ; @SpringBootApplication public class WebApplication { public static void main ( String [ ] args ) { SpringApplication . run ( WebApplication . class , args ) ; } }

💬 WebApplication 실행

기본 localhost:8080으로 띄어 진다.

11. 결과 화면

미리 회원가입을 한 후(TB_USER table에 계정이 있어야) 로그인 가능

💬 로그인 화면

💬 로그인 성공 시 화면

💬 로그인 실패 시 화면

📚 참고

Spring Boot | 로그인 구현하기 (Spring Security)

728×90

반응형

위의 과정을 통해 생성된 프로젝트입니다.

구성환경

SpringBoot, Gradle, Thymeleaf, Jpa(JPQL), Jar, MariaDB

이번 장에서는 스프링 시큐리티(Spring Security)를 이용한 로그인 처리, 로그아웃, 중복 로그인 처리, 로그인 정보 유지, 예외처리 등을 적용해본다.

회원 테이블 생성하기

로그인 처리 테스트를 하기 위한 기본적인 컬럼만 생성하였으니 필요시 추가하여 사용한다.

CREATE TABLE `member` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT ‘시퀀스’, `email` VARCHAR(200) NOT NULL COMMENT ‘이메일’ COLLATE ‘utf8mb4_general_ci’, `pwd` VARCHAR(200) NOT NULL COMMENT ‘패스워드’ COLLATE ‘utf8mb4_general_ci’, `last_login_time` DATETIME NULL DEFAULT NULL COMMENT ‘마지막 로그인 시간’, `register_time` DATETIME NULL DEFAULT NULL COMMENT ‘등록일’, `update_time` DATETIME NULL DEFAULT NULL COMMENT ‘수정일’, PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `email` (`email`) USING BTREE ) COMMENT=’회원’

build.gradle

spring-boot-starter-security 추가

implementation ‘org.springframework.boot:spring-boot-starter-security’

로그인 HTML

login.html ( /src/main/resources/templates/member )

Login

로그인 HTML에서 이메일, 비밀번호의 name을 username, password로 설정하였는데, 이는 스프링 시큐리티를 통한 로그인 처리 시 FormLoginConfigurer에서 디폴트 값으로 username, password 으로 받기 때문이다.

FormLoginConfigurer에서 파라미터를 username, password로 받고 있다.

*변경하고 싶을 경우 SecurityConfig에서 아래와 같이 직접 설정해준다.

.formLogin() .usernameParameter(“user”) // 디폴트가 username .passwordParameter(“pwd”) // 디폴트가 password

엔티티(Entity)

Member.java

Member Entity를 생성하고, UserDetails를 상속받아 로그인 처리 시 필요한 메서드를 오버라이드 한다.

package com.board.study.entity.board.member; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collection; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import com.board.study.entity.BaseTimeEntity; import lombok.AccessLevel; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; @EqualsAndHashCode( of = {“id”}) // equals, hashCode 자동 생성 @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter @Entity public class Member extends BaseTimeEntity implements UserDetails { private static final long serialVersionUID = 1 L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String email; private String pwd; private LocalDateTime lastLoginTime; @Builder public Member(Long id, String email, String pwd, LocalDateTime lastLoginTime) { this.id = id; this.email = email; this.pwd = pwd; this.lastLoginTime = lastLoginTime; } @Override public String getPassword() { return this.pwd; } @Override public String getUsername() { return this.email; } //계정이 갖고있는 권한 목록은 리턴 @Override public Collection getAuthorities() { Collection < GrantedAuthority > collectors = new ArrayList <> (); collectors.add(() -> { return “계정별 등록할 권한”; }); //collectors.add(new SimpleGrantedAuthority(“Role”)); return collectors; } //계정이 만료되지 않았는지 리턴 (true: 만료 안됨) @Override public boolean isAccountNonExpired() { return true; } //계정이 잠겨있는지 않았는지 리턴. (true: 잠기지 않음) @Override public boolean isAccountNonLocked() { return true; } //비밀번호가 만료되지 않았는지 리턴한다. (true: 만료 안됨) @Override public boolean isCredentialsNonExpired() { return true; } //계정이 활성화(사용가능)인지 리턴 (true: 활성화) @Override public boolean isEnabled() { return true; } }

컨트롤러(Controller)

MemberController.java

컨트롤러에서는 로그인 페이지 매핑만 하고 로그인 실패, 예외 처리에 대한 값을 받아 model에 넣어준다. 실제 로그인 처리는 스프링 시큐리티를 통해 진행한다.

package com.board.study.web; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class MemberController { @GetMapping(“/login”) public String getLoginPage(Model model, @RequestParam(value = “error”, required = false) String error, @RequestParam(value = “exception”, required = false) String exception) { model.addAttribute(“error”, error); model.addAttribute(“exception”, exception); return “/member/login”; } }

서비스(Service)

MemberService.java

UserDetailsService 인터페이스를 implements 하여 Spring Security에서 유저의 정보를 가져온다.

loadUserByUsername 메서드를 오버라이드하고, 접속하려는 이메일(아이디)이 존재하는지 데이터베이스에서 조회 후 해당 정보를 리턴한다.

package com.board.study.service; 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; import com.board.study.entity.board.member.Member; import com.board.study.entity.board.member.MemberRepository; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Service public class MemberService implements UserDetailsService { private final MemberRepository memberRepository; @Override public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { Member member = memberRepository.findByEmail(email); if (member == null) throw new UsernameNotFoundException(“Not Found account.”); return member; } }

리포지토리(Repository)

MemberRepository.java

로그인 성공 시 최종 로그인 일시를 업데이트할 쿼리와 이메일로 정보를 찾을 때 사용할 finbyEmail 메서드를 생성한다.

package com.board.study.entity.board.member; import java.time.LocalDateTime; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; public interface MemberRepository extends JpaRepository < Member, Long > { static final String UPDATE_MEMBER_LAST_LOGIN = “UPDATE Member SET LAST_LOGIN_TIME = :lastLoginTime WHERE EMAIL = :email”; @Transactional @Modifying @Query(value = UPDATE_MEMBER_LAST_LOGIN, nativeQuery = true) public int updateMemberLastLogin(@Param(“email”) String email, @Param(“lastLoginTime”) LocalDateTime lastLoginTime); public Member findByEmail(String emfail); }

로그인 성공 핸들러

AuthSucessHandler.java

SimpleUrlAuthenticationSuccessHandler를 상속받아 로그인 성공 시 처리할 로직을 작성한다. 마지막 로그인 일시를 업데이트하고 리턴할 URL을 작성한다.

package com.board.study.member.handler; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Component; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.time.LocalDateTime; import com.board.study.entity.board.member.MemberRepository; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Component public class AuthSucessHandler extends SimpleUrlAuthenticationSuccessHandler { private final MemberRepository memberRepository; @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { memberRepository.updateMemberLastLogin(authentication.getName(), LocalDateTime.now()); setDefaultTargetUrl(“/board/list”); super.onAuthenticationSuccess(request, response, authentication); } }

로그인 실패 핸들러

AuthFailureHandler.java

SimpleUrlAuthenticationFailureHandler를 상속받아 로그인 실패 시 처리할 로직을 작성한다. Exception에 대한 사용자 메시지를 처리 후 리턴 URL를 설정한다. 여기서 파라미터로 설정한 Exception 메시지가 로그인 페이지로 전달된다.

*여기서 로그인 실패 횟수에 대한 계정 잠금 처리 등을 추가로 작성할 수도 있다.

Exception 설명 UsernameNotFoundException 계정 없음 BadCredentialsException 비밀번호 불일치 AccountExpiredException 계정만료 CredentialExpiredException 비밀번호 만료 DisabledException 계정 비활성화 LockedException 계정잠김

package com.board.study.member.handler; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.CredentialsExpiredException; import org.springframework.security.authentication.DisabledException; import org.springframework.security.core.AuthenticationException; 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 AuthFailureHandler extends SimpleUrlAuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { String msg = “Invalid Email or Password”; // exception 관련 메세지 처리 if (exception instanceof DisabledException) { msg = “DisabledException account”; } else if (exception instanceof CredentialsExpiredException) { msg = “CredentialsExpiredException account”; } else if (exception instanceof BadCredentialsException) { msg = “BadCredentialsException account”; } setDefaultFailureUrl(“/login?error=true&exception=” + msg); super.onAuthenticationFailure(request, response, exception); } }

스프링 시큐리티 적용 WebSecurity

SecurityConfig.java

URL 패턴, 로그인, 로그아웃, 성공 실패 Handler등을 처리한다.

rememberMe (로그인 정보를 쿠키에 저장해 두었다가 사용하는 기법) 설정 시 브라우저를 종료하고 다시 로그인이 필요한 페이지에 접근해도 인증을 요구하지 않는다.

브라우저 개발자도구 Application > Cookies > rememberMe 쿠키가 HttpOnly( XSS 방지 )로 생성되어 있음을 확인할 수 있다.

Cookie remember-me

package com.board.study.config; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 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.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import com.board.study.member.handler.AuthFailureHandler; import com.board.study.member.handler.AuthSucessHandler; import com.board.study.service.MemberService; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @EnableWebSecurity // 시큐리티 필터 등록 @EnableGlobalMethodSecurity(prePostEnabled = true) // 특정 페이지에 특정 권한이 있는 유저만 접근을 허용할 경우 권한 및 인증을 미리 체크하겠다는 설정을 활성화한다. public class SecurityConfig extends WebSecurityConfigurerAdapter { private final MemberService memberService; private final AuthSucessHandler authSucessHandler; private final AuthFailureHandler authFailureHandler; // BCryptPasswordEncoder는 Spring Security에서 제공하는 비밀번호 암호화 객체 (BCrypt라는 해시 함수를 이용하여 패스워드를 암호화 한다.) // 회원 비밀번호 등록시 해당 메서드를 이용하여 암호화해야 로그인 처리시 동일한 해시로 비교한다. @Bean public BCryptPasswordEncoder encryptPassword() { return new BCryptPasswordEncoder(); } // 시큐리티가 로그인 과정에서 password를 가로챌때 해당 해쉬로 암호화해서 비교한다. @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(memberService).passwordEncoder(encryptPassword()); } @Override protected void configure(HttpSecurity http) throws Exception { /* csrf 토큰 활성화시 사용 쿠키를 생성할 때 HttpOnly 태그를 사용하면 클라이언트 스크립트가 보호된 쿠키에 액세스하는 위험을 줄일 수 있으므로 쿠키의 보안을 강화할 수 있다. */ //http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) http.csrf().disable() // csrf 토큰을 비활성화 .authorizeRequests() // 요청 URL에 따라 접근 권한을 설정 .antMatchers(“/”, “/login/**”, “/js/**”, “/css/**”, “/image/**”).permitAll() // 해당 경로들은 접근을 허용 .anyRequest() // 다른 모든 요청은 .authenticated() // 인증된 유저만 접근을 허용 .and() .formLogin() // 로그인 폼은 .loginPage(“/login”) // 해당 주소로 로그인 페이지를 호출한다. .loginProcessingUrl(“/login/action”) // 해당 URL로 요청이 오면 스프링 시큐리티가 가로채서 로그인처리를 한다. -> loadUserByName .successHandler(authSucessHandler) // 성공시 요청을 처리할 핸들러 .failureHandler(authFailureHandler) // 실패시 요청을 처리할 핸들러 .and() .logout() .logoutRequestMatcher(new AntPathRequestMatcher(“/logout”)) // 로그아웃 URL .logoutSuccessUrl(“/login”) // 성공시 리턴 URL .invalidateHttpSession(true) // 인증정보를 지우하고 세션을 무효화 .deleteCookies(“JSESSIONID”,”remember-me”) // JSESSIONID, remember-me 쿠키 삭제 .permitAll() .and() .sessionManagement() .maximumSessions(1) // 세션 최대 허용 수 1, -1인 경우 무제한 세션 허용 .maxSessionsPreventsLogin(false) // true면 중복 로그인을 막고, false면 이전 로그인의 세션을 해제 .expiredUrl(“/login?error=true&exception=Have been attempted to login from a new place. or session expired”) // 세션이 만료된 경우 이동 할 페이지를 지정 .and() .and().rememberMe() // 로그인 유지 .alwaysRemember(false) // 항상 기억할 것인지 여부 .tokenValiditySeconds(43200) // in seconds, 12시간 유지 .rememberMeParameter(“remember-me”); } }

테스트

로그인 페이지

로그인 실패

중복 로그인

SecurityConfig에 maxSessionsPreventsLogin에 설정한 대로 이전에 로그인 사용자를 로그아웃 한다.

+ 사용자 인증 객체 가져오기

Member activeUser = (Member) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

테스트로 계정을 생성할 때 비밀번호 암호화 시 사용

new BCryptPasswordEncoder().encode(“패스워드”);

GitHub

프로젝트 Import 방법

압축을 풀고, 이클립스 import → General → Existing Projects into Workspace

board.zip 0.25MB

728×90

반응형

Spring Security 로그인 구현하기

Spring Security를 사용하여 로그인과 회원가입 기능을 구현하는 방법을 알아보겠습니다.

간단하게 Spring Security를 적용한 프로젝트는 다음 깃 레포지토리를 통해 확인할 수 있습니다. 해당 프로젝트는 현재 설명하는 내용과 예제가 조금 다르지만 스프링 시큐리티에 대한 내용을 담고 있으니 참고하시기 바랍니다.

https://github.com/hanbee1005/lec-spring-security

Java 11

SpringBoot 2.3.0

Gradle 6.5

예제를 통해 살펴보겠습니다. 예제에서는 Spring MVC를 사용하여 컨트롤러, 서비스, 레포지토리를 만들 것이고 데이터베이스 접근은 JPA 방식을 사용하겠습니다. Spring MVC나 JPA에 대해서는 특별히 언급하지 않겠습니다… (다른 포스팅에서 다뤄볼게요…ㅎㅎ)

먼저 컨트롤러를 통해 아래와 같은 요청을 받을 수 있다고 가정해보겠습니다.

로그인: /auth/login

회원가입: /auth/signup

대시보드: /dashboard (로그인한 사용자만 접근이 가능)

관리자: /admin (로그인한 사용자 중 ADMIN 권한을 가진 사용자만 접근이 가능)

위와 같은 요청을 받을 수 있는 AuthController, HomeController를 생성합니다. 각각의 요청은 별도의 화면 없이 바로 String 데이터를 반환하는 방식으로 구현하였습니다.

package com.example.securityspring.controller; import com.example.securityspring.dto.JwtRequestDto; import com.example.securityspring.dto.MemberSignupRequestDto; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(“/auth”) public class AuthController { @PostMapping(value = “login”, produces = MediaType.APPLICATION_JSON_VALUE) public String login(@RequestBody JwtRequestDto request) { return “login”; } @PostMapping(value = “signup”, produces = MediaType.APPLICATION_JSON_VALUE) public String signup(@RequestBody MemberSignupRequestDto request) { return “signup”; } }

package com.example.securityspring.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HomeController { @GetMapping(“dashboard”) public String dashboard() { return “dashboard”; } @GetMapping(“admin”) public String admin() { return “admin”; } }

로그인 시 입력되는 데이터는 이메일과 패스워드로 추후 JWT 방식을 적용할 것이기 때문에 이름이 JwtRequestDto인 객체를 생성하여 받도록 하겠습니다. 회원가입 시 입력되는 데이터는 이메일, 패스워드, 이름 정도의 데이터로 하겠습니다. 이 데이터는 MemberSignupRequestDto 객체를 통해 받도록 하겠습니다.

package com.example.securityspring.dto; import lombok.Getter; import lombok.Setter; @Getter @Setter public class JwtRequestDto { private String email; private String password; }

package com.example.securityspring.dto; import lombok.Getter; import lombok.Setter; @Getter @Setter public class MemberSignupRequestDto { private String email; private String password; private String name; }

❗️참고

@Getter, @Setter 애노테이션은 lombok 패키지를 추가하면 사용이 가능합니다. build.gradle 파일에 추가하면 됩니다.

implementation ‘org.projectlombok:lombok’ annotationProcessor ‘org.projectlombok:lombok’

아직 Spring Security가 적용되어 있지 않기 때문에 모든 요청에 다 접근이 가능합니다.

이제 Spring Security를 적용해보도록 하겠습니다.

1. build.gradle 파일에 spring security에 대한 의존을 추가합니다.

implementation ‘org.springframework.boot:spring-boot-starter-security’

이 부분만 추가해주더라도 spring security가 동작하면서 기존에 그냥 접근이 가능했던 모든 페이지에서 인증을 요청하게 됩니다. 기본적으로 Spring Security가 제공하는 계정이 있는데 아이디는 user, 비밀번호는 애플리케이션을 실행할 때 콘솔창에 출력됩니다.

2. WebSecurityConfigurerAdapter를 상속받는 설정 파일을 생성합니다.

package com.example.securityspring.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { // 정적인 파일에 대한 요청들 private static final String[] AUTH_WHITELIST = { // — swagger ui “/v2/api-docs”, “/v3/api-docs/**”, “/configuration/ui”, “/swagger-resources/**”, “/configuration/security”, “/swagger-ui.html”, “/webjars/**”, “/file/**”, “/image/**”, “/swagger/**”, “/swagger-ui/**”, // other public endpoints of your API may be appended to this array “/h2/**” }; @Bean public BCryptPasswordEncoder encodePassword() { // 회원가입 시 비밀번호 암호화에 사용할 Encoder 빈 등록 return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // login 없이 접근 허용 하는 url .antMatchers(“/auth/**”).permitAll() // ‘/admin’의 경우 ADMIN 권한이 있는 사용자만 접근이 가능 .antMatchers(“/admin”).hasRole(“ADMIN”) // 그 외 모든 요청은 인증과정 필요 .anyRequest().authenticated(); } @Override public void configure(WebSecurity web) throws Exception { // 정적인 파일 요청에 대해 무시 web.ignoring().antMatchers(AUTH_WHITELIST); } }

이 파일을 통해 어떤 url에 대해 요청을 허용할지, 권한 확인은 어떻게 할지 결정하게 됩니다. 기본적으로 제공되는 로그인, 로그아웃 페이지를 사용하도록 설정할 수도 있습니다. 추가적인 내용에 대해서는 공식 자료를 참고하시기 바랍니다…

3. 회원가입 기능을 구현합니다.

패스워드는 암호화를 한 다음 저장하도록 하겠습니다. 데이터베이스 관련 JPA 코드는 살펴보지 않겠습니다. 아무 관계형 데이터베이스나 다 사용이 가능합니다.

package com.example.securityspring.controller; import com.example.securityspring.dto.JwtRequestDto; import com.example.securityspring.dto.MemberSignupRequestDto; import com.example.securityspring.service.AuthService; import lombok.AllArgsConstructor; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(“/auth”) @AllArgsConstructor public class AuthController { private final AuthService authService; … @PostMapping(value = “signup”, produces = MediaType.APPLICATION_JSON_VALUE) public String signup(@RequestBody MemberSignupRequestDto request) { return authService.signup(request); } }

package com.example.securityspring.service; import com.example.securityspring.domain.Member; import com.example.securityspring.dto.MemberSignupRequestDto; import com.example.securityspring.repository.MemberRepository; import lombok.AllArgsConstructor; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional @AllArgsConstructor public class AuthService { private final MemberRepository memberRepository; private final PasswordEncoder passwordEncoder; public String signup(MemberSignupRequestDto request) { boolean existMember = memberRepository.existsById(request.getEmail()); // 이미 회원이 존재하는 경우 if (existMember) return null; Member member = new Member(request); member.encryptPassword(passwordEncoder); memberRepository.save(member); return member.getEmail(); } }

package com.example.securityspring.domain; import com.example.securityspring.dto.MemberSignupRequestDto; import com.example.securityspring.model.Role; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.security.crypto.password.PasswordEncoder; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.Id; @Getter @Entity @NoArgsConstructor public class Member { @Id private String email; private String password; private String name; @Enumerated(EnumType.STRING) private Role role; public Member(MemberSignupRequestDto request) { email = request.getEmail(); password = request.getPassword(); name = request.getName(); role = Role.USER; // 회원가입하는 사용자 권한 기본 USER (임시) } public void encryptPassword(PasswordEncoder passwordEncoder) { password = passwordEncoder.encode(password); } }

public interface MemberRepository extends JpaRepository { }

저는 테스트 코드를 작성하여 구현된 기능을 확인하였는데 테스트 코드를 작성하지 않는 경우에는 Postman 등을 통해 요청을 보냄으로써 확인이 가능합니다. 만약 Postman으로 테스트를 하는 경우에는 csrf 에러가 발생할 수 있으므로 security config 설정을 변경해주어야 합니다.

@Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable().authorizeRequests() … }

이렇게 회원가입을 하면 비밀번호가 암호화된 상태로 데이터가 저장되는 것을 확인할 수 있습니다.

4. UserDetailsService 및 UserDetails 구현을 통해 로그인 처리를 하고 인증된 사용자를 어떤 형태로 반환할지 정하는 객체를 생성합니다.

package com.example.securityspring.security; import com.example.securityspring.domain.Member; import com.example.securityspring.repository.MemberRepository; 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; @RequiredArgsConstructor @Service public class UserDetailsServiceImpl implements UserDetailsService { private final MemberRepository memberRepository; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { Member member = memberRepository.findById(username) .orElseThrow(()-> new UsernameNotFoundException(“등록되지 않은 사용자 입니다”)); return new UserDetailsImpl(member); } }

package com.example.securityspring.security; import com.example.securityspring.domain.Member; import com.example.securityspring.model.Role; import lombok.AllArgsConstructor; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.ArrayList; import java.util.Collection; @AllArgsConstructor public class UserDetailsImpl implements UserDetails { private static final String ROLE_PREFIX = “ROLE_”; private final Member member; @Override public Collection getAuthorities() { Role role = member.getRole(); SimpleGrantedAuthority authority = new SimpleGrantedAuthority(ROLE_PREFIX + role.toString()); Collection authorities = new ArrayList<>(); //List인 이유 : 여러개의 권한을 가질 수 있다 authorities.add(authority); return authorities; } @Override public String getPassword() { return member.getPassword(); } @Override public String getUsername() { return member.getEmail(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }

5. 로그인 기능을 구현합니다.

package com.example.securityspring.controller; import com.example.securityspring.dto.JwtRequestDto; import com.example.securityspring.dto.MemberSignupRequestDto; import com.example.securityspring.service.AuthService; import lombok.AllArgsConstructor; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(“/auth”) @AllArgsConstructor public class AuthController { private final AuthService authService; @PostMapping(value = “login”, produces = MediaType.APPLICATION_JSON_VALUE) public String login(@RequestBody JwtRequestDto request) { try { return authService.login(request); } catch (Exception e) { return e.getMessage(); } } … }

package com.example.securityspring.service; import com.example.securityspring.domain.Member; import com.example.securityspring.dto.JwtRequestDto; import com.example.securityspring.dto.MemberSignupRequestDto; import com.example.securityspring.repository.MemberRepository; import com.example.securityspring.security.UserDetailsImpl; import lombok.AllArgsConstructor; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional @AllArgsConstructor public class AuthService { private final MemberRepository memberRepository; private final PasswordEncoder passwordEncoder; private final AuthenticationManager authenticationManager; public String login(JwtRequestDto request) throws Exception { Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(request.getEmail(), request.getPassword())); SecurityContextHolder.getContext().setAuthentication(authentication); UserDetailsImpl principal = (UserDetailsImpl) authentication.getPrincipal(); return principal.getUsername(); } … }

package com.example.securityspring.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; 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.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { … @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } … }

이렇게 하면 Spring Security를 통한 로그인, 회원가입 기능 구현이 완료되었습니다. 로그인을 하고 나면 /dashboard 에 접근할 수 있습니다. 기본적으로 회원가입되는 사용자는 USER 권한을 가지기 때문입니다.

위에서 설명한 내용은 아래 프로젝트를 통해 확인할 수 있습니다. Spring Security의 인증 과정은 많은 filter들로 이루어져 있는데 이 부분을 구체적으로 학습하면 더 도움이 될 것 같습니다 🙂 (인프런 백기선 강사님의 Spring Security 강의 추천!!)

https://github.com/hanbee1005/security-spring

So you have finished reading the 스프링 시큐리티 로그인 구현 topic article, if you find this article useful, please share it. Thank you very much. See more: 스프링부트 시큐리티 로그인 예제, 스프링 시큐리티 깃 허브 로그인, spring security 회원가입, Spring boot security mybatis login, Spring boot Security 예제, Vue 스프링 시큐리티 로그인, 스프링 시큐리티 로그인 페이지 없애기, 스프링부트 시큐리티 로그인 세션

Leave a Comment