Why does NewStaticCredentials return a blank Credentials object? - aws-sdk-go

I am trying to read S3 objects in Account A from Account B.
I am able to assume a role in Account B and retrieve sts.Credentials object.
stsClient := sts.New(session.Must(session.NewSession()))
params := &sts.AssumeRoleInput{
RoleArn: aws.String(roleArn),
RoleSessionName: aws.String("role-session-name"),
}
stsResp, err := stsClient.AssumeRole(params)
checkErr(err)
// stsResp.Credentials.AccessKeyId = ASIA...
// stsResp.Credentials.SecretAccessKey = abc...
// stsResp.Credentials.SessionToken = xyz...
I then have to convert sts.Credentials object to a credentials.Credentials object in order to use it in
s3Client := s3.New(session.Must(session.NewSession()), &aws.Config{Credentials: creds})
However, when I do:
creds := credentials.NewStaticCredentials(*stsResp.Credentials.AccessKeyId, *stsResp.Credentials.SecretAccessKey, *stsResp.Credentials.SessionToken)
creds for some reason is a pointer to an empty credentials.Credentials object:
&{creds:{AccessKeyID: SecretAccessKey: SessionToken: ProviderName:} forceRefresh:true m:{state:0 sema:0} provider:0xc4201a2840}
I have also tried:
values, err := creds.Get()
checkErr(err)
fmt.Println(values) // prints out credentials values as expected
So, it's not quite clear to me why credentials.NewStaticCredentials() returns an empty credentials object.

When printing out the credentials.Credentials value returned by credentials.NewStaticCredentials() the creds value you see printed is the cached AWS credentials stored in the Credentials type that has not been populated yet. This field is populated when Credentials.Get is called. The value is invalid prior to Get being called.
The NewStaticCredentials will create a StaticProvider value which satisfies the Provider interface. The Credentials type will use the Provider.Retrieve() method to retrieve the latest credential Values from the Provider. The Credentials type will cache the creds response from Retrieve() until the Provider flags the credentials as expired. In the case of StaticProvider the credentials never expire.
This is why creds.Get() returns the values without an error. If you were to print creds after Get was called you'd see the cached static values in the Credentials type.

Related

Graphene JWT authentication

I'm using graphene-jwt to authenticate user but my user has to multiple object return
here
def mutate(cls, root, info, **kwargs):
result = super().mutate(root, info, **kwargs)
...
How can I add additional query to 'filter' more like User.object.filter(user_type=3)? cause currently my code is like this
except (MultipleObjectsReturned, JSONWebTokenError) as e:
users = models.User.objects.get(email=kwargs.get("email"), user_type_id=3)
result = cls(
user=users,
errors=[Error()],
account_errors=[],
token=get_token(users))
user = result.user
I do get token even my password is wrong, it should be failed when the password is wrong.
Thanks

How to obtain an access token within a Keycloak SPI?

Use case:
From inside a EventListenerProvider on an event I want to make an authenticated REST call to one of our keycloak secured service. For this I need a token.
First I just test printing the token to check whether it is succeeded.
public void onEvent(final Event event) {
Keycloak k = Keycloak.getInstance("http://localhost:8080/auth", "myrealm", "myemail#gmail.com", "password", "myclient");
AccessTokenResponse t = k.tokenManager().getAccessToken();
logger.info(t.getSessionState());
logger.info(t.getToken());
}
Unfortunatly both the session_state and token is NULL.
All the data are correct, the url,the realm..etc. Otherwise we would know about that. Keycloak doesnt log anything just silently returns null.
On the top of that I can use the above code from anywhere else and it works! I can use it from a plain java main() method and still works. Getting token by hand via postman also works.
What is wrong with the Keycloak Provider? How can I get an accesstoken for a particular user?
You can use the following example to create a AccessToken:
public String getAccessToken(UserModel userModel, KeycloakSession keycloakSession) {
KeycloakContext keycloakContext = keycloakSession.getContext();
AccessToken token = new AccessToken();
token.subject(userModel.getId());
token.issuer(Urls.realmIssuer(keycloakContext.getUri().getBaseUri(), keycloakContext.getRealm().getName()));
token.issuedNow();
token.expiration((int) (token.getIat() + 60L)); //Lifetime of 60 seconds
KeyWrapper key = keycloakSession.keys().getActiveKey(keycloakContext.getRealm(), KeyUse.SIG, "RS256");
return new JWSBuilder().kid(key.getKid()).type("JWT").jsonContent(token).sign(new AsymmetricSignatureSignerContext(key));
}
Note that you also need to specify <module name="org.keycloak.keycloak-services"/> in your jboss-deployment-structure.

