API arbeitet nicht mit [autorize], funktioniert aber gut mit [donlanonymous] in ASP.NET CORE 3.1C#

Ein Treffpunkt für C#-Programmierer
Anonymous
 API arbeitet nicht mit [autorize], funktioniert aber gut mit [donlanonymous] in ASP.NET CORE 3.1

Post by Anonymous »

Ich arbeite an einer API mit ASP.NET Core 3.1 und habe mehrere Controller erstellt. Diese API verwendet ein JWT -Bearer -Token, um den Anrufer zu authentifizieren, wobei Logintroller drei Endpunkte Login , Fehler und Menulist (Liste der Menüs gemäß der Rolle) enthält. Nur dieser Controller funktioniert einwandfrei wie der Menulist gibt einen HTTP 401 -Fehler zurück, wenn der Benutzer nicht angemeldet ist, und wenn der Benutzer angemeldet ist, funktioniert er so, wie es sollte. />
TypeError: Versäumt, < /p>
< /blockquote>
zu holen Ich habe versucht, dieses Problem lokal zu debuggen, aber die Anfrage trifft nicht einmal die Funktion "Controller", wie ich den Breakpoint auf den Controller findet, um herauszufinden, wo das Problem nicht zu einem Withan -Withan -Withan -Wachstum ist. Abrufen Daten normal.

Code: Select all

LoginController
:

Code: Select all

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using BAL.Interfaces;
using ViewModel.Model;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Authorization;
using System.Text;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Http;
using DAL.DBEntities;
using Newtonsoft.Json;
using Microsoft.Extensions.Logging;
using ViewModel.vt_Common;

namespace IndigoAPI.Controllers
{
public class LoginController : BaseController
{
#region StructureWork
private readonly ILoginRepository LoginRepository;              // Login Repository Interface
public readonly UserManager userManager;       // ASP Identity
private readonly RoleManager roleManager;         // ASP Identity
private readonly IConfiguration _configuration;                 // Configuration property
private readonly ILogger _logger;              // Logger Dependance Injection
private readonly IExceptionRepository ExceptionRepository;            // for exception log

public LoginController(ILogger logger, UserManager userManager, RoleManager roleManager, IExceptionRepository ExceptionRepository, IConfiguration configuration, ILoginRepository LoginRepository)
{
this.LoginRepository = LoginRepository;
this.ExceptionRepository = ExceptionRepository;
this.userManager = userManager;
this.roleManager = roleManager;
_configuration = configuration;
_logger = logger;
}
#endregion

// me
/// 
///  This method is created to authenticate user and return token.
///  This method uses asp authentication
/// 
/// 

/// 
[HttpPost]
[Route("Login")]
[AllowAnonymous]
public async Task Login([FromBody] LoginForm Header)
{
try
{
if (ModelState.IsValid)
{
var user = await userManager.FindByNameAsync(Header.UserName);  // find user name

var userRoles = await userManager.GetRolesAsync(user);  // get role

if (userRoles.Count > 0)
{
if (user != null && await userManager.CheckPasswordAsync(user, Header.Password))
{
if (await LoginRepository.IsUserActive(Header.UserName) != null)
{
List menulist = new List();
menulist = await LoginRepository.getMenuList_byRole(userRoles[0]);  // get menu list from repo

List userPages = new List();
userPages = await LoginRepository.getPageListByRole(userRoles[0]);
UserPagesList.List = userPages;
var jsonstr = JsonConvert.SerializeObject(userPages);
TempData["UserPages"] = jsonstr;

if (menulist != null)
{
#region Claims
var hashPassword = await LoginRepository.getUserHashPassword(user.Id);
var password = vt_Common.DecryptCipherTextToPlainText(hashPassword);
#endregion

var authClaims = new List
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};    // create claims

foreach (var userRole in userRoles)
{
authClaims.Add(new Claim(ClaimTypes.Role, userRole));
}  // add roles in claims

string menu = "http://foo.it/claim/menulist";
authClaims.Add(new Claim(menu, JsonConvert.SerializeObject(menulist)));  // add menulist in claims

string pages = "http://foo.it/claim/pages";
authClaims.Add(new Claim(pages, JsonConvert.SerializeObject(userPages)));  // add menulist in claims

var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:Secret"]));  // create key

var token = new JwtSecurityToken(
issuer: _configuration["JWT:ValidIssuer"],
audience: _configuration["JWT:ValidAudience"],
expires: DateTime.Now.AddHours(3),
claims: authClaims,
signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
);  // create token

await LoginRepository.LastLogin(Header.UserName, this.HttpContext.Connection.RemoteIpAddress.ToString());

return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo,
ID = user.Id,
UserName = user.UserName,
Role = userRoles[0],
Menulist = menulist
});  // return
}
else
{
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = "No Menu Found." });
}
}
else
{
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = "User is not active." });
}
}
else
{
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = "Wrong user name or password." });
}
}
else
{
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = "Role Not Exist." });
}
}
else
{
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = "Fill the Required Fields." });
}
}
catch (Exception ex)
{
await ExceptionRepository.writeException(Controller(), ex.Message, CurrentUser.UserName, CurrentUser.UserIP);
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = ex.Message });
}
}

