AngularJS + ADAL.JS set Resource ID (Audience) - javascript

How can I use adal.js in AngularJS to get a bearer token for the audience https://management.azure.com from my javascript code?
I have created a Client application in the AD and set its permissions to allow it to access the "Windows Azure Service Management API". My angularjs code is as follows:
adalService.init(
{
instance: "https://login.windows.net/",
tenant: "<something>.onmicrosoft.com",
clientId: "<some id>",
cacheLocation: 'localStorage',
redirectUri: 'http://localhost:63691/index.html#/configure',
endpoints: {
/* 'target endpoint to be called': 'target endpoint's resource ID' */
'https://management.azure.com/subscriptions?api-version=2014-04-01': 'https://management.azure.com/'
}
},
$httpProvider
);
If I use the token received by this adalService in POSTMAN to call https://management.azure.com/subscriptions?api-version=2014-04-01, I get the following error:
The access token has been obtained from wrong audience or resource '<some id>'.
It should exactly match (including forward slash) with one of the allowed audiences 'https://management.core.windows.net/','https://management.azure.com/'.

Okay so I found the solution after going through the source code of ADAL.JS here. At line 137, it looks at config.loginResource to see if it has been set when passing the config object to the init() function.
Putting it out there for anyone getting stuck:
If you need your token to have the claim for “https://management.azure.com/” (or any other resource URI), you can set the audience when initializing the AuthenticationContext like so:
app.config(['$routeProvider', '$httpProvider', 'adalAuthenticationServiceProvider', function ($routeProvider, $httpProvider, adalService) {
adalService.init(
{
instance: "https://login.microsoftonline.com/",
tenant: "<something>.onmicrosoft.com",
clientId: "<client-id>",
cacheLocation: 'localStorage', //optional
redirectUri: '<redirect-uri>',
loginResource: 'https://management.azure.com/' //to set AUDIENCE
},
$httpProvider
);
}]);

Related

AWS EC2 IAM Role Credentials not passed into Node.js application

I am developing a Node.js application which is deployed on an EC2 instance. I am using the AWS SDK for JavaScript. I have tried both v2 and v3. My problem is that whenever I make a call to any AWS service in my application, I get an error saying that the credentials are missing. However, according to the documentation, assigning an IAM role to the EC2 instance should enable the SDK to automatically retrieve the credentials: AWS Documentation. I believe that I have correctly added the IAM role with sufficient permissions to the EC2 instance so I don't understand why the requests are not going through. I do not want to use Environment variables as I would have to manually use them in my code then. Any suggestions of how to debug this issue or thoughts what the problem might be, are greatly appreciated.
For example, a call is made as follows:
const client = new CloudFormationClient({ region: "eu-central-1" });
const params = {
StackStatusFilter: [
"CREATE_IN_PROGRESS"
]
};
const command = new ListStacksCommand(params);
client.send(command).then(
(data) => {
console.log(data);
},
(error) => {
console.log(error);
}
);
The error is simply: Error: Credential is missing.
This originates from the console.log(error).
In have tried with multiple roles but even with the AdministratorAccess the same error occurs. For reference, the permissions are:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}

How to get Azure AD authentication to work in production with msal-browser in my Next.js application?

