How to setup destination in Neo SCP to Cloud Foundry service using OAuth2SAMLBearerAssertion? - s4sdk

I want to consume a CF service in my Neo SCP, using a destination with OAuthSAMLBearerAssertion.
But every time I check for the service in WebIDE, I get error 500.
Here is my destination:
#clientKey= Client-ID of your OAuth client
--> you will get the clientid from environment variables in CF:
--> xsuaa --> credentials --> clientid
#tokenServicePassword= Client secret of your OAuth client
--> you will get the clientsecret from environment variables in CF:
--> xsuaa --> credentials --> clientsecret
#Tue May 21 07:02:37 UTC 2019
Description=CF HANA OData Service
Type=HTTP
TrustAll=true
audience=xyz.aws-live-eu10 (=EntityID out of the SAML metadata)
Authentication=OAuth2SAMLBearerAssertion
WebIDEUsage=odata_gen
Name=cf_xyz_odata_auth
WebIDEEnabled=true
tokenServiceURL=https\://xyz.authentication.eu10.hana.ondemand.com/oauth/token/alias/xyz.aws-live-eu10 (= Token URL out of the SAML metadata)
URL=https\://backend.cfapps.eu10.hana.ondemand.com
ProxyType=Internet
tokenServiceURLType=Dedicated
tokenServiceUser= same as client key
WebIDESystem=CF
Any ideas?

Fixed it:
Problem was that I did had to give the Neo-Account as "allowed provider" in the oauth2-configuration in the xs-security.json and delete/re-start the xsuaa service instance.
"oauth2-configuration": {
"token-validity": 900,
"refresh-token-validity": 1800,
"autoapprove": "true",
"allowedproviders": ["..."],
"grant-types": ["refresh_token", "urn:ietf:params:oauth:grant-type:saml2-bearer", "password", "authorization_code"]
}

Related

Access s3 bucket from other region using java aws-java-sdk

I have s3 bucket from ap-south-1 which I have accessing using aws java sdk
AmazonS3 amazonS3 = AmazonS3ClientBuilder.standard(). withRegion(Regions.AP_SOUTH_1).defaultClient();
awazonS3.putObject(putObjectRequest);
It was working fine when my service is running in "ap-south-1". Now, when I move the service moved to "ap-south-2" reason same code is giving error.
The ap-south-1 location constraint is incompatible for the region specific endpoint this request was sent to. (Service: Amazon S3; Status Code: 400; Error Code: IllegalLocationConstraintException; Request ID: TTTTDW5T2GF0J28S8; S3 Extended Request ID: l3djAuSl5RXWgSLn12gTnyXyF1P7Q60OAMxTNhyrnmIJxIZ2MjRRzmOMT1hsEW6+KjqA=; Proxy: null)
currently i m using
`<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.12.145</version>
</dependency>`
I want to access same bucket of ap-south-1 in ap-south-2
The problem is you are using .defaultClient() which I think ignores the Region you set
Try using .build() instead which Builds a client with the configure properties.
so
AmazonS3 amazonS3 = AmazonS3ClientBuilder
.standard()
.withRegion(Regions.AP_SOUTH_1)
.build();
Note, you can also specify the S3 endpoint explicitly, as follows (but the above code is simpler):
AmazonS3 amazonS3 = AmazonS3ClientBuilder
.standard()
.withEndpointConfiguration(
new EndpointConfiguration("https://s3.ap-south-1.amazonaws.com", "ap-south-1"))
.build();

PublishGCPubSubLite processor in Apache NiFi is not working as expected

