通过我的控制器

时间:2017-02-08 14:55:01

标签: asp.net-core openid-connect

我正在使用已打开的连接中间件与第三方oidc提供商进行身份验证,所有内容都按照我的预期启动并运行。在令牌交换期间,我交换了我的auth代码以获得成功的访问令牌,但是我需要存储此承载令牌以便稍后在后续请求中使用。令牌交换是作为我的启动类的一部分(通过在OpenIdConnectEvents方法中覆盖OnAuthorizationCodeReceived方法)在asp.net核心项目中完成的,我需要在我的控制器中存储和访问该令牌。 / p>

由于目前还没有“会话”,从启动类中存储此令牌值并使其在我的控制器中可访问的最有效(或推荐方式)是什么?

我曾尝试使用IMemoryCache但是尽管在此启动阶段将值放入缓存中,但当我尝试在控制器中访问该缓存时,它始终为空。

是否有一种更好/首选的方法可以将值保存在启动类中,以便以后在生命周期中使用?

我可以在HttpContext.Authentication.HttpAuthenticationFeature.Handler.Options中看到我可以访问oidc的所有OpenIdConnectOptions属性和设置,但在令牌交换后我无处可查看存储的实际令牌值。

2 个答案:

答案 0 :(得分:2)

我使用与Auth0和JWT类似的方法。我在声明服务器上存储了一些app_metadata,检索并在我的控制器中为每个请求使用这些值。

Startup.cs配置

var options = new JwtBearerOptions
        {
            Audience = AppSettings.Auth0ClientID,
            Authority = AppSettings.Auth0Domain
        };

        app.UseJwtBearerAuthentication(options);
        app.UseClaimsTransformation(new ClaimsTransformationOptions
        {
            Transformer = new Auth0ClaimsTransformer()
        });

AdminClaimType

public abstract class AdminClaimType : Enumeration
{
    public static readonly AdminClaimType AccountId = new AccountIdType();
    public static readonly AdminClaimType ClientId = new ClientIdType();
    public static readonly AdminClaimType IsActive = new IsActiveType();

    private AdminClaimType(int value, string displayName) : base(value, displayName)
    {

    }

    public abstract string Auth0Key { get; }
    public abstract string DefaultValue { get; }

    private class AccountIdType : AdminClaimType
    {
        public AccountIdType() : base(1, "AccountId")
        {             
        }

        public override string Auth0Key => "accountId";
        public override string DefaultValue => "0";
    }

    private class ClientIdType : AdminClaimType
    {
        public ClientIdType() : base(2, "ClientId")
        {
        }

        public override string Auth0Key => "clientId";
        public override string DefaultValue => "0";
    }

    private class IsActiveType : AdminClaimType
    {
        public IsActiveType() : base(3, "IsActive")
        {
        }

        public override string Auth0Key => "isActive";
        public override string DefaultValue => "false";
    }
}

Auth0ClaimsTransformer

public class Auth0ClaimsTransformer : IClaimsTransformer
{

    private string _accountId = AdminClaimType.AccountId.DefaultValue;
    private string _clientId = AdminClaimType.ClientId.DefaultValue;
    private string _isActive = AdminClaimType.IsActive.DefaultValue;

    public Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
    {
        //TODO: Clean up and simplify AdminClaimTypes Transformer
        foreach (var claim in context.Principal.Claims)
        {
            switch (claim.Type)
            {
                case "accountId":
                    _accountId = claim.Value ?? _accountId;
                    break;
                case "clientId":
                    _clientId = claim.Value ?? _clientId;
                    break;
                case "isActive":
                    _isActive = claim.Value ?? _isActive;
                    break;
            }
        }
        ((ClaimsIdentity)context.Principal.Identity)
            .AddClaims(new Claim[]
            {
                new Claim(AdminClaimType.AccountId.DisplayName, _accountId),
                new Claim(AdminClaimType.ClientId.DisplayName, _clientId), 
                new Claim(AdminClaimType.IsActive.DisplayName, _isActive)
            });

        return Task.FromResult(context.Principal);
    }

BaseAdminController

//[Authorize]
[ServiceFilter(typeof(ApiExceptionFilter))]
[Route("api/admin/[controller]")]
public class BaseAdminController : Controller
{
    private long _accountId;
    private long _clientId;
    private bool _isActive;

    protected long AccountId
    {
        get
        {
            var claim = GetClaim(AdminClaimType.AccountId);
            if (claim == null)
                return 0;

            long.TryParse(claim.Value, out _accountId);
            return _accountId;
        }
    }

    public long ClientId
    {
        get
        {
            var claim = GetClaim(AdminClaimType.ClientId);
            if (claim == null)
                return 0;

            long.TryParse(claim.Value, out _clientId);
            return _clientId;
        }
    }

    public bool IsActive
    {
        get
        {
            var claim = GetClaim(AdminClaimType.IsActive);
            if (claim == null)
                return false;

            bool.TryParse(claim.Value, out _isActive);
            return _isActive;
        }
    }

    public string Auth0UserId
    {
        get
        {
            var claim = User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
            return claim == null ? string.Empty : claim.Value;
        }
    }

    private Claim GetClaim(AdminClaimType claim)
    {
        return User.Claims.FirstOrDefault(x => x.Type == claim.DisplayName);
    }
}

现在在我从BaseAdminController继承的控制器类中,我可以访问:

  • ACCOUNTID
  • 客户端Id
  • IsActive
  • Auth0UserId
  • 我要添加的任何其他内容

希望这有帮助。

答案 1 :(得分:1)

所以我明白了。它可以通过AuthenticationManager在HttpContext上使用:

var idToken = ((AuthenticateInfo)HttpContext.Authentication.GetAuthenticateInfoAsync("Cookies").Result).Properties.Items[".Token.id_token"];

工作待遇:)