I have been tasked with integrating an existing JavaScript application with Okta.
This application requires access to certain resources on Amazon's AWS API Gateway. The API-Gateway-generated SDK requires an access key and a secret access key for which we would prefer to use temporary credentials.
According to AWS documentation, an assertion is required to make a call to AWS's AssumeRoleWithSAML in order to retrieve temporary credentials.
I've tried the following Okta resources, but have been unable to determine how to obtain an assertion using JavaScript:
AWS SAML Integration with Okta:
This setup allows for logging in to the AWS Console.
The Okta Sign-in Widget: Using the widget, I've been unable to find an assertion in what is being returned.
Okta API/SDK: A JavaScript API/SDK is not listed.
I have found a few Python implementations that return temporary access keys, but haven't found any examples or documentation describing a JavaScript approach with Okta.
Thank you.
Here is an example application showing how to integrate Okta with Amazon S3 in JavaScript, using the Okta Sign-In Widget: https://github.com/okta/okta-oidc-aws
This example application is based on Amazon's JavaScript in the Browser sample application, but authenticates against Okta using OpenID Connect instead of using Facebook, as Amazon's sample application does.
Please note that the current version of the Okta Sign-In Widget (1.7.0) includes the xhr library which conflicts with Amazon's JavaScript SDK. This will be fixed in version 1.9.0 of the Okta Sign-In Widget, which removes xhr. In the meantime, the example in the okta-oidc-aws repo ships with a custom version of the widget that has xhr disabled.
The GitHub repository for the okta-oidc-aws sample has full details on getting the example working.
At a high level, the important parts are as follows:
Get an OpenID Connect id_token from Okta.
Use the WebIdentityCredentials class to exchange the Okta id_token for an AWS IAM Role. This is known as "Web Identity Federation".
The code that does this is below, and is copied straight from the sample.html file in the example:
AWS.config.credentials = new AWS.WebIdentityCredentials({
RoleArn: AWS_ROLE_ARN,
WebIdentityToken: res.idToken
});
AWS.config.credentials.get(function(err) {
if (err) {
console.log("Error creating AWS Web Identity: " + err);
return;
}
bucket = new AWS.S3({
params: {
Bucket: AWS_S3_BUCKET_NAME
}
});
oktaLoginContainer.style.display = 'none';
uploadDialog.style.display = 'block';
listObjs();
});
Related
I have the line
onst [url] = await blob.getSignedUrl({ action: 'read', expires: Date.now() + 60 * 1000, contentType: mimetype })
When I run my unit-tests with the Firebase storage emulator I got the error:
Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information
How can I use getSignedUrl with Firebase emulator?
When using a blob signed url, use service account credentials instead of the default ADC. Having been said that, you have two options:
You can create a service account that will use the command using the Cloud SDK: gcloud iam service-accounts keys create FILE_NAME.json --iam-account=NAME#PROJECT_ID.iam.gserviceaccount.com; which you can use to call Firebase server APIs from your app server or trusted environment. After creating your service account, you must initialize with a service account key file.
Here's an example java code for initializing:
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json");
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
You can also check the Firebase Service Accounts to help you identify which service account you will use in your project.
Another option is to set the service account key in an environment variables.
For Linux or macOS:
export GOOGLE_APPLICATION_CREDENTIALS="KEY_PATH"
Example is:
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"
For Windows (using powershell):
$env:GOOGLE_APPLICATION_CREDENTIALS="KEY_PATH"
Example is:
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"
Just note that this variable only applies to your current shell session, so if you open a new session, set the variable again.
Update:
In Google Cloud Platform environments, such as Cloud Functions and App Engine, you usually don't provide a keyFilename or credentials during instantiation. In those environments, we call the signBlob API to create a signed URL. As was stated here. In that case, the service account used must have Service Account Token Creator Role.
The Service Account Token Creator Role enables impersonation of service accounts to create OAuth2 access tokens, sign blobs, or sign JWTs. Provide your service account when initializing the client. If using default credentials, then make sure that the Cloud Functions service account must have Service Account Token Creator Role, as it is required when calling the signBlob API if the app is deployed within GCP.
You can further check this github issues comment.
I'm deeveloping an application that uses React (nextjs to be more accurate) and Ruby on rails as my back end. Althought, i'm trying to use AAD as my Identiity provider.
I need to know if my approuch using OIDC it's correct and how to implement it as well.
Following the protocol rules (https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc), the first thing i'm trying, and failing, is to get user sign-in to get the authorization_code and then exchange that to an access_token in my backend.
window.location.assign(
url.build({
host: process.env.NEXT_PUBLIC_AAD_AUTHORITY,
path: "/oauth2/v2.0/authorize",
query: {
response_type: "code id_token",
client_id: process.env.NEXT_PUBLIC_AAD_CLIENT_ID,
scope: "openid https://graph.microsoft.com/.default",
redirect_uri: "http://localhost:3000/callback",
response_mode: "form_post",
nonce: code_challenge,
code_challenge_method: "S256",
code_challenge: code_challenge,
},
})
);
Since i'm using OICD, the response mode must be "form_post" or "fragment".
form_data_request
My problem is that i have no idea how to receive this kind of response, since i'm not using fetch (generates CORS errors) that its it thenable.
So....any thoughts?
Your approach using OIDC is correct because rails fully support OIDC. To implement you need to configure the tenant in Azure AD then register a new app in you tenant Azure Active Directory. Go to Azure portal and click on “App registration” and on “New registration”. Lastly, move to your rails app and then integrate your application with Azure active directory. Here is a complete guide that can direct you.
I am trying to set up a spa javascript app which logs the user into our azure active directory tenant and then retrieves profile information from microsoft graph and calls an azure function written in c# core (my API).
I have separate application registrations set up for my website and the api in azure active directory.
I'm using the MSAL.js library in the javascript spa website and I'm using the newer microsoft identity / v2.0 endpoints.
The SPA app signs into active directory as expected and is able to use the access token to make the call to graph for the profile information. In my azure function I validate the token and this fails with the error "IDX10511: Signature validation failed. Keys tried: ....."
Now if I remove Microsoft graph from the scopes when requesting a token I get a token that when passed to the azure function validates perfectly well but I can no longer retrieve profile data in the spa app?
How do I get both to work?
Its also worth noting that ive tested the tokens with jwt.io and it is also unable to verify the signature when graph is used.
Heres how I'm getting my token:
var msalConfig = {
auth: {
redirectUri: window.location.origin, // forces top level instead of specific login pages - fixes deep link issues.
clientId: "Client ID of the website app", //This is your client ID
authority:
"https://login.microsoftonline.com/my-tennant-guid" //This is your tenant info
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true
}
};
const msalUserAgent = new Msal.UserAgentApplication(msalConfig);
var requestObj = {
scopes: ["User.Read", "api://MyApi/Access"]
};
//when the spa starts up I login using redirects
msalUserAgent.loginRedirect(requestObj);
//then before calling an api I request a token using this method
acquireTokenSilent() {
var promise = msalUserAgent.acquireTokenSilent(requestObj);
return promise;
},
Try specifying the scopes as scopes: ["User.Read"] in the acquireTokenSilent() function.
Since an access token is only valid for one API.
If you need two, call acquireTokenSilent twice with different scopes.
It's okay to specify scopes for two APIs when signing in, but not when getting tokens. A token has an audience that specifies the target API. So you can't use a token for one API against another. And that's why it's only valid for one API.
I'm working on an Office Add-in that currently uses adal to obtain an auth token.
As I want to use the Fabric front end I am changing it to React and I notice that the officer-js-helpers have implemented authenticators that seem to do the same job as the adal library.
Am I correct in this assumption? If so, how do I duplicate this adal config using the office-js-helpers authentication functions:
var adalConfig = {
instance: 'https://login.microsoftonline.com/',
tenant: 'myprivatesite.onmicrosoft.com',
clientId: 'xxx-xxx-xxx-xxx-xxx',
endpoints: {
'https://my.private.url.endpoint/path': 'https://myprivatesite.onmicrosoft.com/path.to.something',
}
And this token request:
var authContext = new AuthenticationContext(adalConfig);
authContext.acquireToken('https://myprivatesite.onmicrosoft.com/path.to.something', function (error, token) {
console.log(token)
});
UPDATE:
I have got the adal.js library working in my react app. I have used some of the code from the init function in the adalAuthenticationService angular provider to retrieve the authentication token.
So the question remains. Can I use the office-js-helpers to do the same thing?
Adal.js cannot be used out of the box for web add-ins authentication because within the sandboxed iFrame context of a web add-ins you cannot navigate simply to the authentication login page hosted outside your domain.
Office-js-helpers uses the dialogAPI when available and a popup as a fallback solution when not available.
If I remember correctly Office-js-helpers targets only Azure AD v2.0 (which comes with a lot of nice new features comparing to Azure AD). I guess it is a good choice.
I created an Open source sample the documentation can be interesting to you. However, this is not exactly what you want it is based on an AuthorizationCode flow while you are looking for Implicit flow.
OK It appears it is extremely easy. All that is required from the adal configuration is the client Id and the tenant.
if (OfficeHelpers.Authenticator.isAuthDialog()) {
return;
}
var authenticator = new OfficeHelpers.Authenticator();
authenticator.endpoints.registerAzureADAuth('xxx-xxx-xxx-xxx-xxx', //clientId
'myprivatesite.onmicrosoft.com' // tenant
);
authenticator.authenticate(OfficeHelpers.DefaultEndpoints.AzureAD)
.then(function (token) {
console.log(token);
.catch(function(error) {
console.log(error);
});
I am using the Azure node.js SDK. https://azure.microsoft.com/en-us/develop/nodejs/
Strangely I cannot find documentation for starting a virtual machine on Azure using the node.js SDK.
I need a clear example of how to launch an Azure virtual machine using the node.js SDK.
Also I need reference documentation that specifies all the optional parameters for launching a Virtual Machine using the node.js SDK.
Here's one example.
var startVirtualMachine = async function(resourceGroup, vmName){
try {
let credential = await msRestAzure.loginWithServicePrincipalSecret(process.env.AZURE_CLIENT_ID, process.env.AZURE_APPLICATION_SECRET, process.env.AZURE_TENANT);
computeClient = new ComputeManagementClient(credential, process.env.AZURE_SUBSCRIPTION_ID);
await computeClient.virtualMachines.start(resourceGroup, vmName);
return true;
} catch (error) {
throw error;
}
}
You can use the REST API to manage your VM. To start a VM, it's here. There is no options though.
You can then use request for example to issue your POST request.
As I known, you can use the Virtual Machine REST API of Azure Resource Management to start your VM with the parameters subscription-Id, resource-group-name & vm-name, please move to the doc https://msdn.microsoft.com/en-us/library/azure/mt163628.aspx to know the start API for Azure VM.
Note: the api-version required is 2015-06-15
The API with POST request need to be authenticated via set up request header Authorization: Bearer <access token>.
For requesting access token, you can refer to the offical sample code https://github.com/AzureAD/azure-activedirectory-library-for-nodejs/blob/master/sample/client-credentials-sample.js to get the token from the code tokenResponse.accessToken.
Or you can use the function VirtualMachineOperations.start of the node package azure-arm-compute to start VM with the same parameters above, please refer to the doc http://azure.github.io/azure-sdk-for-node/azure-arm-compute/latest/.