[英]RestSharp with JWT-authentication doesn't work
This is the page where I "learned" how to do it: https://stormpath.com/blog/token-authentication-asp-net-core 这是我“学习”如何做的页面: https : //stormpath.com/blog/token-authentication-asp-net-core
But for me this is not working (doesn't work with Fiddler, too) There is this controller for my ApplicationUser-model: 但是对我来说这不起作用(也不适用于Fiddler)我的ApplicationUser-model有这个控制器:
[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);
}
}
and there's my wrapper for RestSharp to get all applicationusers: 我的包装是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;
}
From my web-client application I want to login with JWT (Token-Authentication) what works. 我想从Web客户端应用程序中使用JWT(令牌身份验证)登录。 After login I get eg this access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJURVNUIiwianRpIjoiZTBjYjE0NjgtYzBmOS00ZTM4LTg4ZjgtMGM4ZjNmYjMyNjZmIiwiaWF0IjoxNDcwOTUwMTA0LCJuYmYiOjE0NzA5NTAxMDQsImV4cCI6MTQ3MDk1MDQwNCwiaXNzIjoiRXhhbXBsZUlzc3VlciIsImF1ZCI6IkV4YW1wbGVBdWRpZW5jZSJ9.a9_JK2SG3vzc6NSOB0mZXqHlM9UAEXUHHrrijAQUsX0
登录后,我得到这个如的access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJURVNUIiwianRpIjoiZTBjYjE0NjgtYzBmOS00ZTM4LTg4ZjgtMGM4ZjNmYjMyNjZmIiwiaWF0IjoxNDcwOTUwMTA0LCJuYmYiOjE0NzA5NTAxMDQsImV4cCI6MTQ3MDk1MDQwNCwiaXNzIjoiRXhhbXBsZUlzc3VlciIsImF1ZCI6IkV4YW1wbGVBdWRpZW5jZSJ9.a9_JK2SG3vzc6NSOB0mZXqHlM9UAEXUHHrrijAQUsX0
without the Authorize
-attribute I get the ApplicationUser, but when setting the Attribute, the result is null (since the web-api is not getting called) 没有Authorize
-attribute,我得到了ApplicationUser,但是在设置Attribute时,结果为null(因为未调用web-api)
the wrapper-call looks like this: 包装器调用如下所示:
//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);
and here userAfterLogin
is null. 此处userAfterLogin
为null。
I'm trying to get the login since two weeks but I still don't get it right.. 自两个星期以来,我一直在尝试获取登录信息,但仍然无法正确登录。
Any idea what I'm doing wrong? 知道我在做什么错吗? Maybe a wrong request-header-value for authorization? 也许是错误的授权请求标头值?
Update 更新资料
this is my Startup.Configure where I configured to use the Bearer / JWT: 这是我的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?}");
});
}
If you recive authorizacion error or using postman you realize that you are being asked to redirect to login just decorate your class with: 如果您收到授权错误或使用邮递员,您将意识到您被要求重定向到登录名,只需使用以下命令装饰您的班级:
[Authorize(AuthenticationSchemes = "Bearer")]
By default .Net uses cookie based auth, with that annotation you swicht to token based one 默认情况下,.Net使用基于cookie的身份验证,带有该注释的您将粘贴到基于令牌的令牌中
So you are using 2 middlewares for identity. 因此,您正在使用2个中间件进行身份验证。 One provided by asp.net identity (cookie based) and another token based. 一个由asp.net身份提供(基于cookie),另一个由令牌提供。 Now both of the middleware use the same attribute for handling the request [Authorize]. 现在,两个中间件都使用相同的属性来处理请求[授权]。 More precisely look at the code here 更精确地看一下这里的代码
https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs
for JWTBearer 对于JWTBearer
and 和
https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs
for Cookie 饼干
Because both are activated in middleware pipeline the principal will have the data when you send auth token or cookie. 因为两者都在中间件管道中激活,所以当您发送身份验证令牌或cookie时,主体将拥有数据。
But because both of them are active either of them will return Unauthorized for the request that doesnt have cookie or JwtBearer. 但是因为它们都处于活动状态,所以对于没有cookie或JwtBearer的请求,它们中的任何一个都将返回Unauthorized。
For the solution you are looking for you need to create a middleware on top of existing cookie and token based to route the request to either based on if authorization header is present. 对于您要寻找的解决方案,您需要在现有的cookie和令牌的基础上创建一个中间件,以根据是否存在授权标头将请求路由到其中一个。
In Fiddler you would see, if you are redirected to login page (it would report 2 Results, one with 302 (redirect) and then the 404 - is that the case? 在Fiddler中,您将看到是否将您重定向到登录页面(它将报告2个结果,其中一个为302(重定向),然后为404)-是这样吗?
You have DebugLogger activated, so try AddDebug(LogLevel.Trace) and view the Debug output window, it is very helpful in analysing which of authentication steps fail. 您已激活DebugLogger,因此请尝试AddDebug(LogLevel.Trace)并查看“调试”输出窗口,这对于分析哪些身份验证步骤失败非常有帮助。 It also shows if authentication fails or authorization, and if has a valid token etc. So it points to the direction to look for problems. 它还显示身份验证是否失败或授权,以及是否具有有效的令牌等。因此,它指出了查找问题的方向。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.