当过滤标识2.0要求票在的WebAPI应用程序?(Where to filter Identity

2019-09-29 16:21发布

ASP.NET应用程序使用OWIN允许多个身份源(Facebook,谷歌等)。 大多数提供商specifc信息的来源提供无关我的应用程序,甚至可能大,我不希望在我的cookie的会话。 我的应用程序主要的WebAPI,但我怀疑这个问题同样适用于MVC和的WebForms。

现在,我需要的是一个整数帐户ID。 在哪里/我要重建的身份,外部认证后?

例如,这里是我可以过滤声明的一种方法:

public ReplaceExistingClaims(ClaimsIdentity identity) {
{
    Claim customClaim = GetCustomClaimFromDbForIdentity(identity);
    foreach (Claim claim in ClaimsIdentity.Claims) ClaimsIdentity.RemoveClaim(claim);
    ClaimsIdentity.AddClaim(customClaim);
}

而下面是两个不同的地方,我可以注入这些说法的变化:

var facebookAuthenticationOptions = new FacebookAuthenticationOptions
{
    Provider = new FacebookAuthenticationProvider
    {
        OnAuthenticated = context =>
        {
            ReplaceExistingClaims(context.Identity);
            return Task.FromResult(0);
        }
    }
};

以上,我知道我能勾从单个供应商Startup ,如果它提供了一个Authenticated事件。 我有这个两个概念问题。 一:它要求我分开来写来包装我的代码为每个提供我插上二:没有要求对供应商提供此事件。 这两个让我觉得必须有我的代码不同的预期插入点。

public ActionResult ExternalLoginCallback(string returnUrl)
{
    ReplaceExistingClaims((ClaimsIdentity)User.Identity);
    new RedirectResult(returnUrl);
}

以上,我知道我可以把代码ExternalLoginCallback 。 但出现这种情况的原因有两个为时已晚。 一:用户已经发行的票,我认为无效,但默认的[Authorized] ,因为它是由我签字,而现在他们正在请求我的网站与它认为有效。 甚至有可能是这里的比赛条件。 二:有没有保证,浏览器将访问这个重定向,并且我从设计的角度来看,如果喜欢它没有到,如简化我的WebAPI的客户端代码。

据我所知,最好的解决方案将满足以下要求:

  1. 相同的代码适用于所有的供应商
  2. 客户端接收从我的服务器我的自定义票据(如没有图像索赔)
  3. 客户将永远不会收到来自我的服务器,另一张机票格式
  4. 验证过程需要尽可能小的HTTP往返
  5. 令牌刷新等核心身份功能仍然可用
  6. 一旦用户是[Authorize] d,没有进一步的帐户变换是必要
  7. 数据库/存储库访问票生成过程中是可行的

有些我研究,我自己的注释:

  • 如何访问Microsoft.Owin.Security.xyz OnAuthenticated方面AddClaims值?
  • https://katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin.Security.Facebook/FacebookAuthenticationHandler.cs
  • https://katanaproject.codeplex.com/workitem/82
  • https://www.simple-talk.com/dotnet/.net-framework/creating-custom-oauth-middleware-for-mvc-5/

Answer 1:

你必须实现DelegationHandler,把你所有的认证程序在里面。

注册在应用程序启动(DI功能已启用):

private static void RegisterHandlers(HttpConfiguration config)
{
    var authHandler = new MyFacebookAuthHandler();
    config.MessageHandlers.Add(authHandler);
}

这是实现的例子:

public class MyFacebookAuthHandler : DelegationHandler
{
    public override sealed Task<HttpResponseMessage> OnSendAsync(HttpRequestMessage request,
                                                                 CancellationToken cancellationToken)
    {
        try
        {
            // Process credentials
            // Probably you have to save some auth information to HttpContext.Current
            // Or throw NotAuthorizedException
        }
        catch(NotAuthorizedException ex)
        {
            return request.CreateErrorResponse(HttpStatusCode.Unauthorized, ex).ToCompletedTask();
        }
        catch (Exception ex)
        {
            return request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex).ToCompletedTask();
        }

        return base.OnSendAsync(request, cancellationToken);
    }
}


Answer 2:

ClaimsAuthenticationManager类是专门为这个。

https://msdn.microsoft.com/en-us/library/system.security.claims.claimsauthenticationmanager(v=vs.110).aspx

从该参考代码示例:

class SimpleClaimsAuthenticatonManager : ClaimsAuthenticationManager
{
    public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
    {
        if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated == true)
        {
            ((ClaimsIdentity)incomingPrincipal.Identity).AddClaim(new Claim(ClaimTypes.Role, "User"));
        }
        return incomingPrincipal; 
    }
}


文章来源: Where to filter Identity 2.0 claim ticket in a WebAPI app?