The following implementation of msal works without issues when I run it on localhost. But when I deploy it to an Azure App Service the clientId and/or tenantID seems to become undefined, even when I tried experimenting with placing the id strings directly into the file. Here is the error I get when i try to click the login button in production:
GET https://login.microsoftonline.com/undefined/v2.0/.well-known/openid-configuration 400 (Bad Request)
Uncaught (in promise) ClientAuthError: endpoints_resolution_error: Error: could not resolve endpoints. Please check network and try again. Detail: ClientAuthError: openid_config_error: Could not retrieve endpoints. Check your authority and verify the .well-known/openid-configuration endpoint returns the required endpoints. Attempted to retrieve endpoints from: https://login.microsoftonline.com/undefined/v2.0/.well-known/openid-configuration
at t [as constructor] (_app-3866deb516d5bf6f9628.js:1)
at new t (_app-3866deb516d5bf6f9628.js:1)
at Function.t.createEndpointDiscoveryIncompleteError (_app-3866deb516d5bf6f9628.js:1)
at Function.<anonymous> (_app-3866deb516d5bf6f9628.js:1)
at _app-3866deb516d5bf6f9628.js:1
at Object.throw (_app-3866deb516d5bf6f9628.js:1)
at s (_app-3866deb516d5bf6f9628.js:1)
And here is the msal implementation:
import * as msal from "#azure/msal-browser";
function redirUri() {
if (process.env.NODE_ENV == "development") {
return "/"
} else {
return "https://somewebsitename.azurewebsites.net/"
}
}
const msalConfig = {
auth: {
clientId: process.env.NEXT_PUBLIC_AZURE_AD_CLIENT_ID,
authority: `https://login.microsoftonline.com/${process.env.NEXT_PUBLIC_AZURE_AD_TENANT_ID}`,
redirectUri: redirUri()
}
};
const msalInstance = new msal.PublicClientApplication(msalConfig);
export { msalInstance }
What is the correct way to do this?
You can't get the app setting in Azure app service configuration.
You can get the ClientID and tenant Id from your application configuration by doing this.
process.env.clientId and process.env.tenantId
Ensure you have configured the following settings on the portal:

using passport-azure-ad configuration to secure a web app and web server via OIDCStrategy and BearerStrategy