/// 
/// If user requested to unauthorized method this method will hit
/// 
/// 
[HttpGet]
[Route("error")]
public async Task Error()
{
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = "Unauthorized."  });
}

/// 
/// This method return menulist
/// 
/// 
[HttpGet]
[Route("MenuList")]
public async Task MenuList()
{
try
{
List menulist = new List();
menulist = await LoginRepository.getMenuList_byRole(CurrentUser.RoleName);  // get menu list from repo
return Json(new { status = true, data = menulist });
}
catch (Exception ex)
{
await ExceptionRepository.writeException(Controller(), ex.Message, CurrentUser.UserName, CurrentUser.UserIP);
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = ex.Message });
}
}
}
}
< /code>
UserController
: In diesem Controller wird GetUser keine Daten abgerufen, sondern GetRoles aufgrund der deglierigen Annotation:

Code: Select all

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using BAL.Interfaces;
using DAL.DBEntities;
using Microsoft.Extensions.Logging;
using ViewModel.Model;
using Microsoft.AspNetCore.Http;
using System;
using ViewModel.vt_Common;
using Microsoft.AspNetCore.Authorization;

namespace IndigoAPI.Controllers
{
public class UserController : BaseController
{
#region StructureWork
private readonly IUserRepository UserRepository;              // Login Repository Interface
public readonly UserManager userManager;       // ASP Identity
private readonly RoleManager roleManager;         // ASP Identity
private readonly ILogger _logger;              // Logger Dependance Injection
private readonly IExceptionRepository ExceptionRepository;            // for exception log

public UserController(ILogger logger, UserManager userManager, RoleManager roleManager, IExceptionRepository ExceptionRepository, IUserRepository UserRepository)
{
this.UserRepository = UserRepository;
this.ExceptionRepository = ExceptionRepository;
this.userManager = userManager;
this.roleManager = roleManager;
_logger = logger;
}
#endregion

/// 
/// This method will return user list
/// 
/// 
[HttpGet]
[Route("GetUser")]
public async Task GetUser()
{
try
{
List roles = new List();
roles = await UserRepository.getUser();
return Json(new { status = true, data = roles });
}
catch (Exception ex)
{
await ExceptionRepository.writeException(Controller(), ex.Message, CurrentUser.UserName, CurrentUser.UserIP);
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = ex.Message });
}
}

/// 
/// This method will return role list
/// 
/// 
[HttpGet]
[Route("GetRole")]
[AllowAnonymous]
public async Task GetRole()
{
try
{
List  roles = new List();
roles = await UserRepository.getRole();
return Json(new { status = true, data = roles });
}
catch (Exception ex)
{
await ExceptionRepository.writeException(Controller(), ex.Message, CurrentUser.UserName, CurrentUser.UserIP);
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = ex.Message });
}
}

/// 
/// This method will register users
/// 
/// 

/// 
[HttpPost]
[Route("CreateUser")]
public async Task CreateUser([FromBody] RegisterModel model)
{
try
{
var userExists = await userManager.FindByNameAsync(model.UserName);     //check user exist or not

if (userExists != null)
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "Error", Message = "User already exists!" });

ApplicationUser user = new ApplicationUser()
{
Email = model.UserEmail,
SecurityStamp = Guid.NewGuid().ToString(),
UserName = model.UserName
};

var result = await userManager.CreateAsync(user, model.UserPassword); //create user

if (result.Succeeded)
{
if (await roleManager.RoleExistsAsync(model.RoleName))
{
if (await roleManager.RoleExistsAsync(model.RoleName))
{
await userManager.AddToRoleAsync(user, model.RoleName);  //link role and user

model.UserPassword = vt_Common.EncryptPlainTextToCipherText(model.UserPassword);
userExists = await userManager.FindByNameAsync(model.UserName);

await UserRepository.createUpdateUser(model, userExists.Id, CurrentUser.UserName, CurrentUser.UserIP); //add user
//await UserRepository.createUpdateUser(model, userExists.Id, "aliyan", "172.16.200.235"); //add user
}
}
else
{
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = "Role Not Exist" });
}
}
else
{
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = result.ToString() });
}

return Ok(new Response { Status = "Success", Message = "User created successfully!" });

}
catch (Exception ex)
{
await ExceptionRepository.writeException(Controller(), ex.Message, CurrentUser.UserName, CurrentUser.UserIP);
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = ex.Message });
}
}