Credentials for HTTP requests from built-in Apama runtime in Cumulocity

I'm using Apama v10.3.1. I'm using the built-in Apama container of a Cumulocity installation, that is all I'm uploading is a monitor, not an entire Apama project. In my Apama monitor I'm executing an HTTP GET request against the Cumulocity REST API to obtain additional parameters I need for my monitor processing.
My problem is that when executing the HTTP request I need to provide a user and password, otherwise I get a 401 error. Since I do not want to hard code the user and password in my monitor, is there any way to use the credentials the built-in Apama container uses for communicating with Cumulocity? Since Apama communicates with Cumulocity under the hood for exchanging events, measurements and alike, I would assume that there are credentials available somewhere. Is that the case and if so, how can I tell my Apama monitor to use these credentials?
Here is an extract of the code:
monitor SampleAlarmRules {
action onload() {
monitor.subscribe(Alarm.CHANNEL);
monitor.subscribe(FindManagedObjectResponse.CHANNEL);
on all Alarm(type = "ax_UnavailabilityAlarm") as a {
onAlarm(a.source);
}
}
action onAlarm(string source) {
integer reqId := integer.getUnique();
send FindManagedObject(reqId, source, new dictionary<string,string>) to FindManagedObject.CHANNEL;
on FindManagedObjectResponse(reqId = reqId) as resp
and not FindManagedObjectResponseAck(reqId) {
ManagedObject dev := resp.managedObject;
dictionary<string, string> httpConfig := {
HttpTransport.CONFIG_AUTH_TYPE:"HTTP_BASIC"
//HttpTransport.CONFIG_USERNAME:"someUser",
//HttpTransport.CONFIG_PASSWORD:"somePassword"
};
HttpTransport httpTransport := HttpTransport.getOrCreateWithConfigurations("someBaseUrl", 80, httpConfig);
Request request := httpTransport.createGETRequest("/inventory/managedObjects/5706999?withParents=true");
request.execute(handleResponse);
}
}
action handleResponse(Response response) {
JSONPlugin json := new JSONPlugin;
if response.isSuccess(){
switch (response.payload.data as payload) {
case string: {
}
default: {
}
}
}
else {
print "###Request failed. Response status is: " + response.statusCode.toString() + " | " + response.statusMessage;
}
}
}
With this configuration (user and password commented) I get the following print statement:
Request failed. Response status is: 401 | Unauthorized
When enabling the user and password, the request executes successfully. However, I do not want to hard code the user and password in here.
Also, is there a way to get the current tenant from an environment variable or anything like that so that I don't have to hard code the base URL?
Thanks
Mathias
Yes, it is possible to do that because Cumulocity passes these as environment variables to all microservice including the Apama microservice.
You should be able to use the com.apama.correlator.Component event to access the environment variables. Use
Component.getInfo("envp") to get the dictionary of environment properties and then lookup the interested variables. You can see the list of environment variables at http://www.cumulocity.com/guides/reference/microservice-runtime/#environment-variables
So for your use case something like following will work:
using com.apama.correlator.Component;
...
monitor test {
action onload() {
dictionary<string,string> envp := Component.getInfo("envp");
dictionary<string, string> httpConfig := {
HttpTransport.CONFIG_AUTH_TYPE:"HTTP_BASIC",
HttpTransport.CONFIG_USERNAME:envp["C8Y_USER"],
HttpTransport.CONFIG_PASSWORD:envp["C8Y_PASSWORD"]
};
HttpTransport httpTransport := HttpTransport.getOrCreateWithConfigurations("someBaseUrl", 80, httpConfig);
Request request := httpTransport.createGETRequest("/inventory/managedObjects/5706999?withParents=true");
request.execute(handleResponse);
}
}
Similarly, you can access the tenant name using environment variable C8Y_TENANT.
Please note that these environment variables are available only in the cloud. If you want to do the same or test the code locally when using it with Cumulocity transport added by yourself, without changing the code, you can manually define the same environment variables in the run configuration of the Designer so that they are available there as well.

Firebase signInWithCredential failed: First argument "credential" must be a valid credential

I am using the react-native-facebook-login package to log users in. Currently the flow is working well and after the user enters their details, I successfully see an object returned with their information.
When I try and create an account in Firebase with signInWithCredential, I receive the following error message:
signInWithCredential failed: First argument "credential" must be a valid
I can't seem to find a breakdown of how that credential needs to be passed - is it a string, an object, an array etc. Is it just the token or do I need to pass other details (i.e. the provider)?
The credentials object I am currently getting back has:
permission: Array
token: String
tokenExpirationDate: String
userId: String
Any help would be much appreciated - thanks!
Feeling pretty pleased - finally cracked the nut.
They key bit is the token needs to be changed first before being a relevant credential. See code below:
onLogin={function(data){
let token = firebase.auth.FacebookAuthProvider.credential(data.credentials.token);
firebase.auth().signInWithCredential(token)
.then((user) => {
console.log(user)
}).catch((err) => {
console.error('User signin error', err);
});
}}
to answer your question, based on the documentation of firebase:
where GoogleAuthProvider could be any of your setup / supported auth providers
// Build Firebase credential with the Google ID token.
var credential = firebase.auth.GoogleAuthProvider.credential(id_token);
// Sign in with credential from the Google user.
firebase.auth().signInWithCredential(credential).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// ...
});
On a side note, as you are using react-native and firebase, did you already try react-native-firestack? makes a lot of things easier.

How to do authentication using Akka HTTP

Looking for a good explanation on how to do authentication using akka HTTP. Given a route that looks like
val route =
path("account") {
authenticateBasic(realm = "some realm", myAuthenticator) { user =>
get {
encodeResponseWith(Deflate) {
complete {
//do something here
}
}
}
}
}
The documentation outlines a way, but then the pertinent part performing the actual authentication is omitted...
// backend entry points
def myAuthenticator: Authenticator[User] = ???
Where can I find an example implementation of such an authenticator? I have the logic already for authenticating a user given a user name and password, but what i can't figure out is how to get a username/password (or token containing both) from the HTTP request (or RequestContext).
Authenticator is just a function UserCredentials => Option[T], where UserCredentials in case of being (check with pattern matching) Provided have verifySecret(secret) method which you need to safely call and return Some (Some user for example) in case of success, like:
def myAuthenticator: Authenticator[User] = {
case p#Provided(username) =>
if(p.verifySecret(myGetSecret(username))) Some(username) else None
case Missing => None //you can throw an exeption here to get customized response otherwise it will be regular `CredentialsMissing` message
}
myGetSecret is your custom function which gets username and returns your secret (e.g. password), getting it possibly from database. verifySecret will securely compare (to avoid timing attack) provided password with your password from myGetSecret. Generally, "secret" is any hidden information (like hash of credentials or token) but in case of basic authentication it is just a plain password extracted from http headers.
If you need more customized approach - use authenticateOrRejectWithChallenge that gets HttpCredentials as an input, so you can extract provided password from there.
More info about authorization is in scaladocs.