首页 文章

如何使用Identity Server 4的Windows身份验证发出访问令牌

提问于
浏览
1

我的目标是保护Web API,使其只能由客户端使用IS基于Windows身份验证发出的访问令牌进行访问 . 我完成了这个基本的样本:http://docs.identityserver.io/en/release/quickstarts/1_client_credentials.html

现在,我需要扩展基本示例,以便基于Windows身份验证发出返回到客户端的访问令牌 . 更具体地说,我需要让用户(正在执行客户端应用程序)在请求访问令牌时针对Active Directory进行身份验证 . 该怎么做?

我已经成功运行快速启动(https://github.com/IdentityServer/IdentityServer4.Templates),其中登录基于Windows外部提供程序,但我无法弄清楚如何将此功能用于我的策略 .

我尝试使用扩展授权(http://docs.identityserver.io/en/release/topics/extension_grants.html)并使ValidateAsync()方法成为对AD进行身份验证的方法,但无法使其工作(主要是因为HttpContext不可用) . 这甚至是正确的方法吗?

Update

在此系统中,客户端是控制台应用程序(没有人工交互),因此上下文是运行应用程序的帐户 . 我一直在运行QuickstartUI并查看AccountController逻辑如何处理“Windows”按钮,但无法掌握如何将其与请求访问令牌相结合 . 我的客户端代码是这样的:

static async Task Main(string[] args)
{
  var disco = await DiscoveryClient.GetAsync("http://localhost:50010");

  var tokenClient = new TokenClient(disco.TokenEndpoint);
  var tokenResponse = await tokenClient.RequestCustomGrantAsync("CustomWindows"); // Not sure about this

  var client = new HttpClient();
  client.SetBearerToken(tokenResponse.AccessToken);

  var response = await client.GetAsync("http://localhost:50011/api/identity");
  var content = await response.Content.ReadAsStringAsync();
  Console.WriteLine(JArray.Parse(content));

  Console.ReadLine();
}

在这种情况下,我不确定如何使用TokenClient获取访问令牌 . 我不希望存储和使用密码,但是基于针对AD验证客户端上下文而具有IS问题访问令牌 . 如果在这种情况下必须使用隐式或混合流,那么必须如何进行?

1 回答

  • 0

    我有相同的要求,并使用扩展授权实现它 .
    这是扩展授权的代码:

    public class WinAuthGrantValidator : IExtensionGrantValidator
    {
        private readonly HttpContext httpContext;
    
        public string GrantType => WinAuthConstants.GrantType;
    
        public WinAuthGrantValidator(IHttpContextAccessor httpContextAccessor)
        {
            httpContext = httpContextAccessor.HttpContext;
        }
    
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            // see if windows auth has already been requested and succeeded
            var result = await httpContext.AuthenticateAsync(WinAuthConstants.WindowsAuthenticationSchemeName);
            if (result?.Principal is WindowsPrincipal wp)
            {
                context.Result = new GrantValidationResult(wp.Identity.Name, GrantType, wp.Claims);
            }
            else
            {
                // trigger windows auth
                await httpContext.ChallengeAsync(WinAuthConstants.WindowsAuthenticationSchemeName);
                context.Result = new GrantValidationResult { IsError = false, Error = null, Subject = null };
            }
        }
    }
    

    这是客户端代码:

    var httpHandler = new HttpClientHandler
    {
        UseDefaultCredentials = true,
    };
    
    // request token
    var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret", httpHandler, AuthenticationStyle.PostValues);
    var tokenResponse = await tokenClient.RequestCustomGrantAsync("windows_auth", "api1");
    

相关问题