使用 Angular 发送到 Aspnet core 1.0 网站的 JWT

Posted

技术标签:

【中文标题】使用 Angular 发送到 Aspnet core 1.0 网站的 JWT【英文标题】:Using a JWT sent by Angular to an Aspnet core 1.0 web site 【发布时间】:2017-03-09 11:27:35 【问题描述】:

我正在将我用 (VS2013) MVC5 和 Angular 1 编写的旧应用程序迁移到 (VS2015) MVC 6 和 Angular 2。在我的 MVC 5 应用程序中,我曾经在我曾经使用以下代码行将其存储到会话的 Web UI 端:

 //Store token details
 [HttpPost]
 public void EvaluateToken(string token)
 
    JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
    SecurityToken st = tokenHandler.ReadToken(token);
    var tokenData = ((JwtSecurityToken)st);
    var claims = tokenData.Claims.Where(t => t.Type.Equals(" ")).ToList();

    ClaimsIdentity cIdentity = new ClaimsIdentity(DefaultAuthenticationTypes.ExternalBearer);
    ci.AddClaims(claims);
    AuthenticationManager.SignIn(new AuthenticationProperties()  IsPersistent = true , cIdentity );

    string user = "//get username from token";

    ClaimsPrincipal cPrincipal = new ClaimsPrincipal (cIdentity);

    //write to cookie
    SessionSecurityToken sst = new SessionSecurityToken(cPrincipal , TimeSpan.FromMinutes(20));
    sst.IsReferenceMode = true; 
    SessionAuthenticationModule ssm = FederatedAuthentication.SessionAuthenticationModule;
    ssm.WriteSessionTokenToCookie(sst);
 

上面的代码适用于非 aspnetcore 项目,我可以使用以下代码行从授权上下文中检索声明,其中 action 包含在被调用的相应操作方法上的属性上的声明集,并且val 包含一个布尔值 true 或 false 指定声明在 context.Principal 中是否存在。

public class CustomClaimsAuthorizationManager: ClaimsAuthorizationManager


    public override bool CheckAccess(AuthorizationContext context)
    
        var action = context.Action.First().Value;
        bool val= context.Principal.HasClaim(" ", action);
        return val;
    

但是,当迁移到核心项目时,我收到此错误:

ID1061:HttpContext.Current 为空。此代码路径仅在以下情况下有效 在 ASP.NET 的执行上下文中。

在我的 EvaluateToken 方法中的这行代码:

SessionAuthenticationModule ssm = FederatedAuthentication.SessionAuthenticationModule;

我需要这条线才能工作,以便当我尝试访问具有自定义声明属性的操作方法时,我应该能够评估令牌中的声明是否存在。如果无法将其按原样移动到 aspnet 核心,那么我想知道如何在 aspnet 核心中使用令牌来授权访问仅具有传入令牌和受众、颁发者和密钥的特定视图用于生成令牌。该文档指定添加自定义策略,并且似乎采用了不同的路径。我不确定如何使用这种逻辑将声明存储在 UI 端的主体对象中,以便在 UI 端的视图之间移动时使用它。

这是我在配置方法中的 aspnet 核心 Web 项目上的 startup.cs 文件中的内容:

var issuer = "localhost";
var aud = "localhost";
var secret = "SecretValueHere";

var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret));

            var jwtBearerOptions = new JwtBearerOptions
            
                AutomaticAuthenticate = true,
                AutomaticChallenge = true,
                Audience = aud ,
                ClaimsIssuer = issuer,
                TokenValidationParameters = new TokenValidationParameters
                
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = signingKey,
                    ValidateIssuer = true,
                    ValidIssuer = issuer,
                    ValidateAudience = true,
                    ValidAudience = aud ,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero,
                    RequireExpirationTime = true  
                
            ;

            app.UseJwtBearerAuthentication(jwtBearerOptions);

【问题讨论】:

【参考方案1】:

ID1061:HttpContext.Current 为空。此代码路径仅在以下情况下有效 在 ASP.NET 的执行上下文中。

HttpContext.Current 在 Aspnet Core 中不可用。见Access HttpContext.Current。

我需要这条线才能工作,以便当我尝试访问操作方法时 具有我的自定义声明属性,我应该能够评估是否 令牌中的声明是否存在

您只需要(我假设声明存储在令牌中):

    JWT 认证中间件(你已经试过了) Claims Based Authorization。

如果您需要未存储在令牌中的其他声明,则可以使用 jwt 身份验证中间件的 Claims Transformation 或 OnTokenValidated 事件。

【讨论】:

我使用的是ClaimsPrinciplePermission 属性,而不是Authorize 属性。有没有办法在aspnet核心中使用ClaimsPrinciplePermission?还是我必须将所有这些都移到授权? 在您的案例中使用 ClaimsPrinciplePermission 是否有特殊原因?如果不是,我会使用授权属性。 我正在将遗留代码迁移到 aspnet 核心中。要做到这一点,将有很多返工。在相关说明中,我已经尝试了您提到的内容,在这里使用此示例进行登录(andrewlock.net/introduction-to-authentication-with-asp-net-core)和此示例(docs.asp.net/en/latest/security/authorization/policies.html)来评估传入的声明。但是,AuthorizationHandlerContext context 属性中的声明列表没有结果。这是为什么呢? 确保 jwt 不记名身份验证正常工作并设置主体声明。您可以查看 User.Claims 进行检查。您也可以发布您尝试的代码。

以上是关于使用 Angular 发送到 Aspnet core 1.0 网站的 JWT的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASPNET.Core Web 应用程序中发送带有 CORS 标头的 HTTP 4xx-5xx 响应?

在Angular 4中将数据发送到JAVA post REST API时出现CORS错误

将 REST-Call 从 Angular 发送到 Camunda Rest-Engine 时出现 CORS 错误

Ionic 2 / Angular 2 / CORS:HTTP 标头未随请求一起发送

跨域资源共享错误 (CORS) Angular 10

AspNet.Cors 和 AspNet.WebApi.Cors 有啥区别?