Search code examples
.netnativeopenidopenid-connect

OpenID Connect protected API for a desktop application


I'm building a WPF .NET windows application that will connect up to an API. Because we have other APIs, I'd like to start putting all the login logic into a single module/service that handles it in a standardized way. I am thinking OpenID Connect (OIDC) is a good protocol for this.

From what I can tell, Authorization Code flow with PKCE is the way to go here. I'd like someone to confirm for me if I'm going about this the right way. Below is the flow I imagine I'll need to implement:

  1. User starts the application and logs into our OIDC provider via an embedded browser (going through the Code with PKCE flow). The client is our native app and the scope is limited to 'profile' 'the-api'.
  2. After the user logs in, the refresh token and access token are returned using a POST redirect that the application can intercept.
  3. The native application uses that access token to get user info and display profile information in the app.
  4. The native app sends a request to the API with the access_token.
  5. The api verifies the user by checking the access_token at the userinfo endpoint of the OP and ensuring it has the proper scope.

I think the native client should check the access_token before sending each request to the API. If the access_token is expired or about to expire (maybe in < 30 seconds), then go fetch a new access_token before sending the request.

The thing that makes me feel unsure about this is that there is no redirect to the API. Many of the flows redirect the user to the OP, then redirect back to the API. I guess the reason this does not have that is because it's native and doesn't directly support redirects to pages like a browser would.

Am I going about this the right way?


Solution

  • I am thinking OpenID Connect (OIDC) is a good protocol for this

    OIDC and OAuth 2.0 is the best choice if you want to separate user identities from your application. That mean you do not hold them in your end of application but get through for example Azure AD, ADFS or even Google. Also it is the correct choice if you prefer token based authentication and authorisation. Which mean you trust tokens issued by an authorization server (also called and identity provider or OP) which is more secure than passing username/password through basic authentication.

    Authorization Code flow with PKCE is the way to go here

    Correct. Native applications such as one you are creating, which runs on windows machine of user should use PKCE with auth. code flow.

    About the flow

    I am not sure the second step, After the user logs in, the refresh token and access token are returned using a POST redirect that the application can intercept. I guess you are getting tokens from authorization request ? Not sure what you meant here but what ideally must happen is you should obtain authorization code after user log in in the browser instance. Once you get that you must directly call token endpoint of the identity provider. You get tokens as a result of this token request. And it has PKCE completion step as well.

    Also The native application uses that access token to get user info and display profile information in the app. For this you can use ID token which comes in token response. It contains end user information. Please check more from protocol's explanation.

    From API end, yes it must check validity of call against access token which comes along with API request. For this it can use user_info endpoint for first time it sees a fresh access token and then cache details. And in later calls it can use cached information to detect user information. Also, some OPs send JWT based access tokens which your API can read and detect expiration details.

    I think the native client should check the access_token before sending each request to the API.

    No.! It must be the API that should do this check. Otherwise API will blindly accept tokens which can be send by some malicious client. Implement this to API end and in case access token is not valid, send a 401 - unauthorized response.