c# - 具有 JWT 身份验证的 RestSharp 不起作用

标签 c# asp.net-core asp.net-web-api2 access-token restsharp

这是我“学习”如何操作的页面:https://stormpath.com/blog/token-authentication-asp-net-core

但对我来说这不起作用(也不适用于 Fiddler) 我的 ApplicationUser 模型有这个 Controller :

[Authorize] //works when it's not set, doesn't work when it's set
[Route("api/[controller]")]
public class ApplicationUserController : Controller
{
    private IRepository<ApplicationUser> _applicationUserRepository;

    public ApplicationUserController(IRepository<ApplicationUser> applicationUserRepository)
    {
        _applicationUserRepository = applicationUserRepository;
    }

    [HttpGet("{id}")]
    public ApplicationUser Get(int id)
    {
        return _applicationUserRepository.Get(id);
    }
}

还有我的 RestSharp 包装器来获取所有应用程序用户:

public Task<T> GetResponseContentAsync<T>(string resource, int id) where T : new()
{
    RestRequest request = new RestRequest($"{resource}/{{id}}", Method.GET);
    request.AddUrlSegment("id", id);
    if (!AuthenticationToken.IsNullOrEmpty(true))
    {
        request.AddHeader("Authorization", string.Format("Bearer {0}", AuthenticationToken));
        _client.Authenticator = new JwtAuthenticator(AuthenticationToken);
        _client.Authenticator.Authenticate(_client, request);
    }

    TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
    _client.ExecuteAsync<T>(request, response =>
    {
        tcs.SetResult(response.Data);
    });
    return tcs.Task;
}

在我的网络客户端应用程序中,我想使用有效的 JWT( token 身份验证)登录。登录后我得到例如这个access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJURVNUIiwianRpIjoiZTBjYjE0NjgtYzBmOS00ZTM4LTg4ZjgtMGM4ZjNmYjMyNjZmIiwiaWF0IjoxNDcwOTUwMTA0LCJuYmYiOjE0NzA5NTAxMDQsImV4cCI6MTQ3MDk1MDQwNCwiaXNzIjoiRXhhbXBsZUlzc3VlciIsImF1ZCI6IkV4YW1wbGVBdWRpZW5jZSJ9.a9_JK2SG3vzc6NSOB0mZXqHlM9UAEXUHHrrijAQUsX0

没有 Authorize-attribute 我得到了 ApplicationUser,但是当设置 Attribute 时,结果为 null(因为没有调用 web-api)

包装调用看起来像这样:

//this works, token-value is set
string token = new RepositoryCall("http://localhost:54008/").Login("token", "TEST", "TEST123");

string accessToken = JsonConvert.DeserializeObject<Dictionary<string, string>>(token)["access_token"];
ViewData["Result"] = accessToken;

ApplicationUser userAfterLogin = await new RepositoryCall("http://localhost:54008/api") 
    { AuthenticationToken = accessToken }
    .GetResponseContentAsync<ApplicationUser>("ApplicationUser", 2);

此处 userAfterLogin 为空。

两周以来我一直在尝试获取登录名,但我仍然没有成功..

知道我做错了什么吗?可能是错误的授权请求 header 值?

更新

这是我的 Startup.Configure,我在其中配置使用 Bearer/JWT:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();

    app.UseIdentity();
    var secretKey = "mysupersecret_secretkey!123";
    var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));

    // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
    var options = new TokenProviderOptions
    {
        Audience = "ExampleAudience",
        Issuer = "ExampleIssuer",
        SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),
    };


    var tokenValidationParameters = new TokenValidationParameters
    {
        // The signing key must match!
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = signingKey,

        // Validate the JWT Issuer (iss) claim
        ValidateIssuer = true,
        ValidIssuer = "ExampleIssuer",

        // Validate the JWT Audience (aud) claim
        ValidateAudience = true,
        ValidAudience = "ExampleAudience",

        // Validate the token expiry
        ValidateLifetime = true,

        // If you want to allow a certain amount of clock drift, set that here:
        ClockSkew = TimeSpan.Zero
    };


    app.UseJwtBearerAuthentication(new JwtBearerOptions
    {
        AutomaticAuthenticate = true,
        AutomaticChallenge = true,
        TokenValidationParameters = tokenValidationParameters
    });

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AutomaticAuthenticate = true,
        AutomaticChallenge = true,
        AuthenticationScheme = "Cookie",
        CookieName = "access_token",
        TicketDataFormat = new CustomJwtDataFormat(
            SecurityAlgorithms.HmacSha256,
            tokenValidationParameters)
    });

    app.UseMiddleware<TokenProviderMiddleware>(Options.Create(options));
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

最佳答案

如果您收到授权错误或使用 postman ,您会意识到您被要求重定向到登录只需用以下方式装饰您的类(class):

[Authorize(AuthenticationSchemes = "Bearer")]

默认情况下 .Net 使用基于 cookie 的身份验证,使用该注释你可以切换到基于 token 的身份验证

关于c# - 具有 JWT 身份验证的 RestSharp 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38906404/

相关文章:

c# - .Net核心2.2 : how to change characterset in EF codefirst approach

C#/.Net TryValidateObject - 如何本地化?

azure - 如何使用 Linux 操作系统修复 Azure 应用服务中的问题 "IOException: Read-only file system"ASP.NET Core?

c# - 注入(inject) DbContext 时无法访问 ASP.NET Core 中已处置的对象

iis - 本地IIS添加SSL后 "Unable to start debugging on the Web server"

asp.net - 如何调用 URL 末尾带有点的 Web API 操作?

c# - 检测 WebBrowser 控件中 HTML 内容的实际大小

c# - 仅当文件存在时才加载资源字典

c# - HttpRuntime.Cache 等同于 asp.net 5、MVC 6

c# - 在 ASP.NET Web API2 webservice 中实现 OAuth 访问 token