How to get the Access Token in Okta SSO, Getting java.io.FileNotFoundException - spring

I am new to the Okta SSO, trying to get the Access token using below code.Am i using right API and package to do this? Please suggest, Thanks in advance
private com.microsoft.aad.adal4j.AuthenticationResult.AuthenticationResult getAccessToken(
AuthorizationCode authorizationCode, String currentUri)
throws Throwable {
String authCode = authorizationCode.getValue();
ClientCredential credential = new ClientCredential(clientId,
clientSecret);
com.microsoft.aad.adal4j.AuthenticationContext context = null;
com.microsoft.aad.adal4j.AuthenticationResult result = null;
java.util.concurrent.ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
context = new AuthenticationContext("https://dev-xxxxxxx.okta.com/oauth2/oauth2/authorize", true,
service);
Future<AuthenticationResult> future = context.acquireTokenByAuthorizationCode(authCode, new URI(currentUri), credential, null);
result = future.get();
} catch (ExecutionException e) {
throw e.getCause();
} catch(InterruptedException e){
LOGGER.error(e);
} catch(MalformedURLException e){
LOGGER.error("Malformed URL :"+e);
}finally {
service.shutdown();
}
if (result == null) {
throw new ServiceUnavailableException(
"authentication result was null");
}
return result;
}
10:59:05,653 ERROR AuthenticationContext:148 - [Correlation ID: cc2fccef-6c3c-4638-ae53-02d8ac2504c7] Request to acquire token failed.
java.io.FileNotFoundException: https://xxxxxx/common/discovery/instance?api-version=1.0&authorization_endpoint=https://xxxxxxxx/oauth2/oauth2/authorize
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1872)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at com.microsoft.aad.adal4j.HttpHelper.readResponseFromConnection(HttpHelper.java:86)
at com.microsoft.aad.adal4j.HttpHelper.getResponse(HttpHelper.java:182)
at com.microsoft.aad.adal4j.HttpHelper.executeGetRequest(HttpHelper.java:158)
at com.microsoft.aad.adal4j.HttpHelper.executeHttpGet(HttpHelper.java:59)
at com.microsoft.aad.adal4j.AuthenticationAuthority.doDynamicInstanceDiscovery(AuthenticationAuthority.java:149)
at com.microsoft.aad.adal4j.AuthenticationAuthority.doInstanceDiscovery(AuthenticationAuthority.java:135)
at com.microsoft.aad.adal4j.AuthenticationContext.acquireTokenCommon(AuthenticationContext.java:775)
at com.microsoft.aad.adal4j.AuthenticationContext.access$100(AuthenticationContext.java:64)
at com.microsoft.aad.adal4j.AuthenticationContext$1.call(AuthenticationContext.java:141)
at com.microsoft.aad.adal4j.AuthenticationContext$1.call(AuthenticationContext.java:130)

Related

Okta URL redirection issue

