403 Forbidden error, while access the ClientRepresentation in keycloack - http-status-code-403

We use keycloak API in our application. When we try to retrieve the Client list of the realm it pass 403 forbidden error. Highly appreciate your comments for avoid this matter.
String authServer = UriUtils.getOrigin(httpRequest.getRequestURL().toString()) + AUTH_CONTEXT_PATH;
String token = httpRequest.getHeader("Authorization").replaceAll("Bearer ", "");
String realmClientsUrl = authServer+"/admin/realms/testrealm/clients/"+getClientRepresentationId(authServer,realm,token);
ClientRequest request = getClientRequest(realmClientsUrl,token);
ClientResponse<String> response;
ClientRepresentation clientRepresentation = null;
try{
response = request.get(String.class);
validateResponse(response,"CLIENT_REPRESENTATION");
clientRepresentation = response.getEntity(ClientRepresentation.class);
return clientRepresentation;
} catch (Exception e) {
e.printStackTrace();
}
Error which passed,
java.lang.Exception: ErrorStage:CLIENT_REPRESENTATION_ID,HTTP responseCode:403,StatusIno=Forbidden

You might get this error if the logged in user doesn't have the relevant Client Roles access. Add the client role access as "View Client" under realm-management.

Related

Create Envelope with access token returns 404 (DocuSign PHP SDK)

I am trying to create an envelope through PHP sdk, we have working integration using X-DocuSign-Authentication header (with user, password, integrator key combo). Trying to migrate the integration to access token, but keep on getting 404 Resource not found error from the actual SDK (the resources is dictated by the SDK).
Current code:
// DocuSign\eSign\Configuration
$config = new Configuration();
$config->setHost('https://www.docusign.net/restapi');
// DocuSign\eSign\Client\ApiClient
$api = new ApiClient($config);
try {
$response = $api->requestJWTUserToken(
"correct-integrators-key",
"correct-user-id",
file_get_contents( base_path() . '/ds-private.key', true), //exists
"signature impersonation",
);
}
catch (ApiException $e) {
return $e->getMessage();
}
JWT Token payload comes back successfully, and access token is valid.
// DocuSign\eSign\Client\Auth\OAuthToken
if(!$response[0] instanceof OAuthToken)
return "Auth Token Invalid.";
$access_token = $response[0]->getAccessToken();
try {
$user = $api->getUserInfo($access_token);
} catch (ApiException $e) {
return $e->getMessage();
}
// DocuSign\eSign\Client\Auth\UserInfo
if(!$user[0] instanceof UserInfo)
return "User Info Invalid.";
Setting the account ID and base URL also are seemingly correct (account ID comes back as expected, and is correct one, base URL comes back as na2 subdomain, seems to be the correct - this is supported by the fact that "USER_DOES_NOT_BELONG_TO_SPECIFIED_ACCOUNT" is thrown if any other host is used)
$account_id = null;
$base_url = null;
foreach ($user[0]->getAccounts() as $account) {
if($account instanceof Account)
if($account->getIsDefault()) {
$account_id = $account->getAccountId(); // Account ID succeeds, comes back as correct account ID (verified on the admin panel)
$base_url = $account->getBaseUri(); // Base URL succeeds, comes back as na2 subdomain
}
}
$config->setAccessToken($access_token); // Access token succeeds
$config->setHost($base_url);
This code is practically copy/paste of working example with the "old" integration.
$envelopeApi = new EnvelopesApi($api);
$templateRole = new TemplateRole();
$definition = new EnvelopeDefinition();
$templateRole->setEmail('catchable#gmail.com');
$templateRole->setName('Rebecca Smith');
$templateRole->setRoleName('Correct Role Defined On Template');
$templateRole->setClientUserId('Correct User Id For Embedding');
$signers = [];
$signers[] = $templateRole;
$definition->setTemplateId('Valid Template Id');
$definition->setTemplateRoles($signers);
$definition->setStatus('sent');
try {
$envelope = $envelopeApi->createEnvelope($account_id, $definition);
}
catch (ApiException $e) {
return [
'envelope_error_message' => $e->getMessage(), // Returns: "Error while requesting server, received a non successful HTTP code [404] with response Body: "
'envelope_error_code' => $e->getCode(), // Returns: 404
];
}
Tried also directly running $api->callApi to check if v2.1 vs v2 in resource path is the issue, but got 404 on both.
You need to append /restapi to the baseUri
Instead of
$base_url = $account->getBaseUri(); // Base URL succeeds, comes back as na2 subdomain
try
$base_uri_suffix = '/restapi';
$base_url = $account->getBaseUri().$base_uri_suffix; // Base URL succeeds, comes back as na2 subdomain
See the source in the PHP Code Example

