티스토리 뷰
반응형
package com.inspection.oauth2.interceptor;
import java.io.IOException;
import java.security.Principal;
import java.util.Collection;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.inspection.core.security.service.InspectionUserDetails;
@EnableAutoConfiguration
public class RefreshTokenIssueBeforeAccessTokenCheckIntercpetor extends HandlerInterceptorAdapter {
private static Logger LOG = LoggerFactory.getLogger(RefreshTokenIssueBeforeAccessTokenCheckIntercpetor.class);
private DataSource dataSource;
public RefreshTokenIssueBeforeAccessTokenCheckIntercpetor(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String url = request.getRequestURI();
if (url.equals("/v1/oauth/token")) {
String grantType = request.getParameter("grant_type");
if (grantType.equals("refresh_token")) {
// refresh token 일때 재발급 하기전에 우선 검색해본다.
// client 부분 먼저 인증해본다.
Authentication authentication = (Authentication) request.getUserPrincipal();
if (!authentication.isAuthenticated()) {
throw new InsufficientAuthenticationException("The client is not authenticated.");
}
String clientId = getClientId(request.getHeader("Authorization"));
if(!"key".equals(clientId)) {
return true;
}
String refreshToken = request.getParameter("refresh_token");
// refreshToken으로 사용자 인증 정보를 가져온다.
OAuth2Authentication oauth2Authentication = tokenStore().readAuthenticationForRefreshToken(refreshToken);
UserDetails userDetails = (InspectionUserDetails) oauth2Authentication.getUserAuthentication()
.getPrincipal();
LOG.info(ToStringBuilder.reflectionToString(userDetails));
// 발급된 사용자 refreshToken 정보로 accessToken을 가져온다.
Collection<OAuth2AccessToken> accessTokens = tokenStore()
.findTokensByUserName(userDetails.getUsername());
if (accessTokens == null) {
// 기존 발급된 accessToken이 없을 때 refreshToken 새로 발급
return true;
}
// 아니면 인증 정보를 가져와서 reponse로 뿌려준다.
OAuth2AccessToken oauth2AccessToken = accessTokens.iterator().next();
LOG.info(oauth2AccessToken.getValue());
request.setAttribute("oauth2", oauth2AccessToken);
RequestDispatcher rd = request.getRequestDispatcher("/v1/test/oauth2");
rd.forward(request, response);
return false;
}
}
return true;
}
/**
* This implementation is empty.
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
protected String getClientId(Principal principal) {
Authentication client = (Authentication) principal;
if (!client.isAuthenticated()) {
throw new InsufficientAuthenticationException("The client is not authenticated.");
}
String clientId = client.getName();
if (client instanceof OAuth2Authentication) {
// Might be a client and user combined authentication
clientId = ((OAuth2Authentication) client).getOAuth2Request().getClientId();
}
return clientId;
}
@Bean
public JdbcTokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
/**
* client 가져오기
* @author 정명성
* @create date : 2016. 8. 3.
* @param header
* @param request
* @return
* @throws IOException
*/
private String getClientId(String header) throws IOException {
byte[] base64Token = header.substring(6).getBytes("UTF-8");
byte[] decoded;
try {
decoded = Base64.decode(base64Token);
} catch (IllegalArgumentException e) {
throw new BadCredentialsException("Failed to decode basic authentication token");
}
String token = new String(decoded, "UTF-8");
int delim = token.indexOf(":");
if (delim == -1) {
throw new BadCredentialsException("Invalid basic authentication token");
}
return token.substring(0, delim);
}
}
@RequestMapping(value = "/test/oauth2")
public ResponseEntity RefreshTokenExistAccessToken(HttpServletRequest request) {
OAuth2AccessToken oauth2AccessToken = (OAuth2AccessToken) request.getAttribute("oauth2");
HttpHeaders headers = new HttpHeaders();
headers.set("Cache-Control", "no-store");
headers.set("Pragma", "no-cache");
return new ResponseEntity<OAuth2AccessToken>(oauth2AccessToken, headers, HttpStatus.OK);
}
용도는 refresh_token을 발급했을때 access_token이 만료가 안된 상태면 access_token을 그대로 내보낼려고 했다.
이걸 한 이유는 안드로이드 앱에서 뻗는 경우가 있다고해서 그 액션이 안뻗게 만들려고 했었는데,
원인을 확인한 바. 안드로이드 앱에서 메모리 릭이 발생되서 문제가 생겼던 것이였다.
위 코드는 spring oauth2 내부적으로 돌아가는 부분 코드를 발쵀해서 적용한 것이기 때문에
뭐 좀더 경험할 수 있었다.
반응형
'Web Development > Spring OAuth2' 카테고리의 다른 글
Spring oauth2 설정 부분. (0) | 2016.08.12 |
---|---|
Spring OAuth2 인증 토큰 발급 관련 Test Html (jquery, angularjs) (0) | 2016.08.12 |
Spring OAuth2 CORS(cross origin requests are only supported for HTTP) 관련 필터 설정. (0) | 2016.08.12 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- java 폴더구조 구하기
- jstl 커스텀 태그
- java calendar
- spring ExcelView
- jstl foreach
- mybatis Merge
- jstl split
- java 압축 풀기
- Kotlin
- POE Excel 만들기
- JSTL
- POI EXCEL
- java 설정
- java 설치
- coroutine
- 코루틴
- JSP 세션
- java 특정문자 갯수구하기
- spring property
- Database#transaction
- github image 첨부시 주의할점
- 전자정부프레임워크 tiles
- MyBatis 팁
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함