除了对OpenID Connect和OAuth 2.0的内置支持之外,IdentityServer4还允许添加对其他协议的支持。

您可以将这些附加协议端点添加为中间件或使用例如MVC控制器。在这两种情况下,您都可以访问ASP.NET Core DI系统,该系统允许重用我们的内部服务,例如访问客户端定义或密钥材料。

可以在此处找到添加WS-Federation支持的示例

典型认证工作流程

身份验证请求通常如下所示:

  • 身份验证请求到达协议端点
  • 协议端点执行输入验证
  • 重定向到登录页面,返回URL设置回协议端点(如果用户是匿名的)
    • 通过访问当前请求详细信息 IIdentityServerInteractionService
    • 用户身份验证(本地或通过外部身份验证中间件)
    • 登录用户
    • 重定向回协议端点
  • 创建协议响应(令牌创建和重定向回客户端)

有用的IdentityServer服务

要实现上述工作流程,需要与IdentityServer建立一些交互点。

访问配置并重定向到登录页面

您可以通过将IdentityServerOptions 类注入代码来访问IdentityServer配置这个,例如具有登录页面的配置路径:

var returnUrl = Url.Action("Index");
returnUrl = returnUrl.AddQueryString(Request.QueryString.Value);

var loginUrl = _options.UserInteraction.LoginUrl;
var url = loginUrl.AddQueryString(_options.UserInteraction.LoginReturnUrlParameter, returnUrl);

return Redirect(url);

登录页面与当前协议请求之间的交互

所述IIdentityServerInteractionService支撑件转动一个协议返回URL成解析和验证上下文对象:

var context = await _interaction.GetAuthorizationContextAsync(returnUrl);

默认情况下,交互服务仅了解OpenID Connect协议消息。要扩展支持,您可以自己编写IReturnUrlParser

public interface IReturnUrlParser
{
    bool IsValidReturnUrl(string returnUrl);
    Task<AuthorizationRequest> ParseAsync(string returnUrl);
}

..然后在DI中注册解析器:

builder.Services.AddTransient<IReturnUrlParser, WsFederationReturnUrlParser>();

这允许登录页面获取客户端配置和其他协议参数等信息。

访问用于创建协议响应的配置和密钥材料

通过将IKeyMaterialService代码注入到代码中,您可以访问配置的签名凭据和验证密钥:

var credential = await _keys.GetSigningCredentialsAsync();
var key = credential.Key as Microsoft.IdentityModel.Tokens.X509SecurityKey;

var descriptor = new SecurityTokenDescriptor
{
    AppliesToAddress = result.Client.ClientId,
    Lifetime = new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddSeconds(result.Client.IdentityTokenLifetime)),
    ReplyToAddress = result.Client.RedirectUris.First(),
    SigningCredentials = new X509SigningCredentials(key.Certificate, result.RelyingParty.SignatureAlgorithm, result.RelyingParty.DigestAlgorithm),
    Subject = outgoingSubject,
    TokenIssuerName = _contextAccessor.HttpContext.GetIdentityServerIssuerUri(),
    TokenType = result.RelyingParty.TokenType
};