We are Using Apache Nifi to Publish events to PubsubLite using (PublishGCPubSubLite 1.17.0) Nifi processor.
GCP SA json files contains below field:
{
"type": "service_account",
"project_id": "",
"private_key_id": "",
"private_key": "",
"client_email": "",
"client_id": "",
"auth_uri": "",
"token_uri": "",
"auth_provider_x509_cert_url": "",
"client_x509_cert_url": ""
}
We tried using type:"service_account" and it is getting failed to communicate. and we are getting the below error,
PublishGCPubSubLite[id=7f9baf80-0184-1000-ffff-ffff8ec321b3] Failed to create Google Cloud PubsubLite Publisher: com.google.api.gax.rpc.UnauthenticatedException: io.grpc.StatusRuntimeException: UNAUTHENTICATED: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
Caused by: io.grpc.StatusRuntimeException: UNAUTHENTICATED: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
From Nifi server we tested the connectivity and credential, it is working:
./google-cloud-sdk/bin/gcloud auth login --cred-file gcp.json
Authenticated with service account credentials for: [#.iam.gserviceaccount.com].
Your current project is [None]. You can change this setting by running:
$ gcloud config set project PROJECT_ID
Please suggest how to make connection to PubsubLite on Apache Nifi

Cognito SAML server-side login

I'm actually trying to auth a server (golang) on a Cognito with an external identity provider configured (Azure AD via SAML).
The Cognito / azure AD connection is working well but I can't figure how to authenticate my server.
I'm working with this small piece of code:
package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
cognito "github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
)
const flowUsernamePassword = "ADMIN_USER_PASSWORD_AUTH"
const AppClientID = "XXXX"
const UserPoolId = "XXXX"
// Login handles login scenario.
func login() {
conf := &aws.Config{Region: aws.String("eu-west-1")}
sess, err := session.NewSession(conf)
CognitoClient := cognito.New(sess)
username := "xxxx#xxxxx.onmicrosoft.com"
password := "XXXX"
params := map[string]*string{
"USERNAME": aws.String(username),
"PASSWORD": aws.String(password),
}
authTry := &cognito.AdminInitiateAuthInput{
AuthFlow: aws.String(cognitoidentityprovider.AuthFlowTypeAdminUserPasswordAuth),
AuthParameters: params,
ClientId: aws.String(AppClientID),
UserPoolId: aws.String(UserPoolId),
}
res, err := CognitoClient.AdminInitiateAuth(authTry)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(res.AuthenticationResult)
}
func main() {
login()
}
Where username and password are my Azure AD user.
I can connect on the test hosted UI on Cognito (so the SAML configuration seems to be ok) but when I'm trying to do the same from my golang app, I'm always ending with that error: NotAuthorizedException: Incorrect username or password. and I can't figure why.
Thanks,
What you are trying to do cannot work. The reason here is - there is no user with such password in your database. The user that is there is a "federated user". Only user's data got synchronized form Azure AD. But the authentication must still happen over Azure AD.
The workflow looks as follow (very simplified):
You authenticate with Azure AD
Azure AD redirects to Hosted UI
Hosted UI retrieves user data from Azure AD (except password, obviously)
You always need to go through Azure AD (or any other federated IDP) if you are using a federated identity provider. You won't be able to directly authenticate with Cognito using the same credentials as you have for your federated IDP.
That's basically the whole point of federated identites.

How to exchange JWT token for Credentials in Cognito Identity Pool in .NET Core 3.1 WebApi