/// 
/// this method will update user
/// 
/// 
/// 
[HttpPut]
[Route("UpdateUser")]
public async Task UpdateUser([FromBody] RegisterModel model)
{
try
{
var olduserExists = await userManager.FindByIdAsync(model.ASPUserID);
var newUserExist = await userManager.FindByNameAsync(model.UserName);

if (olduserExists != null)
{
if (newUserExist == null || olduserExists == newUserExist)
{
model.UserPassword = "";
await UserRepository.createUpdateUser(model, model.ASPUserID, CurrentUser.UserName, CurrentUser.UserIP);  //add user
}
else
{
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = "User already exist" });
}
}
else
{
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = "User not exist" });
}

return Ok(new Response { Status = "Success", Message = "User updated successfully!" });
}
catch (Exception ex)
{
await ExceptionRepository.writeException(Controller(), ex.Message, CurrentUser.UserName, CurrentUser.UserIP);
return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "false", Message = ex.Message });
}
}
}
}
< /code>
Startup.cs
:

Code: Select all

using DAL.DBEntities;
using IndigoAPI.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System;
using System.Text;
using System.Threading.Tasks;

namespace IndigoAPI
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddControllersWithViews();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "IndigoAPI", Version = "v1"  });

c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Description = "Please enter JWT token in the field",
Name = "Authorization",
Type = SecuritySchemeType.ApiKey
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement {
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] {}
}
});
});

services.AddDbContext(options =>
options.UseSqlServer(Configuration.GetConnectionString("IndigoDB")));

services.AddIdentity(options =>
{
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = true;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequiredLength = 6;

options.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores()
.AddDefaultTokenProviders();

services.AddCors(options =>
{
options.AddPolicy("AllowAll", builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});

services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = Configuration["JWT:ValidAudience"],
ValidIssuer = Configuration["JWT:ValidIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Secret"]))
};

options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
Console.WriteLine("Authentication failed: " + context.Exception.Message);
return Task.CompletedTask;
},
OnChallenge = context =>
{
Console.WriteLine("Challenge error: " + context.Error + " - " + context.ErrorDescription);
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
Console.WriteLine("Token validated successfully");
return Task.CompletedTask;
}
};
});

services.AddAuthorization();

services.RegisterServices(Configuration);
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c =>  c.SwaggerEndpoint("/swagger/v1/swagger.json", "IndigoAPI v1"));
}

app.UseHttpsRedirection();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseCors("AllowAll");

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
< /code>
BaseController
:

Code: Select all

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using ViewModel.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Authentication;
using System.Data;
using ViewModel.vt_Common;
using System.Collections.Generic;
using System.Linq;
using System;
using DAL.Repositories;

namespace IndigoAPI.Controllers
{
[ApiController]
[Route("api/[controller]"), Authorize]
public class BaseController : Controller
{
private string Token;
private UserProfile User;

public UserProfile CurrentUser
{
get
{
User = new UserProfile();
User.UserName = vt_Common.getUserNameFromToken(Token);
User.RoleName = vt_Common.getUserRoleFromToken(Token);
User.UserIP = this.HttpContext.Connection.RemoteIpAddress.ToString();
User.MenuList = vt_Common.getMenuListDataTableFromJson(Token);
User.UserPages = vt_Common.getUserPagesDataTableFromJson(Token);
return User;
}
set
{
User = value;
}
}

protected string Controller()
{
return Convert.ToString(TempData["ControllerName"]);
}

protected string GetToken()
{
return Token;
}

public async override void OnActionExecuting(ActionExecutingContext filterContext)
{
try
{
var token = HttpContext.GetTokenAsync("access_token");

if (token.Result != null)
{
Token = token.Result.ToString();
var currentController = filterContext.RouteData.Values["controller"].ToString();
var currentAction = filterContext.RouteData.Values["action"].ToString();
TempData["ControllerName"] = currentController + "/" + currentAction;
string Page_URL = string.Empty;

Page_URL = currentController + "/" + currentAction;
if (Page_URL.ToLower() != "login/menulist")
{
List pages = new List();
pages = vt_Common.convertJsonToPageURLList(Convert.ToString(TempData["UserPages"]));
LoginRepository login = new LoginRepository();
pages = await login.getPageListByRole(CurrentUser.RoleName);
pages = UserPagesList.List;

var aa = Convert.ToString(TempData["UserPages"]);
var right = pages.Where(x => x.PageURL.ToLower() == Page_URL.ToLower()).FirstOrDefault();

if (right == null)
{
filterContext.Result = new RedirectResult("~/api/login/error");
}
}
}
}
catch (System.Exception e)
{
filterContext.Result = new RedirectResult("~/api/login/error");
}

base.OnActionExecuting(filterContext);
}

public override void OnActionExecuted(ActionExecutedContext context)
{
if (context.Exception != null)
{
//context.HttpContext.Trace.Write("Exception thrown");
}
}
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post