Azure-Samples / ms-identity-javascript-v2

VanillaJS sample using MSAL.js v2.x and OAuth 2.0 Authorization Code Flow with PKCE on Microsoft identity platform
MIT License
105 stars 84 forks source link

Access to fetch from origin has been blocked by CORS #3

Closed DarkLite1 closed 4 years ago

DarkLite1 commented 4 years ago

We;re having a bit of a similar issue as described here. Currently when running the sample code with msal version 1, which uses the implicit grant flow, all works fine. However, when we try to use this sample that uses msal 2 it fails with the following error:

image

Updating the Azure App Regisrtation to use the "SPA Redirect URI" did not fix it: image

We also tried to disable "implicit grant" in the hope that would resolve the CORSS issue but no luck. Is there still something we're missing here?

  "dependencies": {
    "@azure/msal-browser": "^2.0.0-beta.0",
    "express": "^4.17.1",
    "morgan": "^1.10.0",
    "yargs": "^15.3.1"
  },
derisen commented 4 years ago

hi @DarkLite1 -could you also share your msal configuration? And it might be a good idea to update your msal-browser package first (-beta.2 is out already)

DarkLite1 commented 4 years ago

Thanks for the help. I've updated the package but am still running into the same CORS issue. Yuo can find the repo here. It's basically the same as the original except for the authConfig.js file.

I there any harm in staying with msal version 1? It seems like implicit grant is simple to implement :P

derisen commented 4 years ago

Interesting. I just tested your repo with my own app registration on Chrome and did not have any issues, so I doubt code is the issue. Could you confirm that on the Portal/AppRegistration/Authentication tab, you did not check the boxes for access and id token

screenshot

and in your app manifest this part looks the same:

    "replyUrlsWithType": [
        {
            "url": "http://localhost:5000",
            "type": "Spa"
        }
    ],

Implicit grant is seen as less secure than auth code grant (with pkce) by the most, though there are some that claims the difference is exaggerated. Keep in mind that it's a comparative statement, it's not "bad" in itself.

DarkLite1 commented 4 years ago

Thank you for looking into this. So I disabled both options of implicit grant image

image

Then checked the app manifest, which seems to be correct:

{
    "id": "0e85e9c3-5c38-4e07-909e-d3d7288951cd",
    "acceptMappedClaims": null,
    "accessTokenAcceptedVersion": null,
    "addIns": [],
    "allowPublicClient": null,
    "appId": "d95f2323-b4a1-443f-a6be-acb610688b49",
    "appRoles": [],
    "oauth2AllowUrlPathMatching": false,
    "createdDateTime": "2020-02-21T11:51:40Z",
    "groupMembershipClaims": null,
    "identifierUris": [],
    "informationalUrls": {
        "termsOfService": null,
        "support": null,
        "privacy": null,
        "marketing": null
    },
    "keyCredentials": [],
    "knownClientApplications": [],
    "logoUrl": null,
    "logoutUrl": null,
    "name": "HC IT Portal",
    "oauth2AllowIdTokenImplicitFlow": false,
    "oauth2AllowImplicitFlow": false,
    "oauth2Permissions": [],
    "oauth2RequirePostResponse": false,
    "optionalClaims": null,
    "orgRestrictions": [],
    "parentalControlSettings": {
        "countriesBlockedForMinors": [],
        "legalAgeGroupRule": "Allow"
    },
    "passwordCredentials": [],
    "preAuthorizedApplications": [],
    "publisherDomain": "hcgroupnet.onmicrosoft.com",
    "replyUrlsWithType": [
        {
            "url": "http://localhost:8080",
            "type": "Web"
        },
        {
            "url": "http://localhost:3000",
            "type": "Web"
        },
        {
            "url": "http://localhost:5000",
            "type": "Spa"
        },
        {
            "url": "http://localhost:4200",
            "type": "Web"
        },
        {
            "url": "http://localhost:8081",
            "type": "Web"
        }
    ],
    "requiredResourceAccess": [
        {
            "resourceAppId": "0e01a2d8-64bb-4c3b-a75d-939aa5d8d361",
            "resourceAccess": [
                {
                    "id": "ac742df9-e14c-4200-bfa2-03f17e3dec7b",
                    "type": "Scope"
                }
            ]
        },
        {
            "resourceAppId": "00000003-0000-0000-c000-000000000000",
            "resourceAccess": [
                {
                    "id": "bc024368-1153-4739-b217-4326f2e966d0",
                    "type": "Scope"
                },
                {
                    "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
                    "type": "Scope"
                }
            ]
        }
    ],
    "samlMetadataUrl": null,
    "signInUrl": null,
    "signInAudience": "AzureADMyOrg",
    "tags": [],
    "tokenEncryptionKeyId": null,
    "verifiedPublisher": {
        "displayName": null,
        "verifiedPublisherId": null,
        "addedDateTime": null
    }
}

