我看到过与此问题类似的话题,但是我没有运气解决它。 登录工作成功,但是当我尝试获取主页中登录用户的数据时,出现此错误401未经授权,邮递员中也显示相同的错误
我的startup.cs
public class Startup
{
private string _connectionString=null;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//Inject AppSettings
services.Configure<ApplicationSettings>(Configuration.GetSection("ApplicationSettings"));
_connectionString = Configuration["secretConnectionstring"];
//without this it will define for example id to Id
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options => {
var resolver = options.SerializerSettings.ContractResolver;
if (resolver != null)
(resolver as DefaultContractResolver).NamingStrategy = null;
});
services.AddEntityFrameworkNpgsql()
.AddDbContext<ApiContext>(
opt => opt.UseNpgsql(_connectionString));
services.AddEntityFrameworkNpgsql()
.AddDbContext<AuthentificationContext>(
options => options.UseNpgsql(_connectionString));
services.AddDefaultIdentity<ApplicationUser>()
.AddEntityFrameworkStores<AuthentificationContext>();
services.Configure<IdentityOptions>(options => {
options.Password.RequireDigit = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 4;
});
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
// Jwt Authentification
var key = Encoding.UTF8.GetBytes(Configuration["ApplicationSettings:JWT_Secret"].ToString());
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x=> {
x.RequireHttpsMetadata = false;
x.SaveToken = false;
x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
services.AddTransient<dataSeed>();
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, dataSeed seed)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
// global policy - assign here or on each controller
app.UseCors("CorsPolicy");
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
app.UseAuthentication();
}
}
}
UserprofileController
{
[Route("api/[controller]")]
[ApiController]
public class UserProfileController : ControllerBase
{
private UserManager<ApplicationUser> _userManager;
public UserProfileController(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
[HttpGet]
[Authorize]
//GET : /api/UserProfile
public async Task<Object> GetUserProfile()
{
string userId = User.Claims.First(c => c.Type == "UserID").Value;
var user = await _userManager.FindByIdAsync(userId);
return new
{
user.fullName,
user.Email,
user.UserName
};
}
}
}
UserServices
headers = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Accept': 'application/json'
})
}
readonly BaseUrl = 'http://localhost:53847/api';
constructor(private fb: FormBuilder, private http: HttpClient) { }
formModel = this.fb.group({
UserName: ['', Validators.required],
Email: ['', Validators.email],
fullName: ['', Validators.required],
Passwords: this.fb.group({
Password: ['',[Validators.required, Validators.minLength(4)]],
ConfirmPassword: ['', Validators.required],
}, { validator : this.comparePasswords})
});
comparePasswords(fb: FormGroup) {
let confirmPswdCtrl = fb.get('ConfirmPassword');
//passowrdMismatch
//confirmPswdCtrl.errors={passowrdMismatch:true}
if (confirmPswdCtrl.errors == null || 'passowrdMismatch' in confirmPswdCtrl.errors) {
if (fb.get('Password').value != confirmPswdCtrl.value)
confirmPswdCtrl.setErrors({ passowrdMismatch: true });
else
confirmPswdCtrl.setErrors(null);
}
}
register() {
var body = {
UserName: this.formModel.value.UserName,
Email: this.formModel.value.Email,
fullName: this.formModel.value.fullName,
Password: this.formModel.value.Passwords.Password,
};
return this.http.post(this.BaseUrl + '/ApplicationUser/Register', body, this.headers);
}
login(formData) {
return this.http.post(this.BaseUrl + '/ApplicationUser/Login', formData, this.headers);
}
getUserProfile() {
var tokenHeader = new HttpHeaders({ 'Authorization': 'Bearer' + localStorage.getItem('token'), 'Content-Type': 'application/json' });
return this.http.get(this.BaseUrl + '/UserProfile', { headers: tokenHeader });
}
}
ApplicationUserController PostMethod
[HttpPost]
[Route("Login")]
//POST : /api/ApplicationUser/Login
public async Task<IActionResult> Login(LoginModel model)
{
var user = await _userManager.FindByNameAsync(model.UserName);
if (user != null && await _userManager.CheckPasswordAsync(user, model.Password))
{
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim("UserID",user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.JWT_Secret)), SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(securityToken);
return Ok(new { token });
}
else
return BadRequest(new { message = "Username or password is incorrect." });
}
}
帮助Plz .. Thx
答案 0 :(得分:1)
我看到的一个问题在这里:
var tokenHeader = new HttpHeaders({ 'Authorization': 'Bearer' + localStorage.getItem('token'), 'Content-Type': 'application/json' });
指定Bearer
令牌时,您需要在Bearer
和令牌本身之间留一个空格,以便结果看起来像this:
Authorization: <type> <credentials>
在您的情况下,这将转换为:
Authorization: Bearer token
但是,如果您看一下上面的代码,您会看到您实际上将像这样提供它:
Authorization: Bearertoken
这是行不通的。因此,将代码更改为:
var tokenHeader = new HttpHeaders({ 'Authorization': 'Bearer ' + localStorage.getItem('token'), 'Content-Type': 'application/json' });
// ---------------------------------------------------------^ Notice I've added a space here.
答案 1 :(得分:0)
就我而言,我没有收到任何错误,并且一切似乎都可以正常工作,但是我的API每次都返回401。 在这个问题上,我的脑袋撞了很多。 我有...
[Authorize]
在我的Controller上,发现该站点正在尝试使用cookie身份验证,因此尽管我的JWT工作正常,但是缺少cookie身份验证使它失败了。 我将属性更改为...
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
并解决了该问题,因为现在控制器会忽略Cookie身份验证,而只专注于jwt。 希望这对某人有帮助
答案 2 :(得分:0)
我发现更改语句顺序是我的问题。 Configure()要求ASP.NET Core中间件的顺序正确。
此DID不起作用,需要我向每个控制器添加[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
...
app.UseAuthorization();
app.UseAuthentication();
这确实有效:
app.UseAuthentication();
app.UseAuthorization();