Unable to catch CosmosException when token expired in Blazor WebAssembly

I am using Azure CosmosDB with Blazor WebAssembly (client-side).
I want to catch CosmosException When connection token expires, But not getting cosmos exception for that, (Null exception found)
I have also tried same code in console application, In that I am able to catch cosmos exception that showing token expired.
Code sample :
using (CosmosClient client = new CosmosClient(account, token))
{
Database db = null;
db = client.GetDatabase("databaseName");
Container orgContainer = client.GetContainer("databaseName","containerName");
try
{
ItemResponse<CosmosException> response = await orgContainer.ReadItemAsync<CosmosException>("test", new PartitionKey("test"));
var data = response.Resource;
}
catch(CosmosException ex)
{
}
catch(Exception ex)
{
}
}
Exception Details of Console Application
This is probably because the exception occurs outside the try block. Also, make sure you do not instantiate a new cosmos client on each request. This does not perform well. Use singleton and keep alive between requests.

Does Keycloak allow obtaining id tokens via web interface

I am investigating how to possibly authenticate to a Kubernetes 1.13 cluster with OpenID Connect and Keycloak. I am new to this area.
This YouTube video ("Use Open ID Connect for Kubernetes API server") accomplishes part of what I want. An id token is initially obtained by making a HTTP request (with curl) to Keycloak citing grant type password. The resulting token is then subsequently used in further HTTP requests to the Kubernetes API. This works but has the disadvantage that clients directly handle users' permanent credentials.
Would it not be better if the token were issued by a secure web page that also required authentication via Keycloak (this time with grant type authorization code) and did nothing else but displaying a new token? Such tokens (transient credentials) could then e.g. be manually copied into kubeconfigs for further use?
Does Keycloak provide such interactive web pages (next to the REST endpoints for obtaining tokens programatically) or is this out of scope? If the second, are there other standard components for such tasks?
UPDATE This illustration from the Kubernetes documentation perhaps makes more clear what I am seeking. In step 1 a user should log into the Identity provider to obtain tokens which can then be configured into kubectl. Does Keycloak support this step, i.e. offer a web page where users could log in to obtain their tokens?
If I am able to understand your question ,so you want to get the accesstoken via Java code so here is code you can write and call
String obtainAccessToken = obtainAccessToken(username, password);
putRequest.addHeader("Authorization", "bearer " + obtainAccessToken);
putRequest.addHeader("content-type", MediaType.APPLICATION_JSON);
Here is the method you should call
public String obtainAccessToken(String UserName, String pwd)
{
AuthzClient authzClient = AuthzClient.create(configuration);
AccessTokenResponse accessTokenResponse = authzClient.obtainAccessToken(UserName, pwd);
String token = accessTokenResponse.getToken();
return token;
}
Here is the get realm method
public Response getAllRealms() {
ObjectMapper mapper = JacksonObjectMapperProvider.getObjectMapper();
CloseableHttpResponse response = null;
List<SureRealmRepresentation> realmList = new ArrayList<SureRealmRepresentation>();
int status;
try {
String urlGetAllRealms = URL + "/admin/realms";
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet getRequest = new HttpGet(urlGetAllRealms);
String obtainAccessToken = obtainAccessToken(username, password);
getRequest.addHeader("Authorization", "bearer " + obtainAccessToken);
getRequest.addHeader("content-type", MediaType.APPLICATION_JSON);
response = httpclient.execute(getRequest);
status = response.getStatusLine().getStatusCode();
String responseBody = EntityUtils.toString(response.getEntity());
if (status == 200) {
RealmRepresentation[] realmArray = mapper.readValue(responseBody, RealmRepresentation[].class);
}
catch (Exception e) {
if (e instanceof Exception) {
throw (Exception) e;
} else {
throw ErrorHandler.wrap(new Exception("EroorType : "+ e.toString()));
}
}

Azure App Service Error 405 - The request could not be completed. (Method Not Allowed)

I'm working with Azure App Service .NET backend with a Xamarin.iOS app. I am able to successfully register a new user and I can see the user's details in the database. I have a custom ApiController, which handles the registration and the I'm able to save the details with a successful POST call.
However, when I try to log into the app, I get the following error:
{Microsoft.WindowsAzure.MobileServices.MobileServiceInvalidOperationException: The request could not be completed. (Method Not Allowed)
Below is my code:
The RegistrationController in the backend which successfully makes a POST call
[MobileAppController]
[RoutePrefix("api/register")]
[AllowAnonymous]
public class RegisterController : ApiController
{
[HttpPost]
[Route("newuser")]
public HttpResponseMessage NewUser(RegistrationRequest request)
{
// Registration code in here
}
}
This is how I call this function on the client side:
public async Task<Result<UserProfile>> RegisterUser(RegistrationWrapper registrationrequest)
{
try
{
var registrationRequest = new JObject();
registrationRequest.Add("username", registrationrequest.username);
registrationRequest.Add("password", registrationrequest.password);
registrationRequest.Add("email", registrationrequest.email);
registrationRequest.Add("phone", registrationrequest.phone);
registrationRequest.Add("firstname", registrationrequest.firstname);
registrationRequest.Add("lastname", registrationrequest.lastname);
var result = await client.InvokeApiAsync("register/newuser", registrationRequest);
// Handle result here
}
catch (Exception ex)
{
return Result<UserProfile>.Failure(ex.Message + ex.StackTrace + ex.InnerException);
}
}
Custom AuthController which handles the login
This POST call fails with the error described above.
[MobileAppController]
[RoutePrefix("api/auth")]
public class AuthController : ApiController
{
public HttpResponseMessage Post(AuthenticationRequest credentials)
{
try
{
//Authentication code goes here
catch (Exception e)
{
Console.WriteLine("Ërror :" + e.Message);
Console.WriteLine(e.StackTrace);
return Request.CreateResponse(HttpStatusCode.InternalServerError, new
{
Stacktrace = e.StackTrace,
ErrorMessage = e.Message,
Credentials = credentials
});
}
}
How I invoke this function from the client side
async Task<Result<Account>> Login(string username, string password)
{
try
{
var credentials = new JObject();
credentials.Add("username", username);
credentials.Add("password", password);
var result = await client.InvokeApiAsync("auth", credentials);
//Handle result here
}
catch (Exception ex)
{
return Result<Account>.Failure(ex, ex.Message + ex.StackTrace);
}
}
}
I'm not sure why it's failing during the log in. Any ideas?
After trying tons of solutions found here on StackOverflow, the one that finally worked for me was this first answer found on a similar question.
It seems that the http POST call is redirected to https.
After enabling authentication on your App Service in the Azure portal, you need to change the url to https.
So I changed mine from this:
http//{my_site}.azurewebsites.net
To this:
https//{my_site}.azurewebsites.net
On the client side, and now used this new one to create my local sync tables.
Everything works as expected now.
The HTTP status code 405 is returned when an API endpoint is called with a wrong (Not Allowed) HTTP method. For example, if instead of a POST request the endpoint is called with a GET request.

IBM Connections Atom Profile Service

I am trying to get back a profile for myself but I only get back a successful http response...no data. This is the code I am using.
try {
RestClient restClient = new RestClient("https://apps.na.collabserv.com","my.email","my.password");
Response<AtomFeed> responseFeed = restClient.doGet("/profiles/atom/profileService.do").asAtomFeed();
System.out.println(responseFeed.getData().toXmlString());
} catch(Exception e) {
e.printStackTrace();
}
If I try to add a email= to the url I get a 403 forbidden return.
Not really sure what the issue is,
Thanks!

Resources