I have developed an application which do SSO in various applications. I am able to authorize user and able to redirect on application embedded link by passing sessionToken which is a value of cookieToken in that url and this piece of code is working fine and not asking for login again.
#GetMapping("get-sso-url/{user_id}")
public ResponseEntity<Object> getSSOUrl(#PathVariable("user_id") String userId, #RequestParam("app_id") String appId){
log.info("DashboardController::getSSOUrl::START");
UserActivityDetails userActivityDetails = userActivityService.getUserActivity(userId);
AppInfoDetails appInfoDetails = appInfoService.findById(appId);
String appUrl = appInfoDetails.getApiEndpoint() + userActivityDetails.getCookieToken();
log.debug("DashboardController::getSSOUrl::appUrl " + appUrl);
log.info("DashboardController::getSSOUrl::END");
return new ResponseEntity<>(new UrlResponse(appUrl), HttpStatus.OK);
}
Now I just want to verify that the url is returning HttpStatus.OK or not? so I have written like this:
public ResponseEntity<Object> getSSOUrl(#PathVariable("user_id") String userId, #RequestParam("app_id") String appId){
log.info("DashboardController::getSSOUrl::START");
UserActivityDetails userActivityDetails = userActivityService.getUserActivity(userId);
AppInfoDetails appInfoDetails = appInfoService.findById(appId);
String appUrl = appInfoDetails.getApiEndpoint() + userActivityDetails.getCookieToken();
log.debug("DashboardController::getSSOUrl::appUrl " + appUrl);
log.info("DashboardController::getSSOUrl::END");
return checkAppResponse(appUrl).equals(HttpStatus.OK) ? new ResponseEntity<>(new UrlResponse(appUrl), HttpStatus.OK)
: new ResponseEntity<>(new UrlResponse(appUrl), HttpStatus.NOT_FOUND);
}
private HttpStatus checkAppResponse(String appUrl){
try{
URL url = new URL(appUrl);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
int statusCode = httpURLConnection.getResponseCode();
if(statusCode == 200)
return HttpStatus.OK;
} catch (MalformedURLException e) {
throw new CustomRuntimeException(e.getMessage());
} catch (IOException e) {
throw new RuntimeException(e);
}
return HttpStatus.NOT_FOUND;
}
After adding above check, when I'm trying to redirect on application it asks me to login to the okta first.
Here is a sreenshot

Get response body 401 spring

I'm consuming a service using Spring's Rest Template. I'm getting error 401 in response: [no body]. But I'm doing the same query by postman, and I get the body. can anybody help me?
code:
private static List<AcervoMarcSecao> assinar(List<AcervoMarcSecao> acervosMarcSecao, byte[] imgAssinatura) throws ClientException, IOException {
restTemplate = new RestTemplate();
ResponseEntity<String> response = null;
HttpEntity<?> request = getHttpEntity(acervosMarcSecao, imgAssinatura);
try {
response = restTemplate
.exchange(parametros.get("SERVICE_HUB2_BASE_URL") + "/fw/v1/pdf/kms/lote/assinaturas",
HttpMethod.POST, request, String.class);
if(response.getBody() != null) {
LoteAssinaturaDTO loteAssinatura = new Gson().fromJson(response.getBody(), LoteAssinaturaDTO.class);
for(int i = 0; i < acervosMarcSecao.size(); i++) {
byte[] documentoAssinado = ImageRecover.recoverImageFromUrl(loteAssinatura.getDocumentos().get(i)
.getLinks().get(0).getHref());
if(documentoAssinado != null)
if(acervosMarcSecao.get(i).getVinculo() == null)
acervosMarcSecao.get(i).setVinculo(new Vinculos());
acervosMarcSecao.get(i).getVinculo().setArquivoAssinado(documentoAssinado);
acervosMarcSecao.get(i).getVinculo().setDataGravacao(new Date());
}
}
return acervosMarcSecao;
} catch (RestClientResponseException e) {
ErrorDTO error = new Gson().fromJson(e.getResponseBodyAsString(), ErrorDTO.class);
if(error.getChave().equals("excecao.hub.perfil")) {
throw new AlertaException(resourceBundle.getString("lblTipoAssinaturaDigitalInvalida"));
}
throw new AlertaException(error.getMessage());
} catch (Exception e) {
throw new AlertaException(resourceBundle.getString("txtErroCertificarArquivo"));
}
}
postman:

Spring boot RestTemplate close connection for NULL responses results in ConnectionPoolTimeoutExceptions

