简体   繁体   English

检查是否已在IdentityServer 4中对用户进行身份验证

[英]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. 我正在用IdentityServer 4实现授权服务器。我可以保护我的API,并使用混合流发布ID,访问和刷新令牌。 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: 为了实现这一点,我认为仅通过promt = none到达授权端点/ connect / authorize并解析响应就足够了,但它不断出现以下错误:

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: 您可以看到,我之前在身份验证服务器中登录用户时,用于检查用户是否在授权服务器中经过身份验证的请求的SubjectId是“匿名”,而不是值“ 1”:

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? 什么时候设置SubjectId? I actually can't set it manually when I do the request to the authorization endpoint. 当我向授权端点发出请求时,实际上我无法手动设置它。

Thanks. 谢谢。

promt=none is the correct approach. promt = none是正确的方法。 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. 这必须通过可访问IdentityServer cookie的前端通道进行。

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." “授权服务器不得显示任何身份验证或同意用户界面页面。如果最终用户尚未经过身份验证,或者客户端对请求的声明没有预先配置的同意,或者不满足其他处理条件,则将返回错误错误代码通常是login_required,interaction_required或第3.1.2.6节中定义的其他代码。它可以用作检查现有身份验证和/或同意的方法。” - OpenID Connect Core 1.0 -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. 请注意,仅因为您具有有效的访问令牌,并不意味着该用户已通过IdentityServer进行身份验证,或者根本就没有用户。 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. 这样做总是会失败,因为您没有提供用户浏览器提供的cookie。

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. ETA:如果您想要中央控制和撤销令牌的能力,则需要使用参考令牌而不是JWT。 That way when a user signs out of the IDP you can explicitly revoke any currently valid tokens. 这样,当用户退出IDP时,您可以显式撤消任何当前有效的令牌。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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