Broad Overview: I am trying to create a .Net Core 3.1 WebApi backend that is authenticated against Amazon Cognito. I want to use the Amazon-hosted sign-in page(s) provided by Cognito. I want to leverage Cognito Identity Pool to provide temporary scoped credentials for users after they have logged in. I cannot figure out how to exchange the Cognito token to create the Credentials to call AWS services.
Technology Overview
.NET Core 3.1 WebApi
Amazon Cognito User Pool for initial authentication
Amazon Identity Pool for defining permissions (Roles) for logged in users
Deployed on AWS via API Gateway + Lambda using the AWS Serverless framework (basically CloudFormation)
Currently both of the following work:
Add [Authorize] attribute to a controller endpoint and access the URL in a browser. This re-directs me to the Cognito-hosted login page and, upon successful login, returns me back to the controller/endpoint and I am authorized.
Create a separate Client application and login to AWS Cognito. Pass the JWT token in the Authorization HTTP header when calling APIs from the client and the Authorization succeeds and API access is granted.
In both cases, the access to the API is permitted however the AmazonServiceClient instances that are created in the WebApi are granted the permissions associated with the Lambda function (which is the proper behavior).
Problem
I need to create AmazonServiceClients whose credentials match the Role defined by the Cognito Identity Pool.
To do this, I need to exchange token provided by logging into Cognito User Pool for temporary credentials in the Identity Pool.
Virtually ALL examples and documentation I can find on this process define how to manually login to Cognito using the API (not the hosted web UI), and then using the API response to create a CognitoUser and then get credentials from the Identity Pool using that user.
The closest (though super brief) documentation I can find to do what I need is from AWS here: https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/cognito-creds-provider.html
// Authenticate user through Facebook
string facebookToken = GetFacebookAuthToken();
// Add Facebook login to credentials. This clears the current AWS credentials
// and retrieves new AWS credentials using the authenticated role.
credentials.AddLogin("graph.facebook.com", facebookAccessToken);
While that example uses Facebook, conceptually it should be the same for any provider (Facebook, Google, Twitter, OpenId, etc.).
My Current Attempt
I have registered CognitoAWSCredentials as a Scoped service as it is user-specific and therefore should only exist as long as the API request session exists.
RegionEndpoint region = Configuration.GetAWSOptions().Region;
services.AddScoped(_ => new CognitoAWSCredentials(Settings.CognitoIdentityPoolId, region));
I have created an event handler that gets triggered when the OpenIdConnect event 'OnTokenValidated' is fired. This happens after I login to the Cognito hosted web UI and am redirected back to my API.
In this handler I can call:
CognitoAWSCredentials creds = services.BuildServiceProvider().GetRequiredService<CognitoAWSCredentials>();
creds.AddLogin( ... ??? ...);
(note: since I'm setting all this up in the Startup.ConfigureServices(IServiceCollection services) method, I am building an IServiceProvider instance each time authentication succeeds... which may be inefficient but I haven't figured out another way to access a scoped service inside the ConfigureServices method)
All this preamble to say that I cannot find a set of values for the AddLogin call which allow this test call to succeed:
ImmutableCredentials immCreds = creds.GetCredentials();
Relevant Data Structures
In the event handler where I can call AddLogin, I have access to: Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenValidatedContext which in particular contains:
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage with:
access_token
id_token
refresh_token
System.IdentityModel.Tokens.Jwt.JwtSecurityToken with:
{
{
"alg": "RS256",
"kid": "**************************"
}. {
"at_hash": "**************************",
"sub": "**************************",
"email_verified": true,
"iss": "https://cognito-idp.ca-central-1.amazonaws.com/**************************",
"cognito:username": "**************************",
"nonce": "**************************",
"aud": "**************************",
"event_id": "**************************",
"token_use": "id",
"auth_time": 1595260191,
"exp": 1595263791,
"iat": 1595260191,
"email": "**************************"
}
}
I have tried using the iss value as the providerName in AddLogin, and either the access_token or id_token but neither work.
Does anyone know what I need to use for AddLogin in order for Cognito to create Identity Pool credentials for me based upon a JWT token from a Cognito User Pool login?
unless I missed it, I haven't seen documentation that states this, but even though all the Issuer fields on the various data structures include the 'https://', you need to strip it before using the Issuer as the providerName on the AddLogin call. ugh.
CognitoAWSCredentials creds = services.BuildServiceProvider().GetRequiredService<CognitoAWSCredentials>();
string shortIssuer = tokenValidatedContext.SecurityToken.Issuer;
if (shortIssuer.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("https://".Length);
if (shortIssuer.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("http://".Length);
creds.AddLogin(shortIssuer, tokenValidatedContext.TokenEndpointResponse.IdToken);
now, the above code has a problem as the services.BuildServiceProvider(). part means the credentials object I modify isn't global (only local to the service provider I built here I think), but that's a different issue - just noting that in case anyone is copying this code.
services...<other authentication setup>...
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.ClientId = Settings.CognitoClientId;
options.MetadataAddress = CognitoMetadataAddress;
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.UsePkce = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidIssuers = new string[] { Settings.CognitoAuthority },
ValidateAudience = true,
ValidAudiences = new string[] { Settings.CognitoClientId }
};
options.Events = new OpenIdConnectEvents() {
OnTokenValidated = tokenValidatedContext => {
CognitoAWSCredentials creds = services.BuildServiceProvider().GetRequiredService<CognitoAWSCredentials>();
string shortIssuer = tokenValidatedContext.SecurityToken.Issuer;
if (shortIssuer.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("https://".Length);
if (shortIssuer.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("http://".Length);
creds.AddLogin(shortIssuer, tokenValidatedContext.TokenEndpointResponse.IdToken);
return Task.CompletedTask;
}
};
})
(some code removed to focus on specifically the OpenId Connect event and the CognitoAWSCredentials init)

Fog/aws gem for IBM Cloud Object Storage is not working

As Softlayer or IBM Cloud has moved from Swift based Object Storage to S3 based Cloud Object Storage. I am using fog/aws instead of fog/softlayer.
The below is the code:
require 'fog/aws'
fog_properties = {
provider: 'AWS',
aws_access_key_id: username,
aws_secret_access_key: api_key
}
#client = Fog::Storage.new(fog_properties)
#client.directories
But it failed even with valid key and id.
<Error><Code>InvalidAccessKeyId</Code><Message>The AWS Access Key Id you provided does not exist in our records.\</Message><AWSAccessKeyId>####</AWSAccessKeyId><RequestId>####</RequestId><HostId>##</HostId></Error>
End Point IBM COS uses is "https://control.cloud-object-storage.cloud.ibm.com/v2/endpoints"
When I tried to use fog alone(require 'fog'). It throws the below error:
Unable to activate google-api-client-0.23.9, because mime-types-2.99.3 conflicts with mime-types (~> 3.0) (Gem::ConflictError)
Please suggest how to resolve these issues.
https://control.cloud-object-storage.cloud.ibm.com/v2/endpoints"
This is not an endpoint but a list of endpoints in JSON.
Choose the endpoint for your bucket location.
For example if your bucket is in us-south the public endpoint is
https://s3.us-south.cloud-object-storage.appdomain.cloud
The following code worked for IBM Cloud Objects Storage
properties = {
region: region,
endpoint: URI('https://s3.us-south.cloud-object-storage.appdomain.cloud'),
credentials: Aws::Credentials.new(access_key_id, secret_access_key)
}
Aws.config.update(properties)
#client = Aws::S3::Client.new
Properties for the config can also be set as ENV variables.
Below are few basic operations performed on COS.
List all the bucker names
#client.list_buckets.buckets.map(&:name)
Create Bucket
#client.create_bucket(bucket: )
Upload a file
#client.put_object(bucket: , key: , body: )
Download a file
#client.get_object(bucket: , key: )
Delete a file
#client.delete_object(bucket: , key: )
Delete a Bucket
#client.delete_bucket(bucket: )

Resources