Search code examples
.net-coreidentityserver4openidopenid-connect

IdentityServer4 Web Login via id_token or access_token


Context

I'm building a hybrid native/web app. Part of it will be API driven, and part of it will be webviews showing an existing website. Once logged in with my OIDC SDK (Amplify/AppAuth), I can access the user's id_token and access_token.

However, because the webviews used in the SDK are not controllable, I cannot reuse the cookies generated by my identity server.

Question

For the reason above, I'm trying to login a user from their id_token or their access_token. (both are JWTs)

I believe this isn't supported by IdentityServer4, but I am looking to implement something myself.

What I have found so far:

1) id_token_hint

OpenID Connect Core 1.0, Section 3.1.2.1, id_token_hint parameter:

OPTIONAL. ID Token previously issued by the Authorization Server being passed as a hint about the End-User's current or past authenticated session with the Client. If the End-User identified by the ID Token is logged in or is logged in by the request, then the Authorization Server returns a positive response; otherwise, it SHOULD return an error, such as login_required. When possible, an id_token_hint SHOULD be present when prompt=none is used and an invalid_request error MAY be returned if it is not; however, the server SHOULD respond successfully when possible, even if it is not present. The Authorization Server need not be listed as an audience of the ID Token when it is used as an id_token_hint value. If the ID Token received by the RP from the OP is encrypted, to use it as an id_token_hint, the Client MUST decrypt the signed ID Token contained within the encrypted ID Token. The Client MAY re-encrypt the signed ID token to the Authentication Server using a key that enables the server to decrypt the ID Token, and use the re-encrypted ID token as the id_token_hint value.

According to this optional spec of OpenID, I should be able to use the id_token on the /authorize endpoint to login the user. I know this isn't implemented in IdentityServer4, but I'm looking at AddCustomAuthorizeRequestValidator to do that. However I'm not sure how to "get a user from their id_token" in the code. Do you have any pointers?

2) using AddJwtBearerClientAuthentication

This method sounds like I could authenticate from my access_token, but I can't find much documentation on how to use it.


Solution

  • THE PROBLEM

    Let me know if I am misunderstanding requirements, but it feels like you have 2 different apps and are trying to make them feel like a single integrated set of screens.

    The default behaviour will be as follows since web views are private browser sessions and cannot use system browser cookies. You want to prevent the second step since it is a poor user experience:

    • User signs in to the mobile app
    • Whenever a secured web view is invoked, there is a new private browser session with no auth cookie, therefore requiring a new login

    COMMON APPROACH: SUPPLY A TOKEN TO THE WEB VIEW

    It can be common to forward the mobile token to the web view, if the two apps are part of the same user experience. If required, extend the mobile app's scopes to include those for the web app.

    You should not need to issue any new tokens or change the security model of either app. But the mobile and web apps need to work together on a solution.

    POSSIBLE WEB VIEW SOLUTION FOR A SERVER SIDE WEB APP

    This might be the simplest option:

    • Provide new .Net Core web back end entry point URLs that require tokens instead of cookies
    • The mobile app could then call those endpoints from web views, and supply its own token in the Authorization Header of the web view request
    • The web back end could then forward mobile web view requests to your Web APIs

    The code to add the Authorization Header to a web view request may be a little tricky but there are ways to do it:

    POSSIBLE WEB VIEW SOLUTION FOR AN SPA

    An option that works for Cookieless SPAs is for the web view to ask the mobile host app for an access token via a Javascript bridge. Some code of mine does this for a cookieless SPA:

    You can clone / run the mobile github repos from your local PC to see the solution. I will be writing up some notes on this in my blog's Mobile Web Integration Post.