-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add JWT Authentication
- Loading branch information
jeehun.yang
committed
Jan 5, 2020
1 parent
df1fe2b
commit 378b622
Showing
18 changed files
with
593 additions
and
137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
src/main/java/com/example/demobook/common/EHCacheConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.example.demobook.common; | ||
|
||
import org.springframework.cache.annotation.EnableCaching; | ||
import org.springframework.cache.ehcache.EhCacheCacheManager; | ||
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; | ||
import org.springframework.context.annotation.AdviceMode; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.core.io.ClassPathResource; | ||
|
||
@Configuration | ||
@EnableCaching(proxyTargetClass = true, mode = AdviceMode.PROXY) | ||
public class EHCacheConfig { | ||
@Bean | ||
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() { | ||
EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean(); | ||
ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml")); | ||
ehCacheManagerFactoryBean.setShared(true); | ||
return ehCacheManagerFactoryBean; | ||
} | ||
|
||
@Bean | ||
public EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean ehCacheManagerFactoryBean) { | ||
EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager(); | ||
ehCacheCacheManager.setCacheManager(ehCacheManagerFactoryBean.getObject()); | ||
return ehCacheCacheManager; | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
src/main/java/com/example/demobook/security/application/AuthenticationService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package com.example.demobook.security.application; | ||
|
||
import static org.springframework.http.ResponseEntity.ok; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.authentication.BadCredentialsException; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.AuthenticationException; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
|
||
import com.example.demobook.security.config.JwtTokenProvider; | ||
import com.example.demobook.security.domain.AuthenticationRequest; | ||
import com.example.demobook.user.application.UserService; | ||
|
||
@Service | ||
public class AuthenticationService { | ||
|
||
private AuthenticationManager authenticationManager; | ||
private JwtTokenProvider jwtTokenProvider; | ||
private UserService userService; | ||
|
||
public AuthenticationService( | ||
AuthenticationManager authenticationManager, | ||
JwtTokenProvider jwtTokenProvider, | ||
UserService userService) { | ||
this.authenticationManager = authenticationManager; | ||
this.jwtTokenProvider = jwtTokenProvider; | ||
this.userService = userService; | ||
} | ||
|
||
/** | ||
* 가입된 유저가 로그인해서 유저 인증이 완료했을 경우, 유저 jwt 토큰을 발급하여 유저에게 전달해준다. | ||
* @param data AuthenticationRequest | ||
* @return user jwt token | ||
* @throws Exception | ||
*/ | ||
public ResponseEntity signin(@RequestBody AuthenticationRequest data, HttpServletResponse response) throws Exception { | ||
try { | ||
String userName = data.getUsername(); | ||
final Authentication authentication = | ||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userName, data.getPassword())); | ||
SecurityContextHolder.getContext().setAuthentication(authentication); | ||
|
||
String token = jwtTokenProvider.createToken(userName, | ||
userService.findByUserId(userName) | ||
.orElseThrow(() -> | ||
new UsernameNotFoundException("Username " + userName + " not found")) | ||
.getUserAuthorizations() | ||
.stream() | ||
.map(userAuthorization -> | ||
userAuthorization.getRoleName()) | ||
.collect(Collectors.toList())); | ||
Map<Object, Object> model = new HashMap<>(); | ||
model.put("username", userName); | ||
model.put("token", token); | ||
return ok(model); | ||
}catch (AuthenticationException e) { | ||
throw new BadCredentialsException("Invalid username/password supplied"); | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/com/example/demobook/security/config/JwtConfigurer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.example.demobook.security.config; | ||
|
||
import org.springframework.security.config.annotation.SecurityConfigurerAdapter; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.web.DefaultSecurityFilterChain; | ||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
|
||
/** | ||
* JWT 설정 | ||
*/ | ||
public class JwtConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> { | ||
|
||
private JwtTokenProvider jwtTokenProvider; | ||
|
||
public JwtConfigurer(JwtTokenProvider jwtTokenProvider) { | ||
this.jwtTokenProvider = jwtTokenProvider; | ||
} | ||
|
||
/** | ||
* JwtToken 필터 전에 인증 필터 추가 | ||
* @param http | ||
* @throws Exception | ||
*/ | ||
public void configure(HttpSecurity http) throws Exception { | ||
JwtTokenFilter customFilter = new JwtTokenFilter(jwtTokenProvider); | ||
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
src/main/java/com/example/demobook/security/config/JwtTokenFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.example.demobook.security.config; | ||
|
||
import java.io.IOException; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.ServletRequest; | ||
import javax.servlet.ServletResponse; | ||
import javax.servlet.http.HttpServletRequest; | ||
|
||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.web.filter.GenericFilterBean; | ||
|
||
/** | ||
* 토큰의 유효성을 검사하는 필터 | ||
*/ | ||
public class JwtTokenFilter extends GenericFilterBean { | ||
|
||
private JwtTokenProvider jwtTokenProvider; | ||
|
||
public JwtTokenFilter(JwtTokenProvider jwtTokenProvider) { | ||
this.jwtTokenProvider = jwtTokenProvider; | ||
} | ||
|
||
/** | ||
* JWT 토큰의 유효성을 검사하기 위해 사용자 정의 JWT 토큰 기반 인증 필터 정의 | ||
* @param req | ||
* @param res | ||
* @param filterChain | ||
* @throws IOException | ||
* @throws ServletException | ||
*/ | ||
@Override | ||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, | ||
ServletException { | ||
String token = jwtTokenProvider.resolveToken((HttpServletRequest) req); | ||
if(token != null && jwtTokenProvider.validateToken(token)) { | ||
Authentication auth = jwtTokenProvider.getAuthentication(token); | ||
if(auth != null) { | ||
SecurityContextHolder.getContext().setAuthentication(auth); | ||
} | ||
} | ||
filterChain.doFilter(req, res); | ||
} | ||
} |
Oops, something went wrong.