|
|
|
@ -10,12 +10,11 @@ package io.entgra.auth_token_getter.service;
|
|
|
|
|
*
|
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
*
|
|
|
|
|
* Unless required by applicable law or agreed to in writing,
|
|
|
|
|
* software distributed under the License is distributed on an
|
|
|
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
|
|
* KIND, either express or implied. See the License for the
|
|
|
|
|
* specific language governing permissions and limitations
|
|
|
|
|
* under the License.
|
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
|
|
* KIND, either express or implied. See the License for the specific language governing
|
|
|
|
|
* permissions and limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import feign.FeignException;
|
|
|
|
@ -24,6 +23,8 @@ import io.entgra.auth_token_getter.util.TokenDataHolder;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
import org.springframework.http.HttpStatus;
|
|
|
|
|
import org.springframework.http.ResponseEntity;
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
@ -60,46 +61,44 @@ public class TokenService {
|
|
|
|
|
@Value("${refresh-token}")
|
|
|
|
|
private String refreshToken;
|
|
|
|
|
|
|
|
|
|
// @Value("${jwt-token}")
|
|
|
|
|
// private String jwtToken;
|
|
|
|
|
|
|
|
|
|
@Value("${saml2-assertion}")
|
|
|
|
|
private String saml2Assertion;
|
|
|
|
|
|
|
|
|
|
// Method to fetch the token and store it in TokenDataHolder
|
|
|
|
|
public Object fetchToken(String scope) {
|
|
|
|
|
|
|
|
|
|
public ResponseEntity<Object> fetchToken(String scope) {
|
|
|
|
|
// Basic validation for required fields
|
|
|
|
|
if (clientId == null || clientId.isEmpty()) {
|
|
|
|
|
return createErrorResponse(400,
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(400,
|
|
|
|
|
"Missing client ID",
|
|
|
|
|
"clientId is not configured.");
|
|
|
|
|
"clientId is not configured."), HttpStatus.BAD_REQUEST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (clientSecret == null || clientSecret.isEmpty()) {
|
|
|
|
|
return createErrorResponse(400,
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(400,
|
|
|
|
|
"Missing client secret",
|
|
|
|
|
"clientSecret is not configured.");
|
|
|
|
|
"clientSecret is not configured."), HttpStatus.BAD_REQUEST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (grantType == null || grantType.isEmpty()) {
|
|
|
|
|
return createErrorResponse(400,
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(400,
|
|
|
|
|
"Missing grant type",
|
|
|
|
|
"grantType is not configured.");
|
|
|
|
|
"grantType is not configured."), HttpStatus.BAD_REQUEST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (scope == null || scope.isEmpty()) {
|
|
|
|
|
return createErrorResponse(400,
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(400,
|
|
|
|
|
"Missing scope",
|
|
|
|
|
"Scope is required to fetch the token.");
|
|
|
|
|
"Scope is required to fetch the token."), HttpStatus.BAD_REQUEST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Base64 encode client credentials for Authorization header
|
|
|
|
|
String auth = clientId + ":" + clientSecret;
|
|
|
|
|
String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
String authHeader;
|
|
|
|
|
String body;
|
|
|
|
|
|
|
|
|
|
// Handle different grant types
|
|
|
|
|
switch (grantType) {
|
|
|
|
|
|
|
|
|
|
case "password":
|
|
|
|
|
authHeader = "Basic " + encodedAuth;
|
|
|
|
|
body = "grant_type=" + grantType + "&username=" + userName + "&password=" + password + "&scope=" + scope;
|
|
|
|
@ -115,25 +114,20 @@ public class TokenService {
|
|
|
|
|
body = "grant_type=refresh_token&refresh_token=" + refreshToken;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// case "urn:ietf:params:oauth:grant-type:jwt-bearer":
|
|
|
|
|
// authHeader = "Basic " + encodedAuth;
|
|
|
|
|
// body = "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=" + jwtToken;
|
|
|
|
|
// break;
|
|
|
|
|
|
|
|
|
|
case "urn:ietf:params:oauth:grant-type:saml2-bearer":
|
|
|
|
|
authHeader = "Basic " + encodedAuth;
|
|
|
|
|
body = "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&assertion=" + saml2Assertion;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case "iwa-ntlm":
|
|
|
|
|
return createErrorResponse(501,
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(501,
|
|
|
|
|
"Not Implemented",
|
|
|
|
|
"IWA-NTLM grant type not handled directly.");
|
|
|
|
|
"IWA-NTLM grant type not handled directly."), HttpStatus.NOT_IMPLEMENTED);
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return createErrorResponse(400,
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(400,
|
|
|
|
|
"Invalid grant type",
|
|
|
|
|
"Unsupported grant type: " + grantType);
|
|
|
|
|
"Unsupported grant type: " + grantType), HttpStatus.BAD_REQUEST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Map<String, String> response;
|
|
|
|
@ -146,48 +140,51 @@ public class TokenService {
|
|
|
|
|
if (response != null) {
|
|
|
|
|
String accessToken = response.get("access_token");
|
|
|
|
|
if (accessToken != null) {
|
|
|
|
|
// Store access token and additional information in TokenDataHolder
|
|
|
|
|
tokenDataHolder.setAccessToken(accessToken);
|
|
|
|
|
tokenDataHolder.setTokenType(response.get("token_type"));
|
|
|
|
|
tokenDataHolder.setExpiresIn(Integer.parseInt(response.get("expires_in")));
|
|
|
|
|
tokenDataHolder.setScope(response.get("scope"));
|
|
|
|
|
log.info("Access token stored in the DataHolder");
|
|
|
|
|
return accessToken;
|
|
|
|
|
return new ResponseEntity<>(accessToken, HttpStatus.OK);
|
|
|
|
|
} else {
|
|
|
|
|
log.error("Access token not found in response");
|
|
|
|
|
return createErrorResponse(500,
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(500,
|
|
|
|
|
"Token Error",
|
|
|
|
|
"Access token not found in the response.");
|
|
|
|
|
"Access token not found in the response."), HttpStatus.INTERNAL_SERVER_ERROR);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (FeignException e) {
|
|
|
|
|
// Handle FeignException and return corresponding status code
|
|
|
|
|
String errorMessage = e.getMessage();
|
|
|
|
|
|
|
|
|
|
if (errorMessage != null && errorMessage.contains("[401]")) {
|
|
|
|
|
log.error("Client credentials or client secret is incorrect: {}", errorMessage);
|
|
|
|
|
return createErrorResponse(500,
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(401,
|
|
|
|
|
"Client Credentials Error",
|
|
|
|
|
"Client credentials or client secret is incorrect.");
|
|
|
|
|
"Client credentials or client secret is incorrect."), HttpStatus.UNAUTHORIZED);
|
|
|
|
|
} else if (errorMessage.contains("Connection refused")) {
|
|
|
|
|
log.error("Resource server is not working: {}", errorMessage);
|
|
|
|
|
return createErrorResponse(500,
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(503,
|
|
|
|
|
"Resource Server Error",
|
|
|
|
|
"Resource server is not working.");
|
|
|
|
|
"Resource server is not working."), HttpStatus.SERVICE_UNAVAILABLE);
|
|
|
|
|
} else {
|
|
|
|
|
log.error("Error while fetching token: {}", errorMessage);
|
|
|
|
|
return createErrorResponse(500,
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(500,
|
|
|
|
|
"Feign Client Error",
|
|
|
|
|
errorMessage); // Return the original Feign exception message if not matched
|
|
|
|
|
errorMessage), HttpStatus.INTERNAL_SERVER_ERROR);
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("An unexpected error occurred: {}", e.getMessage());
|
|
|
|
|
return createErrorResponse(500,
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(500,
|
|
|
|
|
"Unexpected Error",
|
|
|
|
|
e.getMessage());
|
|
|
|
|
e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return createErrorResponse(500,
|
|
|
|
|
// Default error response if no other condition is met
|
|
|
|
|
return new ResponseEntity<>(createErrorResponse(500,
|
|
|
|
|
"Unknown Error",
|
|
|
|
|
"Failed to fetch the token for unknown reasons.");
|
|
|
|
|
"Failed to fetch the token for unknown reasons."), HttpStatus.INTERNAL_SERVER_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|