I have a web app that is provided by an express.js server (web app server). The web app server handles the user login via passport.js and the passport-azure-ad npm package. I am using the OIDCStrategy for this.
I am also hosting a REST api via another server (rest backend). I want to secure this backend via passport.js and the passport-azure-ad npm package using the BearerStrategy. For that I want to define a scope in the web app server passport configuration so that the access_token of the web app server can be passed via a cookie to my web app and from there be used to access the rest backend.
My issue: with my current configuration, I receive 401 access denied while trying to access my backend api with the access_token. access_token invalid is the error message: {"name":"AzureAD: Bearer Strategy", "msg":"authentication failed due to: error: invalid_token","v":0}
I think I should be redirected to a permission page while signing in but it does not. So I guess my access token is actually not valid.
Web app server passport configuration:
passport.use(
new OIDCStrategy(
{
clientID: credsAzureAD.clientID,
identityMetadata: credsAzureAD.identityMetadata, // here is use the web app tenant id
clientSecret: credsAzureAD.clientSecret,
callbackURL: credsAzureAD.returnURL,
redirectUrl: credsAzureAD.returnURL,
skipUserProfile: true,
responseType: 'code',
responseMode: 'query',
scope: 'api://test/Write.Contributor',
useCookieInsteadOfSession: false,
passReqToCallback: false
},
(issuer, sub, profile, accessToken, refreshToken, done) => {
user.accessToken = accessToken;
return done(null, user);
}
)
);
I try to use the scope where api://test is my REST API application ID uri and /Write.Contributor is the scope that I defined in azure active directory.
My REST backend server passport configuration:
const options = {
identityMetadata: azureAD.identityMetadata, // here I use the backend server tenant id
clientID: azureAD.clientID,
issuer: azureAD.issuer, // here I use the backend server tenant id
passReqToCallback: false,
};
const bearerStrategy = new BearerStrategy(options, function(token, done) {
done(null, {}, token);
});
I have created my backend server in azure active directory via application registration and created the named scope and application id above. I also have whitelisted my web app clientId there as a authorized client applications.
I try to call following route and receive 401:
app.get(
'/testtest',
cors(),
passport.authenticate('oauth-bearer', { session: false }),
function(req, res) {
var claims = req.authInfo;
console.log('User info: ', req.user);
console.log('Validated claims: ', claims);
res.status(200).json({ name: claims['name'] });
}
);
This is my rest call from my vue web app:
let headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${this.user.accessToken}`,
'cache-control': 'no-cache'
};
const apiClient = axios.create({
baseURL,
headers
});
apiClient.get('/testtest').then( resp => console.log( resp));
I am taken the access token as is no decoding/encoding.
Any support would be very much appreciated. Thank you!
As #Jim Xu suggested in the comments, adding the application scope of the REST api to the client application via Azure Portal helped solving the issue. But I was also using the wrong token.
instead of using the accessToken from the verify function parameter list, I now use the param from the verify function parameter list.
(iss, sub, profile, access_token, refresh_token, params, done) => {
// access_token did not work
// id_token can be used as an accessToken
user.accessToken = params.id_token;
...
}

Is aws-amplify with auth broken?

I am trying to build a react app which will use the aws hosted ui for authentication. I am trying to use aws-amplify to achieve this, and so far I am having no such luck.
Here the docs state that the auth config should look like this.
const oauth = {
domain : 'your-domain-prefix.auth.us-east-1.amazoncognito.com',
scope : ['phone', 'email', 'profile', 'openid','aws.cognito.signin.user.admin'],
redirectSignIn : 'http://www.example.com/signin/',
redirectSignOut : 'http://www.example.com/signout/',
responseType: 'code',
}
But when I use this config setup I get the following error.
The parameters: App client Id, App web domain, the redirect URL when
you are signed in and the redirect URL when you are signed out are
required.
As you can see, those params are clearly supplied. So I clicked on the source map file linked in my console with the error message, and saw this.
if (data == null || !ClientId || !AppWebDomain || !RedirectUriSignIn || !RedirectUriSignOut) {
throw new Error(this.getCognitoConstants().PARAMETERERROR);
}
Which makes it seem more like the config should look a little something like this.
const auth = {
AppWebDomain: "aaaaa",
TokenScopesArray: ["phone", "email", "profile", "openid", "aws.cognito.signin.user.admin"],
RedirectUriSignIn: "http://localhost:3000",
RedirectUriSignOut: "http://localhost:3000",
responseType: "token",
ClientId: "aaa",
UserPoolId: "aaa",
};
But when doing this, and trying to send the user to the hosted ui as the docs say here I get this error.
Uncaught TypeError: Cannot read property 'domain' of undefined
Once again I looked at the source and found this.
var domain = config.domain,
Which makes it seem like its expecting the config which does not work.
At this point I am really lost and can use any help at all.
Going through the Auth.ts code, it appears that you have to include the userPoolId and userPoolWebClientId fields, in addition to oauth. Here's how I got it to work:
const oauth = {
domain: 'XXXXXX.auth.us-west-2.amazoncognito.com',
scope: ['phone', 'email', 'profile', 'openid', 'aws.cognito.signin.user.admin'],
redirectSignIn: 'http://localhost:3000/',
redirectSignOut: 'http://localhost:3000/',
responseType: 'code'
};
Auth.configure({
oauth: oauth,
region: 'us-west-2',
userPoolId: 'us-west-2_XXXXXXXXX',
userPoolWebClientId: 'XXXXXXXXXXXXXXXXXXXXXXXXXX'
});

auth0 cannot read poperty options of undefined

I try to get auth0 running on a simple react app.
I create a auth0 object with the folling parameter:
this.auth0 = new auth0.WebAuth({
domain: AUTH_CONFIG.domain,
clientID: AUTH_CONFIG.clientId,
redirectUri: AUTH_CONFIG.redirectUri,
audience: `https://${AUTH_CONFIG.domain}/userinfo`,
responseType: AUTH_CONFIG.responseType,
scope: AUTH_CONFIG.scope,
});
after I logg in on the Auth0 website and get redirected to my callback url I get the error
cannot read poperty of undefined
I just cant figer out where this error located.
In my Applcation in auth0 i configured: Allowed Callback URLs: http://localhost:3000/callback

Categories