I want to allow my users to access my WebApp using their Office 365 account in the same way that I already did with Twitter, Facebook and google.
I have already created a WebApp in Azure AD.
I'am using nodejs, passportjs and passport-azure-oauth2 strategy.
In Azure AD, the Web application is Multitenant and the SIGN-ON URL IS "https://nudniq.com"
APP ID URI: "https:\nudniq.com"
Reply URL: "https:\nudniq.comauth\microsoft\callback"
User Assignment required to access app: NO
Note: I'am using back shlashes instead of slashes in the URL's posted here because stackoverflow only allows me to write no more than two links.
The only permision that I ask for is:
Read all users' basic profiles
I'am creating my strategy with this values:
clientID: '<client_id>',
clientSecret: '<client_secret_key>',
callbackURL: 'https://nudniq.com/auth/microsoft/callback'
But I receive the following error:
TokenError: AADSTS50001: Resource identifier is not provided.
Trace ID: 95f88f5a-95b9-4d3a-86fe-19ae0bbfcc76
Correlation ID: b056150c-debd-469d-963b-ea362ca93884
Timestamp: 2016-06-29 01:38:39Z
at AzureOAuth2.OAuth2Strategy.parseErrorResponse (/home/ec2-user/test2/fastpass/node_modules/passport-oauth2/lib/strategy.js:298:12)
at AzureOAuth2.OAuth2Strategy._createOAuthError (/home/ec2-user/test2/fastpass/node_modules/passport-oauth2/lib/strategy.js:345:16)
at /home/ec2-user/test2/fastpass/node_modules/passport-oauth2/lib/strategy.js:171:43
at /home/ec2-user/test2/fastpass/node_modules/oauth/lib/oauth2.js:177:18
at passBackControl (/home/ec2-user/test2/fastpass/node_modules/oauth/lib/oauth2.js:123:9)
at IncomingMessage.<anonymous> (/home/ec2-user/test2/fastpass/node_modules/oauth/lib/oauth2.js:143:7)
at IncomingMessage.emit (events.js:129:20)
at _stream_readable.js:908:16
at process._tickDomainCallback (node.js:381:11)
Please help me, I dont know what am I doing wrong.
If you are use AzureOAuthStrategy strategy, when you occur this issue, it means you have miss configured the resource parameter.
According the code sample in the repository at GitHub:
this.passport.use("provider", new AzureOAuth2Strategy({
clientID: config.clientID,
clientSecret: config.clientSecret,
callbackURL: config.callbackUri,
resource: config.resource,
tenant: config.tenant,
prompt: 'login',
state: false
}
we need to configure this resource parameter.
As you are Office 365 to authenticate your users, please try to set resource to https://graph.microsoft.com.
Additionally, please regenerate your AAD application's Secret key, and keep it save in your application, do not expose them to public.
Any update, please feel free to let me know.
Related
I'm working with Power Bi REST APIs, for which I need an azure ad token.
I have set up an app in Azure AD, and have configured it as.
a. I intend to use that access token in my react app so I have configured it as SPA.
b. i have allowed public-client flow.
** I hv not checked 'access token' and 'id token' checkboxes as I'm using msal 2.0.
c. also have specified redirect uri as http://localhost:4200
d. also have given it all the permission I need to access my powerbi content (I need 'Dataset.ReadWrite.All)
THESE ARE MY AZURE APP ENDPOINTS
I HAVE SET MY REACT APP AS:
I'm using #azure/msal-browser and #azure/msal-react libraries.
This is my msalConfig object-
const configuration: Configuration = {
auth: {
clientId: "myclientidhere",//,
authority: "https://login.microsoftonline.com/mytenantidhere",
redirectUri: "http://localhost:4200/",
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: false,
},
}
and, this is my scope:
export const loginRequest = {
scopes: ["Dataset.ReadWrite.All"]
};
after i run my app i see the auth popup. i put my credentials in it. and suddenly it throws this error-
invalid_client: AADSTS650053: The application 'dashboard.xyz.work' asked for scope 'Dataset.ReadWrite.All' that doesn't exist on the resource '00000003-0000-0000-c000-000000000000'. Contact the app vendor. Trace ID: 77e47883-fdd3-444a-bdd3-9f3a53bc1500 Correlation ID: aa77d724-0d9f-41aa-8e47-251c6b6f9293 Timestamp: 2023-02-09 13:51:46Z
i have granted the same permission in my azure ad app. however my app has not been granted 'admin consent' but as a user my account has the permission to use this scope in powerbi.
NOTE: if I change my scope to 'user.read' or any other ms graph API resource, then I'm able to get an access token of that scope to access graph API resource. but I'm not able to get an access token to access my powerbi resources.
EVERYTHING LOOKS GREAT IN AZURE AD.
I READ IT SOMEWHERE THAT THIS RESOURCE '00000003-0000-0000-c000-000000000000' indicates to the graph.microsoft.com resource. and I'm hitting https://login.microsoftonline.com/{myTenantId} . these are my app endpoints.
I'm not sure if powerbi resources come under graph.microsoft.com ('00000003-0000-0000-c000-000000000000) resource!!??
also on my app's API permissions page I read, they come under https://analysis.windows.net/powerbi/api that is 00000009-0000-0000-c000-000000000000??
am I hitting the wrong endpoint or the issue is something else??
I tried to reproduce the same in my environment and got the same error as below:
To resolve the error, try the below:
I created an Azure AD SPA Application and added API permissions:
Note: Make sure to give scope as
https://analysis.windows.net/powerbi/api/Dataset.ReadWrite.All to access PowerBI content
I generated the auth-code by using below endpoint:
https://login.microsoftonline.com/TenantID/oauth2/v2.0/authorize?
client_id=ClientID
&response_type=code
&redirect_uri=https://jwt.ms
&response_mode=query
&scope=https://analysis.windows.net/powerbi/api/Dataset.ReadWrite.All
&state=12345
&code_challenge=codeChallenge
&code_challenge_method=S256
As admin consent is not granted to the API permissions, you will get the consent screen as below:
The auth-code got generated successfully without any error as below:
Now, I generated access token by using below parameters:
https://login.microsoftonline.com/TenantID/oauth2/v2.0/token
grant_type:authorization_code
client_id:ClientID
scope:https://analysis.windows.net/powerbi/api/Dataset.ReadWrite.All
code:code
redirect_uri:https://jwt.ms
code_verifier:S256
The access token generated successfully with the scope Dataset.ReadWrite.All like below:
To resolve the error, modify the code as below:
export const loginRequest = {
scopes: ["https://analysis.windows.net/powerbi/api/Dataset.ReadWrite.All"]
};
If still the issue persists, try scope as https://analysis.windows.net/powerbi/api/.default.
I'm trying to use the next-auth library to call Azure Active Directory via OAuth 2.0, but not sure how to go about doing this.
The providers format in my /api/[...nextauth].js is currently:
providers: [
{
id: 'azure',
name: 'Azure Active Directory',
type: 'oauth',
version: '2.0',
scope: 'read',
accessTokenUrl: 'https://login.microsoftonline.com/{directory_id}/oauth2/v2.0/token',
authorizationUrl: 'https://login.microsoftonline.com/{directory_id}/oauth2/v2.0/authorize',
clientId: process.env.OAUTH_APP_ID,
clientSecret: process.env.OAUTH_APP_PASSWORD,
},
This doesn't seem to be working (Error: "The reply URL specified in the request does not match the reply URLs configured for the application:"). How should I go about this?
I'm quite late with my answer, but for the sake of this question being answered:
Usually, this message means that you're missing the right redirect URI.
In Azure, open your app registration, go to Authentication and enter the redirect URI under "Single-page application".
In this case, it's going to be something like http://localhost/api/auth/callback/azure for your local development.
First I'm describing how I setup my applications then I will describe how I'm using the APIs.
Setup
In my Azure Active Directory, I have two applications registered: UI and Backend
UI has the client ID clientId1 and backend has client ID clientId2 (it's a GUID, but for simplicity)
Both are under the same tenant tentant1 (single tenant)
Backend (Web API)
Backend has an exposed API with scope "api://clientId2/access_as_user" and authorized client "clientId1" with the scope just mentioned selected
I'm using passport and passport-azure-ad (I pretty much copied https://github.com/Azure-Samples/active-directory-javascript-nodejs-webapi-v2).
My config:
const config = {
identityMetadata: "https://login.microsoftonline.com/tenant1/v2.0/.well-known/openid-configuration",
clientID: "clientId2",
validateIssuer: false,
loggingLevel: 'info',
passReqToCallback: false,
loggingNoPII: false
};
I get this message when starting the server:
{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":16052,"level":40,"msg":"Production environments should always validate the issuer.","time":"2020-04-11T13:25:44.283Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":16052,"level":30,"msg":"In BearerStrategy constructor: created strategy with options {\"identityMetadata\":\"https://login.microsoftonline.com/tenant1/v2.0/.well-known/openid-configuration\",\"clientID\":\"clientId2\",\"validateIssuer\":false,\"loggingLevel\":\"info\",\"passReqToCallback\":false,\"loggingNoPII\":false,\"clockSkew\":300,\"allowMultiAudiencesInToken\":false,\"audience\":[\"clientId2\",\"spn:clientId2\"]\"isB2C\":false,\"_isCommonEndpoint\":false}","time":"2020-04-11T13:25:44.285Z","v":0}
Listening on port 5000
UI (Angular SPA)
UI has permissions was granted automatically permission to access Microsoft Graph (profile, user.read, user.read.all -- last one I think I granted). The permissions are in "API permissions"
I went ahead and also granted access to the Backend access_as_user
For the UI code I'm using the MSAL library and again I pretty much copied the repo (https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-angular)
In the protectedResourceMap field I added the following
['https://graph.microsoft.com/v1.0/me', ['user.read']],
['http://localhost:5000', ['api://clientId2/access_as_user']],
I am able to log in and read my user profile, but when trying to access http://localhost:5000/hello (protected), I'm getting the error the title of this question
{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":20720,"level":30,"msg":"authentication failed due to: jwt audience is invalid","time":"2020-04-11T13:38:08.700Z","v":0}
--
I can see the Bearer Token coming (in the UI and backend), the server decodes the token (I can see all my profile info in the server logs), but it's saying the JWT is invalid?!
I'm not defining an audience, yet I can see in the token when it gets decoded the audience with aud: 'api://clientId2'.
I can also see when the backend starts it shows the audience as [clientId2, sps:clientId2] by default (step4 on the backend). When I define in the config audience: 'api://clientId2', I get a 403 with the message:
{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":12644,"level":30,"msg":"In Strategy.prototype.jwtVerify: We did not pass Req back to Callback","time":"2020-04-11T16:19:30.398Z","v":0}
Any help would be appreciated. Thank you.
Turns out their code in the repository is not using proper configuration to verify the scope access...
https://github.com/Azure-Samples/active-directory-javascript-nodejs-webapi-v2/blob/master/index.js#L41
if (req.authInfo['scp'].split(" ").indexOf("demo.read") >= 0) {
I needed to change the scope from "demo.read" to "access_as_user".
In my case it was just that the clock of my VM where the application was running on was 15mins behind. So the time of the token was created was in the future...
We have implemented Microsoft Azure oauth2 on our web app, and we are trying to address common errors that users have when using that oauth method.
The error: OAuth2::Error, invalid_grant: AADSTS65001: No permission to access user information is configured for '...' application, or it is expired or revoked. resembles about 82% of our errors with the azure oauth flow.
Here's our configuration:
# ==> Office 365 OAuth2
config.omniauth :azure_oauth2,
client_id: '...',
client_secret: '...',
tenant_id: '...',
resource: 'https://outlook.office365.com/',
setup: lambda { |env|
params = Rack::Utils.parse_query(env['QUERY_STRING'])
options = env['omniauth.strategy'].options
case params['state']
when 'calendar'
options[:prompt] = 'login'
when 'select_account'
options[:prompt] = 'login'
end
}
We know that this error can be caused from using a non Office 365 account. Since our resource is 'https://outlook.office365.com/', and because our app needs to be able to interact with your calendar, the user must authenticate with an office 365 account. Some other account like a microsoft live account will cause this error.
QUESTIONS
1 - what else might cause this error?
2 - Is there a way to limit the azure oauth flow to only allow true office 365 logins?
The reason is: If a user got locked out and had to reset his password or any other invalid tries to login to Azure AD (Which authenticates users against o365) will invalidate the refresh token that your app has. therefore, an application will handle the changed password (old refresh token) gracefully by throwing this error. In this case, you app should redirect the user to the authorization page to authenticate the user.
Hope this helps.
I'm using passport.js for Facebook authentication and I started to get this error recently. Full error message looks like this:
FacebookGraphAPIError: (#100) Tried accessing nonexisting field (user_photos) on node type
(User) at D:\app\node_modules\passport-facebook\lib\strategy.js:167:21 at passBackControl
(D:\app\node_modules\passport-facebook\node_modules\passport-oauth2\node_modules\oauth\lib\oauth2.js:124:9)
at IncomingMessage.<anonymous> (D:\app\node_modules\passport-facebook\node_modules\passport-oauth2\node_modules\oauth\lib\oauth2.js:143:7)
at IncomingMessage.emit (events.js:129:20) at _stream_readable.js:908:16 at
process._tickCallback (node.js:355:11)
I tried different approaches to set permissions scope. Initially I declared it in
passport.use(new FacebookStrategy({
profileFields : ['user_photos', 'user_friends'],
}
Then I moved it to
app.get('/auth/facebook', passport.authenticate('facebook',
{ scope : ['email, public_profile, user_photos, user_friends'] }));
And it still causes the same error, as well as user_friends if I remove user_photos. Any ideas on what am I doing wrong? Core of my authentication script was inspired by this tutorial https://scotch.io/tutorials/easy-node-authentication-facebook
"Some Facebook integrations require approval before public usage."
https://developers.facebook.com/docs/facebook-login/permissions/
Your app, either in production or in testing, needs to be reviewed.
https://developers.facebook.com/docs/facebook-login/review/how-to-submit
Until reviewed and approved by Facebook, your app can use only the public profile of an user and his/her email.
Apart from public profile and email, the other permissions require that you submit your app for approval.
So what you do is :
go to the app dashboard.
Go to 'Roles' and select 'Test Users'.
Create a test user(allows you to create more than 1) and grant them all the permissions you plan to request.
In the 'App Review' section make sure the app is set to development mode\
Select the permissions you wish to seek approval for.
Now when performing the screencasts for those permissions, make use of the test user....with permissions already granted by that user, you can perform your screencast without any hitches.
After your app is approved, you can switch your app mode to live.