I have 2 webapi2 projects that use the same database. If I'm on localhost I get a bearer token from one I can pass it to the other and the other will properly decrypt it and load the user. However when I publish them to separate urls on azure, I get the one token fine from one but when I pass it to the other I can't get the ticket to load and it gives me the unauthorized response.
I'm testing this by watching the owin AuthenticationTokenProvider.OnRecieve method. When context.DeserializeTicket is called the ticket remains null and the user never gets loaded.
Your first response will likely be about how the machine keys need to be the same between the 2 so they will work. The problem there is
All my online research says that azure machine keys are synced between apps in the same role (ones a web app and the other is a web api app) so this shouldn't be an issue
I can't specify a machine key because the first app has been in production for a while and changing it's machine key would mess up stored passwords etc...
using the machine key used by the production app on the new api nay work but there is no way to get the machine key of an azure web app.
I'm pretty sure this isn't a machine key issue though but I have no idea how to figure this out. Heeeeelllp!
Related
I have been testing a Blazor Server app (ASP.NET Core 6.0) locally for a while with no issues. It authenticates against Azure AD, and everything works fine.
I deployed it to an IIS 10 server on Windows Server 2019 (after installing Websockets, ASP.NET hosting runtime, etc.) and now I can't get past authentication, either locally on the server or remotely.
When I hit the URL, it immediately redirects to the Microsoft Login page, where I enter my username (email), then password, then 2FA challenge, then the yes/no stay logged in page, and then it appears to hang for a short while (although in the tab it is constantly switching between "Working" and "https://login.microsoft.com...") and then it either comes up with Bad Request - Request Too Long, or just "We can't sign you in".
If it's the Bad Request error, then the cookie store will be full of .AspNetCore.Correlation.xxx and .AspNetCore.OpenIdConnectNonce.xxx cookies, which is what makes the headers too long, and creates the bad request. If it's the "we can't sign you in" error, then clicking the three dots, and saying sign out and forget, resets things which will next time result in the Bad Request error.
Just to check that I hadn't done anything stupid, I created a new blank app, using the Blazor Server template, and deployed that in place of my app. Exactly the same thing happened. I could run it locally in VS, but after publishing to IIS, exactly the same Authentication errors.
Does anyone have any ideas or pointers?
OK, for anyone who finds this in the future... it was a simple fix - but there are no error messages which point to it until you look very deeply.
When I set up both my app, and the Blazor template app, I let the scaffolder set them up, and get a secret from the Azure API, which it placed into my local secret store.
When I published the app to IIS, the ClientSecret was not copied.
The quick fix was to simply put the client secret into the appsettings.json file at which point everything came good immediately. The longer fix is to use the server-based secret store.
Apparently the looping was caused by the client secret not being present. :(
I have decided to try to manage releases of one of my apps on GitHub as with GitHub Actions, I can build on Mac, Linux and Windows and automatically push the artifacts to the GitHub Releases page, where anyone can go and download the app from.
However, I want my app to self-update, so the app itself also needs to be able to query what's the latest version in the repo releases, and then download the relevant asset for the user's OS... which I thought would be a non-issue... however, there's no way to access the GitHub API v4 without either an OAuth app or a personal access token.
I don't want an OAuth app because the users of my app are absolutely not expected to be GitHub customers. So I tried to use a personal access token whose only scope was access to public release assets (which, again, is a public resource anyone can go and manually download).
As this token can't do anything you or anyone else can't do manually, even without a GitHub account, I thought it would be fine to put the token in the source code of my application, but GitHub revokes the token when it detects it on a commit.
Is there a good way to work around this? Should I put the token in a GitHub secret and then try to replace a placeholder with it during compilation?? I wanted to avoid that as that makes it hard for me to test the app locally, and also, it doesn't solve anything as anyone can easily decompile the app and find the token there (supposing GitHub would not detect the secret is present in the "processed" sources during compilation).
Any suggestions would be appreciated.
however, there's no way to access the GitHub API v4 without either an OAuth app or a personal access token.
The GitHub API v3 does support unauthenticated calls, but it's limited to 60 requests/hr per IP address: https://developer.github.com/v3/#rate-limiting
For unauthenticated requests, the rate limit allows for up to 60 requests per hour. Unauthenticated requests are associated with the originating IP address, and not the user making requests.
The Latest Release API docs will show you what information is returned, but I suspect you'll need to make a secondary call to List Assets for a release to know the files the client needs to download.
If that's not satisfactory (e.g. you know you'll have many clients try to update using the same IP address), and you'd like to ensure they aren't being rate-limited, read on for a different approach.
Is there a good way to work around this?
How I would tackle this is by deploying a small web service (e.g. Heroku dyno) that your app can will call without needing authentication, which then performs the actual lookup for the latest version (using a PAT that gets embedded as an environment variable) and returns a simple JSON response that the client will understand.
Benefits:
no token embedded in client
development mode can even call same service
add logic to service that the client would perform to simplify your app
e.g. call /latest/beta or /latest/stable to indicate it's looking for a specific channel
perform both API calls and return the assets that the client needs
can update token in service whenever necessary (e.g. to refresh token) without changing client
can cache response to reduce risk of being rate-limited
Downsides:
more moving parts to manage in your overall architecture
need to worry about uptime of the service if there are lots of clients connecting
this can be offset by making the client resilient to failure cases
My understanding: In an Azure App Service, you can set the service to basically never "fall asleep" by setting the "Always On" setting in Azure Portal.
While this is an easy change to the service, I am trying to avoid having the service constantly run when not in use, and driving up the monthly expense of hosting the service.
My dilemma is that I have an Azure App Service running, which I authenticate a Xamarin Forms app against. In the process of logging in, I return an OAuth token to the client which is set to expire in 15 days (something long for testing).
Everything works fine while the Azure Service is running, but if the Azure Service "falls asleep" then I am forced to login again - which leads me to believe that the tokens issued by the service have been lost after the service falls asleep.
My question is: Is there a way to store the current tokens in an Azure Table Storage (or something) prior to "falling asleep", then pull from the same storage when the service "wakes up"??
I did find the below question, but couldn't get a clear understanding of how to persist the bearer tokens:
How are bearer tokens stored server-side in Web API 2?
I have been searching high and low with clear indication of how to do this, let alone if this is even possible.
Any help would greatly be appreciated.
The answer of How are bearer tokens stored server-side in Web API 2? you find is right. Usually, we will store the access token in client side. You can store it any place in your clients, local storage, sqlite, even files. Just to make sure, your application can get back the access token.
When your application send HTTP requests to the protected server, you will set the access token in Authorization header.
And your server once get a HTTP request, it will verify the token and authorize the user.
We are developing an UWP app using ADAL authentication in Azure. We have configured our client in Azure Portal with the Redirect URI taken from the result of this method:
Windows.Security.Authentication.Web.WebAuthenticationBroker.GetCurrentApplicationCallbackUri()
It was working at the beginning, but now we've noticed that the URI generated by that method has changed. Therefore our login with ADAL does not worked anymore, stating that
The reply address 'ms-app://s-1-15-2-104.......' does not match the reply addresses configured for the application.
Of course, we added the new value of the URI to the client configuration, and it worked, but after a day or two it has changed again. I think this is not the right way to update the Azure configuration every couple of days.
How can we ensure that the result of GetCurrentApplicationCallbackUri stays unchanged?
The GetCurrentApplicationCallbackUri uses your app's SID to construct the URL. I'm not sure of the exact mechanics of it, but if you are still developed the app, especially in a team, the SID can change.
One way to ensure that it remains fixed, is to create the Application in the Windows Dashboard and associate the app with the Store:
From Visual Studio - right click on the Project and select Store->Associate app with the store.
You don't have to submit, but associating the app will update the package.appxmanifest with the real values from the Dashboard and they will persist across developers.
From documentation:
To support SSO, the online provider must allow you to register a redirect URI in the form ms-app://appSID, where appSID is the SID for your app. You can find your app's SID from the app developer page for your app, or by calling the GetCurrentApplicationCallbackUri method.
So, I thought I had this all working until I deployed to a new set of environments. I have a webapp that's authenticating just fine with multi-tenant WAAD users. But when I try to hit the webapp from an HttpClient after authenticating via AcquireTokenAsync I always get the login page as the result.
The only concrete thing I have to go in is the fact that the on-boarding process never seems to complete. The login prompt always asks me to give the WebApp and Native Client permissions.
I've triple checked client ids, tenants, app id urls, etc. Is there anything else to investigate? I hit this snag once before only for it to just start working :(
Edit #1: Webapp + api works just fine via the normal cookies, just seems to completely ignore the Bearer token I'm setting?
So it turns out I had set the Audience on the WindowsAzureActiveDirectoryBearer object incorrectly so the token was never valid...