简体   繁体   中英

Check if user is already authenticated in IdentityServer 4

I'm implementing an authorization server with IdentityServer 4. I can protect my API already and issue id, access and refresh tokens using hybrid flow. One requirement I have for my clients is to be able to check on the background if a user is authenticated in the authorization server already or not.

To achieve that I thought it would be enough to just reach the authorization endpoint /connect/authorize with promt=none and parse the response but it keep getting the following error:

info: IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator[0]
  Showing error: prompt=none was requested but user is not authenticated
info: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
  {
    "ClientId": "BGServer",
    "ClientName": "BabyGiness Server",
    "RedirectUri": "http://localhost:5005/signin-oidc",
    "AllowedRedirectUris": [
      "http://localhost:5005/authorization_code_callback",
      "http://localhost:5005/signin-oidc"
    ],
    "SubjectId": "anonymous",
    "ResponseType": "code id_token",
    "ResponseMode": "form_post",
    "GrantType": "hybrid",
    "RequestedScopes": "openid BG_API",
    "State": "f3ea482efca35891a774242fa582f14782ab45783f4630a2950791e693734c53",
    "Nonce": "56c99bb0175cbf92a83c80089baa003e76cc89f28cb704f440b3c9fec54b759c",
    "PromptMode": "none",
    "Raw": {
      "client_id": "BGServer",
      "response_type": "code id_token",
      "scope": "openid BG_API",
      "redirect_uri": "http://localhost:5005/signin-oidc",
      "state": "f3ea482efca35891a774242fa582f14782ab45783f4630a2950791e693734c53",
      "nonce": "56c99bb0175cbf92a83c80089baa003e76cc89f28cb704f440b3c9fec54b759c",
      "prompt": "none",
      "response_mode": "form_post"
    }
  }

This is how I do my request:

var client = new HttpClient();
var request = new RequestUrl(disco.AuthorizeEndpoint);
var url = request.CreateAuthorizeUrl(
clientId: "BGServer",
scope: "openid BG_API",
responseType: OidcConstants.ResponseTypes.CodeIdToken,
responseMode: OidcConstants.ResponseModes.FormPost,
redirectUri: "http://localhost:5005/signin-oidc",
state: CryptoRandom.CreateUniqueId(),
nonce: CryptoRandom.CreateUniqueId(),
prompt: OidcConstants.PromptModes.None);

var authResponse = await client.GetAsync(url);

You can see that the SubjectId of my request to check if user is authenticated in the authorization server is "anonymous" instead of the value "1" I have when I log in the user in the auth server previously:

info: IdentityServer4.Endpoints.AuthorizeCallbackEndpoint[0]
  ValidatedAuthorizeRequest
  {
    "ClientId": "BGServer",
    "ClientName": "BabyGiness Server",
    "RedirectUri": "http://localhost:5005/signin-oidc",
    "AllowedRedirectUris": [
      "http://localhost:5005/authorization_code_callback",
      "http://localhost:5005/signin-oidc"
    ],
    "SubjectId": "1",
    "ResponseType": "code id_token",
    "ResponseMode": "form_post",
    "GrantType": "hybrid",
    "RequestedScopes": "openid profile BG_API offline_access",
    "State": "CfDJ8HU-TcpaPlFAoESzY3trdqklDCD3w3fsiSazk_fV3AMlQfQE5ow-IbLPLUM7CsL53unb_yLRnTKF5480gQOwSo9_HvlH3u0vRQZGwKde-yjTaSGKmu1LiKQTzpHpC7jStThRFQqbY5ukk-nUYhms473QHi7dudNIbx7fSXSeHn_P5ijItwMvssgIe9j92peeX2lI41Fc2XVAnw3FMGd88FtnVor6iXWUjKZLMiRN_3XWBDZOeCIsUAQrgYofYVp79wpNbOYxhiLabLFYMu0vK3LbEprQXJWSSL7QRFqh34ZO-8fvb1ps6oeo0H8Q6kiGEAJoVjre5wo09rBbmBYbLtU",
    "Nonce": "636554914948006185.YjUwZDY3ZjItY2U2YS00ZmIzLWIxNmUtYTAwMmViM2E4ZTY2ZTA4MmRmODItY2ZiMi00ZTM2LTk2ZGItYzA0ZDJhMGQ3OWQ4",
    "SessionId": "433c1aefad973812e41abac6c231304d",
    "Raw": {
      "client_id": "BGServer",
      "redirect_uri": "http://localhost:5005/signin-oidc",
      "response_type": "code id_token",
      "scope": "openid profile BG_API offline_access",
      "response_mode": "form_post",
      "nonce": "636554914948006185.YjUwZDY3ZjItY2U2YS00ZmIzLWIxNmUtYTAwMmViM2E4ZTY2ZTA4MmRmODItY2ZiMi00ZTM2LTk2ZGItYzA0ZDJhMGQ3OWQ4",
      "state": "CfDJ8HU-TcpaPlFAoESzY3trdqklDCD3w3fsiSazk_fV3AMlQfQE5ow-IbLPLUM7CsL53unb_yLRnTKF5480gQOwSo9_HvlH3u0vRQZGwKde-yjTaSGKmu1LiKQTzpHpC7jStThRFQqbY5ukk-nUYhms473QHi7dudNIbx7fSXSeHn_P5ijItwMvssgIe9j92peeX2lI41Fc2XVAnw3FMGd88FtnVor6iXWUjKZLMiRN_3XWBDZOeCIsUAQrgYofYVp79wpNbOYxhiLabLFYMu0vK3LbEprQXJWSSL7QRFqh34ZO-8fvb1ps6oeo0H8Q6kiGEAJoVjre5wo09rBbmBYbLtU",
      "x-client-SKU": "ID_NET",
      "x-client-ver": "2.1.4.0"
    }
  }

How can I check if the user is authenticated in the authorization server correctly? Is this the valid approach? When is the SubjectId set? I actually can't set it manually when I do the request to the authorization endpoint.

Thanks.

promt=none is the correct approach. As per the spec, if the user isn't authenticated, or needs to give consent, an error is supposed to be returned to the requesting client.

This must take place via the front channel where access to the IdentityServer cookies is possible.

prompt=none:

"The Authorization Server MUST NOT display any authentication or consent user interface pages. An error is returned if an End-User is not already authenticated or the Client does not have pre-configured consent for the requested Claims or does not fulfill other conditions for processing the request. The error code will typically be login_required, interaction_required, or another code defined in Section 3.1.2.6. This can be used as a method to check for existing authentication and/or consent." - OpenID Connect Core 1.0

Please note, just becuase you have a valid access token, it doesn't mean that a user is authenticated with IdentityServer, or that there is a user at all. It just means your app is authorized to do "stuff".

You can't do this (call the authorize endpoint) back-channel as it must be run in the context of the user's browser. Doing it this was will always fail as you're not supplying the cookies the user's browser has.

What are you actually trying to achieve? What's the use case?

ETA: If you want central control and the ability to revoke tokens then you'll need to use reference tokens instead of JWTs. That way when a user signs out of the IDP you can explicitly revoke any currently valid tokens.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM