I've been doing .NET console, .NET Webforms, and light WPF work before, but this is my first foray into Windows 8 Metro development.
I'm developing an app that's dependent on a web service that requires an authentication token. The app is kind of useless without this token; they only need to provide this token and not a username or password. The token can be revoked by the service provider in the event the app needs to be de-authorized.
Since the token is basically required for any app functionality; it needs to be global, it needs to persist for the lifetime of the app; it would be great if the app remembered the credential in a secure way after the app terminates to be loaded on the next run. I tried sticking a CredentialPicker in the App.xaml.cs file, however I guess the credentialpicker needs to be on an actual page? What's the best way to make this global, and spawn the credentialpicker whenever the model class detects there's no credentials for whatever reason?
My logic I thought would be:
Boot App
Load App Start Page
Check Disk for Credential Hash
If Hash Not Exist, Launch CredentialPicker
Validate Credential/Key
If Credential/Key not valid,
Relaunch CredentialPicker
Else
Store Credentials To Disk
Else
Use Existing Credentials; Proceed
Store Credentials In PasswordVault for use during this app lifecycle
Apologize for the verbosity; I just want to know best practices using an application-wide set of credentials in Win8
If you're authenticating with a web service, you want to use the Web Authentication Broker instead (Windows.Security.Authentication.Web.WebAuthenticationBroker, also see the sample on http://code.msdn.microsoft.com/windowsapps/Web-Authentication-d0485122). The collection of credentials stays in the broker, and you get the server response back that typically contains the key you need for subsequent calls.
Using the credential picker for this purpose isn't really what you want, as that UI is primarily intended for enterprise scenarios, and still requires that you manage the credentials directly in the app. The Web Auth Broker was designed so the credentials always exists on the service and all you get back is the key. There is also a topic in the docs Web authentication broker for online providers on creating a login page that will work great inside the broker.
Note that you can use the password vault for the key--just give it some dummy username in the credential object.
Related
I have a Blazor WebAssembly project that is a stand-alone SPA and calls API endpoints (with JWT if needed) to perform application functions.
This is how authentication is currently set up in my app: There is a user-validating API that I call when a user tries to sign in. Upon a successful sign-in, the API returns back to me a few pieces of information about the user (e.g., email, name, etc.) and a JWT. I store some of the user information in local storage and the JWT as a cookie.
There is an Authentication State Provider that I have wrapped around my project. The user's auth status is assessed by whether their user information is in the local storage and a cookie exists in the browser. Upon signing out, I clear out the local storage and the JWT cookie.
The issue that I have is this: If a user does not sign out, closes the browser, and opens it back up - they are still authenticated, even though that cookie is technically expired (e.g., after a day) and cannot be used anymore.
I do have an auto-timeout method, which essentially calls a JS function to clear out the local storage and JWT cookie upon 20 minutes or so of inactivity. But this doesn't control for cases where a user simply closes the browser without signing out properly.
--
I'm in dire need of help. Perhaps my authentication setup is entirely wrong, although lot of Blazor WASM tutorials online seem to have their auth system set up this way. I know Blazor Server can have auth set up in a different (perhaps better) way, but what is the best implementation for Blazor WASM?
An idea I had was clearing out the local storage and JWT cookie upon closing the browser. Is there a method for this? I.e., uponBrowserClose()
Or is this just a terrible idea?
I have a single player Unity game which records stats about game run-throughs, such as accuracy/runtime. I want these stats to be saved onto a web server / db so I can later aggregate them, the web server being a Node app using Express and the DB being a MongoDB instance. I have made the API routes to POST/GET the data but at the moment the routes are public. Normally, I would implement JWT whereby the user would have to login to be able to make web requests, but since the game is single player there is no login credentials to use.
What would be the best way to verify that a call to my web service has been made from within the Unity game without requiring the user to login/register an account?
So far I have thought about using a key on the Unity-side that needs to be sent through with each request, but this is prone to being discovered by searching through the source code.
Implement oAuth on top of your REST API on the Node side. Now a caller has to provide an access token when calling your API. Make sure your implementation supports a flow you're going to choose in step 2. oauth2authorize is a popular toolkit.
Choose an appropriate oAuth flow and implement it on the Unity side. One possibility is the client credentials grant, a flow designed for service-to-service calls. Another option is exchanging JWT for an access token; the payload of the JWT can reflect the security context of the caller being the Unity game itself.
I have a progressive web application that needs write-access to the Google Drive API for uploading data (media files) the user is creating (either online or offline) in the background while online. It does not really need a server (except for serving the required files, so a static server is sufficient), all of the work could be done on the web application client side.
Since uploading needs to happen on the background, whenever the user is online again (using a service worker and the background sync one-shot API), an access token is not enough for my need (the user can be offline/not use the web application for days) and a refresh token is not supposed to be stored on the web application client side, as far as I understand. Even if it were, I would still need the client secret, which means I have to use a server (or keep the secret within the web application client side, which is a no-no) in order to refresh the token.
It seems like the current ways of using the OAuth2 scheme are at odds with server-less progressive web applications, or I might be missing something. Progressive web applications are more like Chrome applications in this regard, I guess, but I have to supply a Chrome application ID in the Google API console for my application, which I do not (and do not intend to) have and Chrome applications use the Chrome identity API for getting the tokens, which I do not intend to use (and cannot).
I am currently using an actual Node.js server which takes care of the authorization step, keeps the access token and refresh token in a database and returns the existing or new access token to the client, whenever asked. The server is redundant here (and requires a privacy policy for this data which I really do not need to store), I want to do everything using client code, without continuously asking for authorization whenever I upload in the background.
Keeping the refresh token on the web application client side and just reaching out to the server for actually refreshing the access token (nothing must be stored in the server side except the client secret, which is fine), but like I mentioned, I understand the refresh token is not supposed to be kept on the web application side.
Is there a safe and secure way to implement this without a server (or with a server that only gets the refresh token and returns it to the client and refreshes the access token by getting the refresh token from the client)?
It's actually fairly simple, depending on the fine details of your use case.
An important factoid is that once a user has granted permission to your app, he will not have to re-grant it. So you don't need to "continuously asking for authorization whenever I upload in the background". However, the only constraint is that the user must be logged in to Google in order to obtain an Access Token. Normally this isn't an issue, but your app needs to deal with the scenario that a user has logged off from Google, and prompt for login.
All the details are here https://developers.google.com/identity/protocols/OAuth2UserAgent
I suggest avoid the Google JS library because (a) it has its own opinions about the UX, (b) wasn't written with PWAs in mind, (c) has issues on mobile, and (d) is closed source so when it breaks (as it does occasionally), your users are dead in the water until Google fixes it. The page above details the OAuth endpoints so you can easily use them directly. This has the side benefit that adding other cloud storage accounts (AWS, Azure, Drop, etc) is just a case of changing the endpoint URL.
The architecture I use in my PWA is to have my PWA prompt once (and once only) for authorization and then store the user's Gmail address in localStorage. I then have a
hidden iframe which polls once per hour for an Access Token, using the gmail address in a login_hint. This means the iframe is never required to present any UX. The only time UX is required is for the initial auth, which is of course unavoidable, and once per session if the user has logged out of Google.
The only other edge-case you might want to deal with is allowing the user to select between multiple Google accounts, say a personal account and a work domain account.
On a broader point, remember that Google didn't create the OAuth spec so there is little they can do to provide an alternative solution. At an abstract level, auth requires one of the user being present, or secure storage for a permanent token (eg on a server or within a secure store such as Android). Even if we invent OAuth 3, that will still be the case.
We have an auth infrastructure based on OAuth2 that is integrated into a variety of web apps within our organization. We also have a pure native application with no middle-ware of its own, and we want to integrate authentication into this native application. This application already has its own internal login mechanism with a native login screen, and we don't want to have it start launching external components like web browsers in order to display login windows. We are both the app provider and the auth provider, so the concern of the app having visibility into the user's credentials is less of an issue -- we trust ourselves to not intentionally do anything untoward with the user's credentials, and it's the same people writing a login form in the app as writing it on a web site. :-)
We are trying to figure out how best to support having the application continue to collect credentials the way it does now, but use them to obtain an auth token within our auth framework. With the APIs in place right now, the only way I can see for it to be done is to bake a Client Secret into the native app so that it can use a Resource Owner Password Credentials Grant request, since the code that would normally be making this call doesn't have a server side to live in. This feels really wrong, somehow. :-P
As far as I can see it, many of the structures of OAuth don't really apply to this app because it's not living in the context of a web browser, it doesn't have any concept of a "domain" nor any sort of "cross-domain" restrictions. It has been suggested that perhaps we create middleware for this app just for the purpose of exchanging authentication codes for tokens, but the rationale for that seems to be that this middleware theoretically ought to be able to somehow vet requests to determine whether they are legitimately from the application, and I don't see any way to do that that couldn't be faked by anyone with access to the client application code. Basically, the only purpose such middleware would serve would be to make the Client Secret irrelevant with respect to getting auth codes for credentials.
One thought that came to us was, how does something like Windows do it? Windows very obviously uses a native login form, but then some flow exists whereby the credentials that are entered are used for authentication and presumably, deep in the internals of the OS, for obtaining an auth token. Does anybody know if this architecture is documented anywhere? Does Microsoft's architectural choices here have any relation to OAuth2? What is the "best practice" for an application if you take it as a given that it doesn't have middleware and has its own native login form?
FWIW you don't need a client secret to use ROPC Grant to obtain or refresh tokens if the client is configured as a public client, i.e. a client that isn't capable of storing a secret.
RFC8252 OAuth 2.0 for Native Apps encourages using a native user agent for your scenario, using authorization code flows with PKCE. Authorization services like Okta and Auth0 have jumped onboard too, although they still recommend ROPC if the client is "absolutely trusted".
RFC6819 OAuth 2.0 Security discourages ROPC, but also says "Limit use of resource owner password credential grants to scenarios where the client application and the authorizing service are from the same organization", which are first-party apps.
So while the security verdict seems to be that authorization code+PKCE is the best practice, the UX hurdle of showing a user a browser window to log into a native app seem to be keeping ROPC alive. It's difficult to tell if that UX is jarring because people aren't used to it or because people can't get used to it.
The Azure sample active-directory-dotnet-native-desktop shows how to use ADAL to sign in for accessing a Web API from a WPF app. In the call to authContext.AcquireToken it's passing the Resource URL of the web service as a parameter. What if I just want to prompt the user to sign in to the desktop client itself and there's no Web API? Isn't there any sample for that?
Can you define what do you mean in practice with "sign in to the desktop client itself"?. A native app will prompt you only when you need to access remote resources, because they are the only ones that the user cannot access directly. If a resource is already on your local PC, and you have access to the windows session, what are you going to protect with the login? In other words, what is the resource or operation that a user cannot perform unless they go through a login? Having access to the windows session means that the user can do pretty much whatever he/she wants. Doing a login without accessing a remote resource would largely amount to theater.