We have a spring boot Application which makes RESTFul calls to a bunch of backends, one of them returns null reponses at times, and we are observing the connections are not released during these instances because of this code in RestTemplate class:
protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor<T> responseExtractor) throws RestClientException {
Assert.notNull(url, "'url' must not be null");
Assert.notNull(method, "'method' must not be null");
ClientHttpResponse response = null;
try {
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
handleResponse(url, method, response);
if (responseExtractor != null) {
return responseExtractor.extractData(response);
}
else {
return null;
}
}
catch (IOException ex) {
String resource = url.toString();
String query = url.getRawQuery();
resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);
throw new ResourceAccessException("I/O error on " + method.name() +
" request for \"" + resource + "\": " + ex.getMessage(), ex);
}
finally {
if (response != null) {
response.close();
}
}
}
Is there a way we can release the connection or consume the contents for when response is null or erring out?
Edited to add code causing errors:
MyHttpClientClass{
private X getResponseBody(RestClient client, URI uri, HttpMethod method, HttpEntity<T> entity, Class<R> responseType, MyErrorHandler errorHandler) {
try
{ String host = this.getHost();
ResponseEntity<X> resp = client.exchange(uri, method, entity, responseType);
return resp.getBody();
} catch (HttpServerErrorException | HttpClientErrorException e)
{ handleHttpException(e, errorHandler);
throw e;
} catch (Exception e) {
log(e);
throw e; } } }
-----------
Class1 implements Callable<T>
{
#Override public T doCall() throws Exception {
try
{ return this.getRestClient().exchange(this.getUri(),
this.getHttpMethod(), this.getEntity(), getResponseType()).getBody(); } catch (HttpClientErrorException ex) { throw ex; } catch (HttpStatusCodeException ex) { if(this.isNeededRetry(ex)) { throw ex; }else { return generateErrorResponse(ex).getBody(); } } catch (RestClientException ex) { throw ex; } catch (Exception ex) { throw ex; } } }
----------
MySpringApplicationClass{
public X get(String api, String params, Class<R> responseType, String path, List<String> pathVariables, MyErrorHandler errorHandler)
{
return getResponseBody(...);
}}

Spring boot HeaderWriterFilter overrides header created in controller

When I add a header to the responseEntity in the Controller, it is not added to the response. I debug the code, an when it reach the "HeaderWriterFilter" it adds default header, but it has no track of the one added in the Controller.
#RequestMapping(
value = "/get-file",
method = RequestMethod.GET
)
public ResponseEntity<Resource> download(Principal principal, Long fileId) throws IOException {
if (principal == null) {
throw new UsernameNotFoundException("User not found.");
}
try {
User loggedInUser = ((LoggedInUserDetails) ((UsernamePasswordAuthenticationToken) principal).getPrincipal()).getLoggedInUser();
// Get file
File file = this.fileService.getById(loggedInUser, fileId);
if (file == null) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
// Get file for download
java.io.File physicalFile = new java.io.File(file.getUrl());
if (file == null) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
InputStreamResource resource = new InputStreamResource(new FileInputStream(physicalFile));
HttpHeaders headers = new HttpHeaders();
headers.add("test", "test.yaml");
return ResponseEntity.ok()
.headers(headers)
.contentType(MediaType.parseMediaType("application/octet-stream"))
.contentLength(physicalFile.length())
.body(resource);
}
catch (FileNotFoundException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
}
The problem was a missing header in WebSecurityConfig. I solved the problem adding
configuration.setExposedHeaders(Arrays.asList("fileName"));
in CorsConfigurationSource.

Authorization code malformed or invalid when getting Azure AD access token with Spring

I have this error when I try to generate the token.
I have do this tutorial http://blog.xebia.in/index.php/2017/12/21/spring-security-and-oauth2-with-azure-active-directory/.
My problem is when I try to get an access token after I have the code.
I have this error:
Here is the related code:
public AuthenticationResult getAccessToken(AuthorizationCode authorizationCode, String currentUri) throws Throwable {
String authCode = authorizationCode.getValue();
ClientCredential credential = new ClientCredential(clientId, clientSecret);
AuthenticationContext context = null;
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
context = new AuthenticationContext(authority + tenant + "/", true, service);
//here are the error
Future<AuthenticationResult> future = context.acquireTokenByAuthorizationCode(authCode, new URI(currentUri), credential, resource, null);
result = future.get();
} catch (ExecutionException e) {
throw e.getCause();
} finally {
service.shutdown();
}

Resources