React + rails Application AAD and OpenID connect - javascript

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.

Related

Microsoft login isn't returning refresh token

I am trying to create an integration between my application and Microsoft calendar,
I have a page which allows the user to connect his account with my App
using the following code
const msalInstance = new msal.PublicClientApplication({
auth: {
clientId: '<client-id>',
},
});
msalInstance.loginRedirect({
scopes: ['user.read', 'calendars.readwrite', 'offline_access', 'openid'],
grant_type: 'authorization_code',
});
The login is working and returns token and I can create an event easily
But the token expires after 1 hour, and the response doesn't contain a refresh token
Is there a way to generate a refresh token, or create a token that will stay active for a longer period.
Because I want the user to login once and just create an integration between my app and azure.
Same as the outlook calendar for slack.
my azure application has the needed API permissions
openid offline_access am I missing something?
as https://stackoverflow.com/users/519348/tzhx mentioned, it was the MSAL JS library that caused the issue
I handled the login manually and I was able to see the refresh token.
Thanks.

auth0 access token doesn't show issuer details

We recently added auth0 for integrating SSO from different oauth2 providers (e.g. contoso1.auth.com and contoso2.auth.com)
https://auth0.com/docs/quickstart/spa/angular/01-login
I followed the above link and Our front end app successfully integrated this in the code and able to signin and get the token.
{
"iss": "https://TENANT_NAME.auth0.com/",
"sub": "auth0|SOME_HASH",
"aud": [
"https://API_IDENTIFIER",
"https://TENANT_NAME.auth0.com/userinfo"
],
"iat": 1563699940,
"exp": 1563786340,
"azp": "SOME_OTHER_HASH",
"scope": "openid profile email"
}
In our angular app we want to render ui (show or hide links based on which authentication(contoso1/contoso2) user has gone through. But auth0 accesstoken doesn't give any details about the issuer "iss" (e.g.contoso1.auth.com or contoso2.auth.com)
We cannot rely on the email to say which SSO user belongs to as in our case contoso1 and contoso2 can have users from each others system with their own email ids.
After spending sometime on auth0 page i realized we have a field "connection" in the datacontext of auth0 object and it stores the name . While we can use this as a temporary workaround we can't rely on this determine which SSO flow user signed in with.
{
tenant: "identity-dev"
clientID: "fdsfsdf-dfsdfsd8989",
clientName: "Angualr Portal",
clientMetadata: "{}"
connection : "contoso1-backchannel",
connectionStrategy:"oidc"
....more
}
Please let me know how we can fetch iss or issuer url details in the token.
Is it a requirement to get this info using the frontend only?
As per this Auth0 article, it is a bit easier if you have a backend in place:
If your code runs in the backend, then we can assume that your server is trusted to safely store secrets (as you will see, we use a secret in the backend scenario).
With the backend you will be able to retrieve and parse the identities array user.identities[i].provider, which clearly identifies the original issuer under provider and connection keys.
If using only a frontend, it is more work and you need to build a proxy:
When working with a frontend app, the process for calling IdP APIs differs from the backend process because frontend apps are public applications that cannot hold credentials securely. Because SPA code can be viewed and altered, and native/mobile apps can be decompiled and inspected, they cannot be trusted to hold sensitive information like secret keys or passwords.
The quoted article contains links in the "Show me how" box that might be of further interest in this regard.
From your post it seems to be that only a frontend is used, but I included info about the backend in case it is worth your while to implement a small backend, if purely to just make retrieving the identity provider a bit easier.

How to Get a valid access token for my API and Microsoft Graph from Azure Active Directory?

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.

Microsoft Graph API 401 when accessing calendar events

I'm currently trying to create a basic website to run locally on a raspberry pi that shows me my outlook calendar for the day. However, when I try and access the https://graph.microsoft.com/v1.0/me/events endpoint, I get a 401 unauthorized error.
This is for a simple node.js express server, with all of the code for interacting with the graph api coming from the javascript quickstart app provided by Microsoft. The quickstart app works fine, and I'm able to see the json response for the https://graph.microsoft.com/v1.0/me endpoint that is part of the demo, but changing the endpoint causes a 401.
I've made sure in the azure app registration page that I've enabled the Calendar.read permission, and in my app I've added the calendar.read permission to my scope. When I login, the login popup window asks for permission to read my calendar which to me says that the app should have access to my calendar.
My application configuration (again based off of the quickstart app) looks like this:
const applicationConfig = {
clientID: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
authority: 'https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
graphScopes: ['calendars.read', 'tasks.read'],
graphEndpoint: 'https://graph.microsoft.com/v1.0/me/events',
};
Other than these changes, the rest of the code is identical to the sample code.
You should also include User.Read in your scopes. From the documentation on User.Read:
Allows users to sign-in to the app, and allows the app to read the profile of signed-in users. It also allows the app to read basic company information of signed-in users.
const applicationConfig = {
clientID: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
authority: 'https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
graphScopes: ['Users.Read', 'Calendars.Read', 'Tasks.Read'],
graphEndpoint: 'https://graph.microsoft.com/v1.0/me/events',
};

Okta integration with JavaScript

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();
});

Categories

Resources