Then I tried running the app again and received the same CORS policy error within Chrome:

image

derisen commented 4 years ago

@DarkLite1 aah, now I see. The issue seems to be that you have both Web and Single-page application added as platforms. Web is the one causing your CORS issue, you should I ideally have separate registrations for each platform. Try removing Web and its return_uris and see if that solves the issue.

DarkLite1 commented 4 years ago

One question before I remove the normal web redirect URL's. Without the implicit grant does this example still work? Because I will use passport in the backend to verify token validity.

derisen commented 4 years ago

The token will still be the same so it should not affect the validation. I see no problem with that.

DarkLite1 commented 4 years ago

Yup, that fixed it. I really thought you could have both within your manifest. An old URL working the old way and a new url working with the new version. Given the URL's have specific ports I think Azure should be able to handle these differently.

Anyway, thanks for the help. Migrating to the newer lib :)

fsundjaja commented 4 years ago

Hi Derisen, I am encountering the same issue too except my situation is slightly different from DarkLite1's i.e. I have 2 platforms for the application: SPA and Android (instead of Web). Should I remove the Android one to make it work? Thanks

derisen commented 4 years ago

@fsundjaja you should ideally have separate app registrations for each. If that is not possible/feasible for some reason, try checking the slider for Default Client Type on Authentication tab and see if that helps

screenshot

fsundjaja commented 4 years ago

Thanks. I left the application with SPA only now however I am still getting blocked by CORS by login.microsoft.com. I am not sure if I did not pass the right scope.

derisen commented 4 years ago

@fsundjaja could you double check that there are no references to Mobile and Desktop Applications in your Application Manifest (by clicking on the Manifest tab on the left-hand menu)?

replyUrlsWithType: [
        {
            "url": "xxxx",
            "type": "InstalledClient"
        }
]
fsundjaja commented 4 years ago

Thanks. I can confirm I dont have Mobile and Desktop Applications in the Application Manifest. Below is what I have

"replyUrlsWithType": [ { "url": "http://localhost:8080/index.html", "type": "Spa" }, { "url": "https://login.microsoftonline.com/common/oauth2/nativeclient", "type": "InstalledClient" } ],

derisen commented 4 years ago

Looks like its still there in the manifest, try deleting this bit:

{
"url": "https://login.microsoftonline.com/common/oauth2/nativeclient",
"type": "InstalledClient"
}
fsundjaja commented 4 years ago

You are correct. I took it out and this is what it looks like (see below) now. Unfortunately the CORS block is still happening.

"replyUrlsWithType": [
    {
        "url": "http://localhost:8080/index.html",
        "type": "Spa"
    }
],

This is what the error looks like on the Chrome's console

Annotation 2020-07-20 142816

And this is what the Network calls look like. Weird thing is if I click on the red one it open ups the browser and I can see the API result just fine. The $metadata is the actual call to API application that seems to redirect it to login.microsoft.com as I am guessing it is not honoring the token I received for the API scope and caused the aforementioned CORS block.

image

derisen commented 4 years ago

Hmm.. this is weird. Can you share your app manifest and app/msal configuration?

fsundjaja commented 4 years ago

Sorry for not getting back sooner. Just one more thing. This CORS block was triggered when I called a Web Api or Application proxy (SAML protected) from a SPA. Do you think API call wont work if it is SAML-protected from a SPA?

derisen commented 4 years ago

@fsundjaja that might be possible, though I'm not quite sure. Just to make sure, can you please delete your service principal and try again. Steps to do so are here. If that won't work, it's best to open a new issue in MSAL.js repo.

solmon commented 3 years ago

@DarkLite1 aah, now I see. The issue seems to be that you have both Web and Single-page application added as platforms. Web is the one causing your CORS issue, you should I ideally have separate registrations for each platform. Try removing Web and its return_uris and see if that solves the issue.

Thank you this saved my day