检查用户是否已在IdentityServer 4

时间:2018-03-01 09:11:46

标签: c# authentication authorization identityserver4

我正在使用IdentityServer 4实现授权服务器。我可以保护我的API并使用混合流发出id,access和refresh令牌。我对客户的一个要求是能够在后台检查用户是否已在授权服务器中进行了身份验证。

为了实现这一目标,我认为仅使用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"
    }
  }

这就是我的要求:

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);

您可以看到我检查用户是否在授权服务器中进行身份验证的请求的SubjectId是"匿名"而不是价值" 1"当我以前登录auth服务器中的用户时,我有了:

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"
    }
  }

如何检查用户是否在授权服务器中正确进行了身份验证?这是有效的方法吗? SubjectId何时设置?当我向授权端点发出请求时,我实际上无法手动设置它。

感谢。

2 个答案:

答案 0 :(得分:2)

promt = none是正确的方法。根据规范,如果用户未经过身份验证或需要同意,则应将错误返回给请求客户端。

这必须通过可以访问IdentityServer cookie的前端通道进行。

提示=无:

  

"授权服务器不得显示任何身份验证或同意用户界面页面。如果最终用户尚未经过身份验证,或者客户端没有对所请求的声明进行预先配置的同意,或者不满足处理请求的其他条件,则会返回错误。错误代码通常是login_required,interaction_required或第3.1.2.6节中定义的其他代码。这可以用作检查现有身份验证和/或同意的方法。" - OpenID Connect Core 1.0

请注意,只是因为您拥有有效的访问令牌,并不意味着用户已使用IdentityServer进行身份验证,或者根本没有用户。这只是意味着您的应用程序被授权执行" stuff"。

答案 1 :(得分:0)

您不能这样做(调用授权端点)反向频道,因为它必须在用户浏览器的上下文中运行。这样做总是会失败,因为您没有提供用户浏览器所拥有的cookie。

你到底想要实现什么目标?用例是什么?

ETA:如果你想要中央控制和撤销令牌的能力,那么你需要使用引用令牌而不是JWT。这样,当用户退出IDP时,您可以明确撤销任何当前有效的令牌。