Is the AmazonSecurityTokenService available in DigitalOcean?
I have tried to generate a token but this is the error I get:
The service returned an error with Error Code MethodNotAllowed and
HTTP Body: MethodNotAllowedtx000000000000000135444-0063e479e5-28e12c76-sgp1b28e12c76-sgp1b-sgp1-zg02
Am I doing something wrong or is this function not available in DigitalOcean?
This is my function:
public static async Task<SessionAWSCredentials> GetTemporaryCredentials(string AccessKey, string AccessSecret, string Region)
{
try
{
var config = new AmazonSecurityTokenServiceConfig();
config.ServiceURL = $"{SDR_Core.ClassLibrary.Globals.StorageGlobals.HttpsProtocol}{Region}{SDR_Core.ClassLibrary.Globals.StorageGlobals.DO_Link}";
using (var stsClient = new AmazonSecurityTokenServiceClient(AccessKey, AccessSecret, config))
{
var getSessionTokenRequest = new GetSessionTokenRequest
{
DurationSeconds = 7200 // seconds
};
GetSessionTokenResponse sessionTokenResponse =
await stsClient.GetSessionTokenAsync(getSessionTokenRequest);
Credentials credentials = sessionTokenResponse.Credentials;
var sessionCredentials =
new SessionAWSCredentials(credentials.AccessKeyId,
credentials.SecretAccessKey,
credentials.SessionToken);
return sessionCredentials;
}
}
catch(Exception e)
{
if (e != null)
{
Console.WriteLine($"Temporary Credentials Exception: {e.Message}");
}
return null;
}
}
Related
I'm trying to use Aws4RequestSigner in a VS2015 form to sign a search request to Amazon PAAPI.
https://www.nuget.org/packages/Aws4RequestSigner/
I get this response from the API:
{"__type":"com.amazon.paapi5#IncompleteSignatureException","Errors":[{"Code":"IncompleteSignature","Message":"The request signature did not include all of the required components. If you are using an AWS SDK, requests are signed for you automatically; otherwise, go to https://webservices.amazon.com/paapi5/documentation/sending-request.html#signing."}]}
private async void Form1_Load(object sender, EventArgs e)
{
_accessKey = "x";
_secretKey = "x";
_service = "ProductAdvertisingAPIv1";
_region = "us-east-1";
_requestUri = new Uri("https://webservices.amazon.com/paapi5/searchitems");
var payload = new
{
Keywords = "Harry",
Marketplace = "www.amazon.com",
PartnerTag = "x0d-20",
PartnerType = "Associates",
Resources = new string[] { "Images.Primary.Small", "ItemInfo.Title", "Offers.Listings.Price" },
SearchIndex = "All"
};
string jsonString = JsonConvert.SerializeObject(payload);
var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
var xAmzDate = GetTimeStamp();
content.Headers.Add("content-encoding", "amz-1.0");
content.Headers.Add("x-amz-date", xAmzDate);
content.Headers.Add("x-amz-target", "com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems");
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = _requestUri,
Content = content
};
request.Headers.Host = "webservices.amazon.com";
var contentType = new MediaTypeHeaderValue("application/json");
contentType.CharSet = "utf-8";
request.Content.Headers.ContentType = contentType;
var signer = new AWS4RequestSigner(_accessKey, _secretKey);
request = await signer.Sign(request, _service, _region);
try
{
var client = new HttpClient();
var response = await client.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
var error = await response.Content.ReadAsStringAsync();
}
// response.EnsureSuccessStatusCode();
txtDisplay.Text = await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException ex)
{
string error = ex.Message;
txtDisplay.Text = error;
}
}
private string GetTimeStamp()
{
return DateTime.UtcNow.ToString("yyyyMMdd\\THHmmss\\Z");
}
It could be that the headers are being added incorrectly or Aws4RequestSigner is simply outdated.
Receiving an unauthorized response when trying to remove a user from a workspace (group). I'm using the .Net SDK method DeleteUserAsAdminAsync. I tried the DeleteUserInGroupAsync method with the same result. I've had no trouble retrieving groups, reports, even adding users to groups using the same authentication code shown below. I'm quite stumped.
public async Task<ResultObject> RemoveUsersFromWorkspaces(List<PowerBIWorkspace> powerBIWorkspaces)
{
// Authenticate using created credentials
AuthenticationResult authenticationResult = null;
authenticationResult = await DoAuthentication("CustomerAppRegistration");
var tokenCredentials =
new TokenCredentials(authenticationResult.AccessToken, "Bearer");
using (var client = new PowerBIClient(
new Uri("https://api.powerbi.com/"), tokenCredentials))
{
try
{
foreach (var wksp in powerBIWorkspaces)
{
// Remove the user to the workspace.
await client.Groups.DeleteUserAsAdminAsync(new Guid(wksp.WorkspaceId), wksp.UserEmail);
}
}
catch (Exception ex)
{
var errorObject = new ResultObject();
errorObject.Success = false;
errorObject.ErrorMessage = ex.Message;
return errorObject;
}
}
var resultObject = new ResultObject();
resultObject.Success = true;
resultObject.ErrorMessage = "";
return resultObject;
}
private const string AuthorityFormat = "https://login.microsoftonline.com/{0}/v2.0";
private const string MSGraphScope = "https://analysis.windows.net/powerbi/api/.default";
private async Task<AuthenticationResult> DoAuthentication(string appRegistrationSection)
{
var config = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json").Build();
//var section = config.GetSection(nameof(AppRegistration));
var section = config.GetSection(appRegistrationSection);
var appRegistration = section.Get<AppRegistration>();
TenantID = appRegistration.TenantId;
ClientID = appRegistration.ClientId;
ClientSecret = appRegistration.ClientSecret;
IConfidentialClientApplication daemonClient;
daemonClient = ConfidentialClientApplicationBuilder.Create(ClientID)
.WithAuthority(string.Format(AuthorityFormat, TenantID))
.WithClientSecret(ClientSecret)
.Build();
AuthenticationResult authResult =
await daemonClient.AcquireTokenForClient(new[] { MSGraphScope }).ExecuteAsync();
return authResult;
}
CredentialProfile basicProfile;
AWSCredentials awsCredentials;
var sharedFile = new SharedCredentialsFile();
if (sharedFile.TryGetProfile("ride-name", out basicProfile) && AWSCredentialsFactory.TryGetAWSCredentials(basicProfile, sharedFile, out awsCredentials))
{
using (var client = new AmazonS3Client(awsCredentials, basicProfile.Region))
{
var response = await client.ListBucketsAsync();
Console.WriteLine($"Number of buckets: {response.Buckets.Count}");
}
}
I am tring to read my s3 bucket object from EKS cluster application method as listed below.
[HttpGet("ReadFromS3")]
[ProducesResponseType(typeof(ApiResponse<string>), 200)]
[ProducesResponseType(500)]
public async Task<String> ReadFromS3()
{
AmazonS3Config config = new AmazonS3Config { RegionEndpoint = RegionEndpoint.EUWest2 };
string aws_tokenFile = Environment.GetEnvironmentVariable("AWS_WEB_IDENTITY_TOKEN_FILE");
string aws_rolw_arn = Environment.GetEnvironmentVariable("AWS_ROLE_ARN");
string logs = string.Empty;
using (var stsClient = new AmazonSecurityTokenServiceClient(new AnonymousAWSCredentials()))
{
logs += "AmazonSecurityTokenServiceClient";
var assumeRoleResult = await stsClient.AssumeRoleWithWebIdentityAsync(new AssumeRoleWithWebIdentityRequest
{
WebIdentityToken = System.IO.File.ReadAllText(Environment.GetEnvironmentVariable("AWS_WEB_IDENTITY_TOKEN_FILE")),
RoleArn = Environment.GetEnvironmentVariable("AWS_ROLE_ARN"),
RoleSessionName = "S3Session",
DurationSeconds = 900
});
if (assumeRoleResult != null)
{
logs += " -> assumeRoleResult";
var credentials = assumeRoleResult.Credentials;
var basicCredentials = new BasicAWSCredentials(credentials.AccessKeyId,
credentials.SecretAccessKey);
logs += " -> BasicAWSCredentials";
using (client = new AmazonS3Client(basicCredentials, RegionEndpoint.EUWest2) )
{
logs += " -> AmazonS3Client";
try
{
GetObjectRequest request = new GetObjectRequest
{
BucketName = bucketName,
Key = keyName
};
GetObjectResponse response = await client.GetObjectAsync(request);
logs += " -> GetObjectAsync";
Stream responseStream = response.ResponseStream;
StreamReader reader = new StreamReader(responseStream);
logs += " -> ResponseStream";
return await reader.ReadToEndAsync();
}
catch (Exception ex)
{
return "Exception in ReadFromS3 :" + ex.Message + logs;
}
}
}
else
{
return "Unable to Connect";
}
}
}
I am getting error at line GetObjectResponse response = await client.GetObjectAsync(request);
Method not found: 'Amazon.Runtime.Internal.Transform.UnmarshallerContext Amazon.Runtime.Internal.Transform.ResponseUnmarshaller.CreateContext
My OWIN Web.API 2 Hosted on EC2 will not authorize a JWT token. I have tested the functionality locally with out a problem but once I publish it out to my docker container hosted on EC2 it responds with a 401. I am using the default RS256 Algorithm and these settings:
var domain = Environment.GetEnvironmentVariable("AUTH0_DOMAIN");
var audience = Environment.GetEnvironmentVariable("AUTH0_CLIENT_IDS");
var keyResolver = new OpenIdConnectSigningKeyResolver(domain);
appBuilder.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] { audience },
TokenValidationParameters = new TokenValidationParameters()
{
ValidAudience = audience,
ValidIssuer = domain,
IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) => keyResolver.GetSigningKey(identifier)
}
});
My Endpoint simply states whether your are authenticated or not.
[Authorize]
[Route("secure")]
public HttpResponseMessage GetSecured()
{
var userId = ClaimsPrincipal.Current.Identity.GetUserId();
return Request.CreateResponse($"Hello, {userId}! You are currently authenticated.");
}
Here is my Startup config:
public void Configuration(IAppBuilder appBuilder)
{
appBuilder.UseCors(CorsOptions.AllowAll); //must be first
Auth0Config.Register(appBuilder);
var httpConfiguration = new HttpConfiguration();
httpConfiguration.MapHttpAttributeRoutes();
UnityConfig.Register(httpConfiguration);
appBuilder.UseWebApi(httpConfiguration);
}
I no longer use the OWIN pipeline but from a previous project here is how I had it configured. It looks like you are using OpenID, I did not. Not sure if this helps.
var issuer = AppSettings.Auth0Domain;
var audience = AppSettings.Auth0ClientID;
var secret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["Auth0ClientSecret"]);
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] {audience},
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
},
Provider = new Auth0AuthenticationProvider()
});
EDIT Added Auth0AuthenticationProvider
public class Auth0AuthenticationProvider : IOAuthBearerAuthenticationProvider
{
private string token;
public Task ApplyChallenge(OAuthChallengeContext context)
{
return Task.FromResult<object>(null);
}
public Task RequestToken(OAuthRequestTokenContext context)
{
token = context.Token;
return Task.FromResult<object>(null);
}
public Task ValidateIdentity(OAuthValidateIdentityContext context)
{
if (string.IsNullOrEmpty(token))
return Task.FromResult<object>(null);
var notPadded = token.Split('.')[1];
var padded = notPadded.PadRight(notPadded.Length + (4 - notPadded.Length % 4) % 4, '=');
var urlUnescaped = padded.Replace('-', '+').Replace('_', '/');
var claimsPart = Convert.FromBase64String(urlUnescaped);
var obj = JObject.Parse(Encoding.UTF8.GetString(claimsPart, 0, claimsPart.Length));
// simple, not handling specific types, arrays, etc.
foreach (var prop in obj.Properties().AsJEnumerable())
{
switch (prop.Name)
{
case "app_metadata":
SetAppMetadataClaims(context, prop.Value.ToString());
break;
}
}
return Task.FromResult<object>(null);
}
private static void SetAppMetadataClaims(OAuthValidateIdentityContext context, string jsonString)
{
var appMetadata = JsonConvert.DeserializeObject<Auth0AppMetaDataModel>(jsonString);
if(!context.Ticket.Identity.HasClaim("AccountId", appMetadata.accountId.ToString()))
context.Ticket.Identity.AddClaim(new Claim("AccountId", appMetadata.accountId.ToString()));
if (!context.Ticket.Identity.HasClaim("ClientId", appMetadata.clientId.ToString()))
context.Ticket.Identity.AddClaim(new Claim("ClientId", appMetadata.clientId.ToString()));
if (!context.Ticket.Identity.HasClaim("IsActive", appMetadata.isActive.ToString()))
context.Ticket.Identity.AddClaim(new Claim("IsActive", appMetadata.isActive.ToString()));
if (appMetadata.roles == null)
return;
foreach (var role in appMetadata.roles)
{
if (context.Ticket.Identity.HasClaim(ClaimTypes.Role, role))
continue;
context.Ticket.Identity.AddClaim(new Claim(ClaimTypes.Role, role));
}
}
}
The problem was not with Auth0 using HS256 or RS256 but instead with the base image I was using. Mono was failing silently most likely blocking the validation of my token. I have switched over to dotnet core in order to use the docker image: microsoft/dotnet:latest
My Startup file now appears like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCors("CorsPolicy");
var options = new JwtBearerOptions
{
Audience = Configuration["Auth0:ApiIdentifier"],
Authority = $"https://{Configuration["Auth0:Domain"]}/"
};
app.UseJwtBearerAuthentication(options);
...
}