201 lines
7.8 KiB
Java
201 lines
7.8 KiB
Java
package com.eactive.eai.authserver.custom;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.json.simple.JSONObject;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.security.oauth2.provider.ClientDetails;
|
|
import org.springframework.util.MultiValueMap;
|
|
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.RequestMethod;
|
|
import org.springframework.web.bind.annotation.RequestParam;
|
|
import org.springframework.web.bind.annotation.ResponseBody;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
|
|
import com.eactive.eai.authserver.config.RequestContextData;
|
|
import com.eactive.eai.authserver.dao.TokenIssuanceLogDAO;
|
|
import com.eactive.eai.authserver.service.BearerTokenService;
|
|
import com.eactive.eai.authserver.service.OAuth2Manager;
|
|
import com.eactive.eai.authserver.vo.ClientVO;
|
|
import com.eactive.eai.common.logger.EAIDBLogControl;
|
|
import com.eactive.eai.common.util.Logger;
|
|
import com.eactive.eai.common.util.MessageUtil;
|
|
import com.eactive.eai.data.entity.onl.authserver.TokenIssuanceLog;
|
|
|
|
@RestController
|
|
@RequestMapping("/auth/oauth/v2")
|
|
public class BearerTokenController {
|
|
|
|
public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
|
|
private final BearerTokenService tokenService;
|
|
|
|
@Autowired
|
|
private TokenIssuanceLogDAO tokenIssuanceLogDAO;
|
|
|
|
public BearerTokenController(BearerTokenService tokenService) {
|
|
this.tokenService = tokenService;
|
|
}
|
|
|
|
@RequestMapping(
|
|
value = "/token",
|
|
method = {RequestMethod.POST, RequestMethod.GET}
|
|
)
|
|
public ResponseEntity<?> issueCAToken(HttpServletRequest request, @RequestParam MultiValueMap<String, String> req) throws JwtAuthException {
|
|
JSONObject resObject = new JSONObject();
|
|
String clientId = req.getFirst("client_id");
|
|
String grantType = req.getFirst("grant_type");
|
|
String clientSecret = req.getFirst("client_secret");
|
|
String scopes = req.getFirst("scope");
|
|
|
|
try {
|
|
|
|
|
|
RequestContextData data = new RequestContextData();
|
|
data.setClientId(request.getParameter("client_id"));
|
|
data.setIpAddress(extractIpAddress(request));
|
|
data.setGrantType(request.getParameter("grant_type"));
|
|
data.setScope(request.getParameter("scope"));
|
|
data.setUsername(request.getParameter("username"));
|
|
data.setResource(request.getParameter("resource"));
|
|
|
|
RequestContextData.ThreadLocalRequestContext.set(data);
|
|
|
|
|
|
|
|
if (!StringUtils.equals(grantType, "client_credentials") ) {
|
|
throw new JwtAuthException("unsupported_grant_type", "Unsupported grant type");
|
|
}
|
|
|
|
ClientDetails clientDetails = OAuth2Manager.getInstance().getClientDeatilsStore().get(clientId);
|
|
if (clientDetails == null) {
|
|
throw new JwtAuthException("invalid_client", "Bad client credentials(not found)");
|
|
}
|
|
|
|
String tokenType = "Bearer";
|
|
|
|
|
|
|
|
|
|
Long expiresIn = Long.valueOf(clientDetails.getAccessTokenValiditySeconds());
|
|
|
|
String[] reqScopeArr = org.springframework.util.StringUtils.tokenizeToStringArray(scopes, " ");
|
|
Set<String> scopeSet = new HashSet<String>();
|
|
for (String scope : reqScopeArr) {
|
|
scopeSet.add(scope);
|
|
}
|
|
veryfyClient(clientDetails, clientSecret, scopeSet);
|
|
|
|
String token = tokenService.generateCAToken(clientId, expiresIn, scopeSet);
|
|
|
|
Map<String, Object> tokenMap = new HashMap<>();
|
|
tokenMap.put("token_type", tokenType);
|
|
tokenMap.put("access_token", token);
|
|
tokenMap.put("expires_in", expiresIn);
|
|
tokenMap.put("scope", scopes);
|
|
// ... and so on for all key-value pairs
|
|
resObject.putAll(tokenMap);
|
|
|
|
logTokenIssuance(true,false, resObject.toJSONString(), token);
|
|
|
|
return ResponseEntity.ok(resObject);
|
|
} catch (JwtAuthException e) {
|
|
logger.error("Token request[/auth/oauth/v2/token] => clientId: {}, grantType: {}, scope: {}",
|
|
clientId, grantType, scopes);
|
|
logger.error(e);
|
|
String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AUTH_FAIL, e.getMessage());
|
|
logTokenIssuance(false ,false, e.getMessage(), null);
|
|
return ResponseEntity.status(401).body(errorJson);
|
|
} catch (Exception e) {
|
|
logger.error("Token request[/auth/oauth/v2/token] => clientId: {}, grantType: {}, scope: {}",
|
|
clientId, grantType, scopes);
|
|
logger.error(e);
|
|
String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AP_ERROR, e.getMessage());
|
|
logTokenIssuance(false ,false, e.getMessage(), null);
|
|
return ResponseEntity.status(500).body(errorJson);
|
|
}finally {
|
|
RequestContextData.ThreadLocalRequestContext.clear();
|
|
}
|
|
}
|
|
|
|
private String extractIpAddress(HttpServletRequest request) {
|
|
String ipAddress = request.getHeader("X-Forwarded-For");
|
|
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
|
|
ipAddress = request.getHeader("Proxy-Client-IP");
|
|
}
|
|
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
|
|
ipAddress = request.getHeader("WL-Proxy-Client-IP");
|
|
}
|
|
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
|
|
ipAddress = request.getHeader("HTTP_CLIENT_IP");
|
|
}
|
|
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
|
|
ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
|
|
}
|
|
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
|
|
ipAddress = request.getRemoteAddr();
|
|
}
|
|
return ipAddress;
|
|
}
|
|
|
|
private void logTokenIssuance(boolean isSuccess, boolean isRestrictionExempt, String resultMessage, String accessToken) {
|
|
try {
|
|
if (!EAIDBLogControl.isEnable()) {
|
|
logger.warn("DB logging is disabled. Skipping token issuance logging.");
|
|
return;
|
|
}
|
|
RequestContextData data = RequestContextData.ThreadLocalRequestContext.get();
|
|
OAuth2Manager.getInstance();
|
|
|
|
TokenIssuanceLog log = new TokenIssuanceLog();
|
|
String clientId = data.getClientId();
|
|
log.setClientId(clientId);
|
|
|
|
if(StringUtils.isNotBlank(clientId)) {
|
|
ClientVO clientVO = OAuth2Manager.getInstance().getClientInfo(clientId);
|
|
log.setAppName(clientVO.getClientName());
|
|
log.setOrgId(clientVO.getOrgId());
|
|
log.setOrgName(clientVO.getOrgName());
|
|
}
|
|
|
|
log.setGrantType(data.getGrantType());
|
|
log.setScope(data.getScope());
|
|
log.setIpAddress(data.getIpAddress());
|
|
log.setSuccessYn(isSuccess ? "Y" : "N");
|
|
log.setIssuanceDateTime(LocalDateTime.now());
|
|
log.setRestrictionExemptYn(isRestrictionExempt ? "Y" : "N");
|
|
log.setResultMessage(resultMessage);
|
|
log.setAccessToken(accessToken); // Add access token value to the log
|
|
|
|
tokenIssuanceLogDAO.saveTokenIssuanceLog(log);
|
|
} catch (Throwable th) {
|
|
logger.error("Error while logging token issuance: " + th.getMessage(), th);
|
|
}
|
|
}
|
|
|
|
private void veryfyClient(ClientDetails clientDetails, String clientSecret, Set<String> scopeSet) throws JwtAuthException {
|
|
if (!StringUtils.equals(clientDetails.getClientSecret(), clientSecret)) {
|
|
throw new JwtAuthException("invalid_client", "Bad client credentials(client_secret is empty or not match)");
|
|
}
|
|
|
|
if (scopeSet.isEmpty()) {
|
|
throw new JwtAuthException("invalid_client", "Bad client credentials(Scope is empty)");
|
|
}
|
|
|
|
if (!clientDetails.getScope().containsAll(scopeSet)) {
|
|
throw new JwtAuthException("invalid_client", "Bad client credentials(Include unacceptable scope)");
|
|
}
|
|
}
|
|
}
|
|
|