I've set up AmazonAutoScalingAsync client as well as many others but I'm unable to retrieve the existing ASGs.
BasicSessionCredentials sessionCredentials =
new BasicSessionCredentials(
credentials.getAccessKeyId(),
credentials.getSecretAccessKey(),
credentials.getSessionToken());
// Assume role
AWSSecurityTokenService sts_client_mfa =
AWSSecurityTokenServiceClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(sessionCredentials))
.build();
AssumeRoleRequest request =
new AssumeRoleRequest()
.withRoleSessionName("proserv-" + username)
.withRoleArn("myarn");
AssumeRoleResult response = sts_client_mfa.assumeRole(request);
Then I build the auto-scaling client as follows:
autoScalingClient =
AmazonAutoScalingAsyncClientBuilder.standard()
.withCredentials(
new AWSStaticCredentialsProvider(
new BasicSessionCredentials(
response.getCredentials().getAccessKeyId(),
response.getCredentials().getSecretAccessKey(),
response.getCredentials().getSessionToken())))
.withRegion(region)
.build();
These are the same steps I do from the AWS console but can't see the same results on the Java code.
getAutoScalingClient()
.describeAutoScalingGroupsAsync()
.get()
.getAutoScalingGroups()
.forEach(
group -> {
System.out.println(group);
});
getAutoScalingClient()
.describeAutoScalingInstancesAsync()
.get()
.getAutoScalingInstances()
.forEach(
entry -> {
System.out.println(entry);
});
Any thoughts?
Just figured it out. I was using the wrong region. After switching to the correct region it displayed as expected.
Related
I need to implement a relatively complex authorization process for a Spring Boot application and consider using Keycloak for this.
Is it possible to do following things using Keycloak (incl. by extending it with custom authentication/authorization mechanisms)?
Keeping track of sessions: Does Keycloak know on how many devices a user is logged in into the application?
Keeping track of failed login attempts: Does Keycloak know how many times a particular user entered an incorrect password?
Terminating sessions: Is it possible to terminate some (but not all) sessions of a user?
My answers
1. Keeping track of session
According to the user manual, section "Managing user sessions", "Viewing client sessions" it is possible to see all active sessions of a user via the web UI.
According to this answer, it is possible to do so programmatically.
2. Keeping track of failed login attempts
According to this page, it may be possible to implement it using a custom event listener.
3. Terminating sessions
It looks like it is possible using the http://auth-server{kc_realms_path}/{realm-name}/protocol/openid-connect/logout endpoint according to documentation and this answer.
Update 1: It looks like items 1 and 2 are indeed possible.
However, I am having trouble with termination of sessions.
This is what I want:
User logs in via Keycloak into a Spring Boot application.
When I terminate the session, the user is logged out of that application.
First, I tried to delete sessions using code like this:
final Keycloak keycloak = KeycloakBuilder.builder()
.serverUrl("http://localhost:8080")
.realm("KeycloakDemo")
.username("postman")
.password("postman2022")
.clientId("postman")
.clientSecret("ZY006ddQbWHdSiAK3A06rrPlKgSz3XS0")
.build();
final UserRepresentation user =
keycloak.realm("KeycloakDemo").users().search("user1").get(0);
final String userId = user.getId();
final UserSessionRepresentation[] sessions = keycloak
.realm("KeycloakDemo")
.users().get(userId).getUserSessions()
.toArray(new UserSessionRepresentation[0]);
if (sessions.length > 0) {
final String sessionId = sessions[0].getId();
keycloak.realm("KeycloakDemo").deleteSession(sessionId);
}
This piece of code deletes sessions (i. e. they are not visible in the Keycloak GUI any longer), but it does not log out the user.
Another attempt was to log out the user after the session was deleted using the following code.
final String token = getToken();
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = RequestBody.create(mediaType, "");
Request request = new Request.Builder()
.url("http://localhost:8080/realms/KeycloakDemo/protocol/openid-connect/logout?id_token_hint=" + token)
.method("GET", null)
.build();
Response response = client.newCall(request).execute();
getToken() is defined as follows:
private String getToken() throws IOException {
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "client_id=admin-cli&username=postman&password=postman2022&grant_type=client_credentials&scope=openid&realm=KeycloakDemo&client_secret=CMewUzBUsiy0gUqg6uEmCRBgR5p6f5Nu");
Request request = new Request.Builder()
.url("http://localhost:8080/realms/KeycloakDemo/protocol/openid-connect/token")
.method("POST", body)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("Authorization", "bearer ... ")
.build();
Response response = client.newCall(request).execute();
if (response.code() != 200) {
System.exit(1);
}
final ObjectMapper om = new ObjectMapper();
final JsonNode jsonNode = om.readTree(response.body().string());
return jsonNode.get("id_token").asText();
}
This does not work, either (the user stays logged in that application, ever if I refresh the page in the browser).
I am able to programmatically log in to the PowerBI Client, gather my Workspaces as well as get a specific Report from a specific Workspace. I need to programmatically render that report to a .pdf or .xlsx file. Allegedly this is possible with the ExportToFileInGroup/ExportToFileInGroupAsync methods. I even created a very simple report without any parameters. I can embed this using the sample app from here. So that at least tells me that I have what I need setup in the backend. But it fails when I try to run the ExportToFileInGroupAsync method (errors below code.)
My Code is:
var accessToken = await tokenAcquisition.GetAccessTokenForUserAsync(new string[] {
PowerBiScopes.ReadReport,
PowerBiScopes.ReadDataset,
});
var userInfo = await graphServiceClient.Me.Request().GetAsync();
var userName = userInfo.Mail;
AuthDetails authDetails = new AuthDetails {
UserName = userName,
AccessToken = accessToken,
};
var credentials = new TokenCredentials($"{accessToken}", "Bearer");
PowerBIClient powerBIClient = new PowerBIClient(credentials);
var groups = await powerBIClient.Groups.GetGroupsAsync();
var theGroup = groups.Value
.Where(x => x.Name == "SWIFT Application Development")
.FirstOrDefault();
var groupReports = await powerBIClient.Reports.GetReportsAsync(theGroup.Id);
var theReport = groupReports.Value
.Where(x => x.Name == "No Param Test")
.FirstOrDefault();
var exportRequest = new ExportReportRequest {
Format = FileFormat.PDF,
};
string result = "";
try {
var response = await powerBIClient.Reports.ExportToFileInGroupAsync(theGroup.Id, theReport.Id, exportRequest);
result = response.ReportId.ToString();
} catch (Exception e) {
result = e.Message;
}
return result;
It gets to the line in the try block and then throws the following errors:
An error occurred while sending the request.
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
UPDATE
Relating to #AndreyNikolov question, here is our Embedded capacity:
After this was implemented, no change. Same exact error.
Turns out the issue was on our side, more specifically, security/firewall settings. Here is the exact quote from our networking guru.
"After some more investigation we determined that our firewall was causing this issue when it was terminating the SSL connection. We were able to add a bypass for the URL and it is now working as expected."
I have the following simple main class that executes Spark.
Spark.port(4570);
final Configuration configuration = new Configuration(new Version(2, 3, 0));
configuration.setClassForTemplateLoading(SparkHandler.class, "/");
Spark.staticFileLocation("/public");
Spark.get("/", (request, response) -> {
// read patterns
// attributes for web-interface.
Map<String, Object> attributes = new HashMap<>();
attributes.put("data", "someData");
return new ModelAndView(attributes, "timeline.ftl");
} , new FreeMarkerEngine());
Everything woks fine. When I go to http://localhost:4570/ I got the requested web-page!
I now change the path in the get statement to /a/b/c but execute the very same code:
Spark.port(4570);
final Configuration configuration = new Configuration(new Version(2, 3, 0));
configuration.setClassForTemplateLoading(SparkHandler.class, "/");
Spark.staticFileLocation("/public");
Spark.get("/a/b/c", (request, response) -> {
// read patterns
// attributes for web-interface.
Map<String, Object> attributes = new HashMap<>();
attributes.put("data", "someData");
return new ModelAndView(attributes, "timeline.ftl");
} , new FreeMarkerEngine());
If I now go to e.g. http://localhost:4570/a/b/c, it returns messages that lots of resources that could previously be found are not available any more. E.g.
INFO 28/07/16 14:45:03:The requested route [/a/b/vis/vis.js] has not been mapped in Spark
However, it is exactly in the location /public/vis/vis.js.
Does that get command change my static directory? Or is something happening here that I just do not understand :).
I found the answer!
In my freemarker/html file I used relative parts like e.g.
<script src="./vis/vis.js"></script>
Changing them to absolute paths solves the problem:
<script src="/vis/vis.js"></script>
Sorry for the silly question, but maybe it helps others.
I am new to Android Development and I would like to know how to perform a GET request using okhttp. I have referred http://square.github.io/okhttp/, but they only have examples of POST request. I have tried this -
okHttpClientLogin = new OkHttpClient();
requestBodyLogin = new FormBody.Builder()
.addEncoded("name", name_input) // params
.addEncoded("keys", keys_input) //params
.build();
requestLogin = new Request.Builder()
.addHeader("Authorization", token_type + " " +access_token)
.url(LOGIN_URL)
.get()
.build();
and got an Error :
{"status":{"status":206,"msg":"No record found"},"user":null}
I know why this error is coming, because the params have not been entered. I also tried passing requestBodyLogin inside .get() but it's not allowing.
Since OkHTTP 2.4, there's the function addQueryParameter. You can either use a HttpUrl, a String or a java.net.URL as url.
Basically, just create a new HttpUrl.Builder() and use the function addQueryParameter.
Example taken from the javadocs:
HttpUrl url = new HttpUrl.Builder()
.scheme("https")
.host("www.google.com")
.addPathSegment("search")
.addQueryParameter("q", "polar bears")
.build();
http://square.github.io/okhttp/3.x/okhttp/okhttp3/HttpUrl.html
http://square.github.io/okhttp/2.x/okhttp/com/squareup/okhttp/HttpUrl.Builder.html#addQueryParameter-java.lang.String-java.lang.String-
I'm very keen to utilize Meteor as the framework for my next project. However, there is a requirement to keep customer data separated into different MongoDB instances for users from different customers.
I have read on this thread that it could be as simple as using this:
var d = new MongoInternals.RemoteCollectionDriver("<mongo url>");
C = new Mongo.Collection("<collection name>", { _driver: d });
However, I was dished this error on my server/server.js. I'm using meteor 0.9.2.2
with meteor-platform 1.1.0.
Exception from sub Ep9DL57K7F2H2hTBz Error: A method named '/documents/insert' is already defined
at packages/ddp/livedata_server.js:1439
at Function._.each._.forEach (packages/underscore/underscore.js:113)
at _.extend.methods (packages/ddp/livedata_server.js:1437)
at Mongo.Collection._defineMutationMethods (packages/mongo/collection.js:888)
at new Mongo.Collection (packages/mongo/collection.js:208)
at Function.Documents.getCollectionByMongoUrl (app/server/models/documents.js:9:30)
at null._handler (app/server/server.js:12:20)
at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1594)
at _.extend._runHandler (packages/ddp/livedata_server.js:943)
at packages/ddp/livedata_server.js:737
Can anyone be so kind as to enlighten me whether or not I have made a mistake somewhere?
Thanks.
Br,
Ethan
Edit: This is my server.js
Meteor.publish('userDocuments', function () {
// Get company data store's mongo URL here. Simulate by matching domain of user's email.
var user = Meteor.users.findOne({ _id: this.userId });
if (!user || !user.emails) return;
var email = user.emails[0].address;
var mongoUrl = (email.indexOf('#gmail.com') >= 0) ?
'mongodb://localhost:3001/company-a-db' :
'mongodb://localhost:3001/company-b-db';
// Return documents
return Documents.getCollectionByMongoUrl(mongoUrl).find();
});
and this is the server side model.js
Documents = function () { };
var documentCollections = { };
Documents.getCollectionByMongoUrl = function (url) {
if (!(url in documentCollections)) {
var driver = new MongoInternals.RemoteCollectionDriver(url);
documentCollections[url] = new Meteor.Collection("documents", { _driver: driver });
}
return documentCollections[url];
};
Observation: The first attempt to new a Meteor.Collection works fine. I can continue to use that collection multiple times. But when I log out and login as another user from another company (in this example by using an email that is not from #gmail.com), the error above is thrown.
Downloaded meteor's source codes and peeked into mongo package. There is a way to hack around having to declare different collection names on the mongodb server based on Hubert's suggestion.
In the server side model.js, I've made these adaptation:
Documents.getCollectionByMongoUrl = function (userId, url) {
if (!(userId in documentCollections)) {
var driver = new MongoInternals.RemoteCollectionDriver(url);
documentCollections[userId] = new Meteor.Collection("documents" + userId, { _driver: driver });
documentCollections[userId]._connection = driver.open("documents", documentCollections[userId]._connection);
}
return documentCollections[userId];
};
Super hack job here. Be careful when using this!!!!
I believe Meteor distinguish its collections internally by the name you pass to them as the first argument, so when you create the "documents" collection the second time, it tries to override the structure. Hence the error when trying to create the /documents/insert method the second time.
To work around this, you could apply a suffix to your collection name. So instead of:
new Meteor.Collection('documents', { _driver: driver });
you should try:
new Meteor.Collection('documents_' + userId, { _driver: driver })