How to [Authorize] attribute work for authorization with owin token? - asp.net-web-api2

How to authorize attribute check token is valid or not?
public class TestController : ApiController
{
[HttpPost]
[Authorize]
public string TestMethod()
{
return "This is testing for authorization working flow...";
}
}
If token not valid then return
{
Message:"token is expired"
}

Related

Accessing JWT claims in ASP.NET Core Web API

My app consists of a Blazor WebAssembly SPA and an ASP.NET Core Web API. For the API I also use the repository pattern. Here's how UsersController.cs looks like:
namespace MyApp.Controllers
{
[Authorize]
[Route("[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
private IUserRepository userRepository;
public UsersController(IUserRepository userRepository)
{
this.userRepository = userRepository;
}
[HttpGet]
public async Task<IActionResult> GetUsers([FromBody] SearchSortFilter Options)
{
try
{
var users = await userRepository.GetUsers(Options);
return Ok(users);
}
catch (Exception ex)
{
return StatusCode(500, ex.Message);
}
}
}
}
While authentication and authorization with Azure AD B2C work very well, I need to access claims data from the JWT token as in the request header.
What is the best way I can do this? Do I just use Request.Authorization, then slice the string to leave out the Bearer part, before using JwtSecurityTokenHandler() to decode into claims?
I was wondering if there was anything like User.Indentity.Name that would allow me to access claims in an opinionated way rather than having to manually do string slicing and decode it.

Verify Antiforgery Token Inside Function

I'm using .netcore 3.0, currently i have an API that will accept external (without Antiforgery token) and internal (with Antiforgery token) call, in this case i will need to add [IgnoreAntiforgeryToken] on the api method and base on the request to determine whether to check the antiforgery token.
Would like to know is there anyway to validate the antiforgery token inside the api function? Thanks in advance.
As far as I know, if you want to call the Antiforgery class to validate the antiforgery token, you could directly call the IAntiforgery service in your api and then use ValidateRequestAsync to validate the token.
More details, you could refer to below codes:
1.Add services.AddHttpContextAccessor(); in the startup.cs ConfigureServices method
2.Add below codes in your controller:
public class HomeController : Controller
{
private readonly IAntiforgery _antiforgery;
private readonly IHttpContextAccessor _httpcontextaccessor;
public HomeController(IAntiforgery defaultAntiforgery, IHttpContextAccessor httpcontextaccessor)
{
_antiforgery = defaultAntiforgery;
_httpcontextaccessor = httpcontextaccessor;
}
public async Task<IActionResult> PrivacyAsync()
{
try
{
await _antiforgery.ValidateRequestAsync(_httpcontextaccessor.HttpContext);
}
catch (Exception)
{
throw;
}
return View();
}
}
I use the similar method as #Brando Zhang
var _antiforgery=(IAntiforgery)this.HttpContext.RequestServices.GetService(typeof(IAntiforgery));
var IsValid = _antiforgery.IsRequestValidAsync(this.HttpContext).Result;
return IsValid;

Resolve routes by named parameters

I have ASP Core 2.2 app. I defined controller:
using Microsoft.AspNetCore.Mvc;
namespace Web.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok();
}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
return Ok();
}
}
}
When I request with url /api/users/3 everything works fine, method GetById is called. But if I try to request /api/users?id=3 method Get is called and I don't know how to fix that. Moreover I would like to create two similar method different only by parameter name. For example public IActionResult GetById(int id) and public IActionResult GetByAge(int age) so I need strict routing by named parameters if possible. I don't want to implement custom middleware to resolve routes myself I wanna try to find ASP feature for that.
The url /api/users/3 : "3" is used as part of the route value .
The url /api/users?id=3: "3" is used as a query string in the url .
Attribute routing with Http[Verb] attributes is the value of which is part of the route value
You could change the Route attribute above the controller to specify action name like below :
[Route("api/[controller]/[action]")]
[ApiController]
public class UsersController : ControllerBase
{
// Get api/users/get
[HttpGet]
public IActionResult Get()
{
return Ok();
}
//Get api/users/GetById/3
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
return Ok();
}
}
Reference :https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-2.2

Custom Authorization Filter in .NET Core API

I want to authorize users before accessing any data using my core api, so I tried is using JWT authentication.
I have successfully generated token while signing in user using api and saved that token on client side in session, now whenever user wants to access any data using api, I'll send that token in header to api and I want to validate that JWT token using custom authorization filter. I have created custom authorization filter and applied it on my GetMenu api and I'm able to validate that token successfully but after token validation in authorization filter it is not hitting it on my GetMenu api.
Here is my AccountController code:
[Filters.Authorization]
[AllowAnonymous]
[HttpPost]
[Route("GetMenu")]
public IActionResult GetMenu(string clientid, int rolecode, string repcode)
{
//further process
}
Here is my Filters.Authorization code:
public class Authorization: AuthorizeAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext filterContext)
{
if (!ValidateToken(filterContext.HttpContext.Request.Headers["token"]))
{
filterContext.Result = new UnauthorizedResult();
}
}
}
I have breakpoints on OnAuthorization method and on GetMenu api.
I'm calling my GetMenu api through postman to test, it is successfully hitting it on OnAuthorization method in Filters.Authorization and validating my JWT Token and displays Status Code: 200 in postman but after successful token validation it should hit on GetMenu api for further data processing but it is not hitting.
What can be the issue? what am i missing? please help.
You should not set the filterContext.Result if the request is successfully authorize.
//
// Summary:
// A context for authorization filters i.e. Microsoft.AspNetCore.Mvc.Filters.IAuthorizationFilter
// and Microsoft.AspNetCore.Mvc.Filters.IAsyncAuthorizationFilter implementations.
public class AuthorizationFilterContext : FilterContext
{
//
// Summary:
// Gets or sets the result of the request. Setting Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result
// to a non-null value inside an authorization filter will short-circuit the remainder
// of the filter pipeline.
public virtual IActionResult Result { get; set; }
}
You only need to set Result when it's failed.
public class Authorization: AuthorizeAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext filterContext)
{
if (!ValidateToken(filterContext.HttpContext.Request.Headers["token"]))
{
filterContext.Result = new UnauthorizedResult();
}
}
}

How do Implement authorization in MVC4 Web API?

I Had create a MVC4 Web API. But People without authorization also can use it.
Example: people type in address bar "/api/product/1" also can get the result.
So, How to implement Security and allow authorize person to use the WEB API only ?
How to give authorize to the person that allow login to web api ?
More info about Authentication and Authorization
Simply adding the annotation to your controller will do:
// Require authorization for all actions on the controller.
[Authorize]
public class ValuesController : ApiController
{
public HttpResponseMessage Get(int id) { ... }
public HttpResponseMessage Post() { ... }
}
// Restrict by user:
[Authorize(Users="Alice,Bob")]
public class ValuesController : ApiController
{
}
// Restrict by role:
[Authorize(Roles="Administrators")]
public class ValuesController : ApiController
{
}
you can use MVC4 AspNet.identiy.Usermanager and Microsoft.Owin.Security to authenticate user..
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.Current.GetOwinContext().Authentication;
}
}
public HttpResponseMessage Login(string username, string password)
{
UserManager<TenantUser> userManager=new new UserManager<TenantUser>(new UserStore<TenantUser>(YOUR DBCONTEXT));
var user = UserManager.Find(username, password);
if (user != null)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicatioCookie);
ClaimsIdentity identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);
}
else
new HttpResponseMessage(HttpStatusCode.Forbidden) { Content = new ObjectContent<object>(new { Error = "You are not authorized to perform this action" }, Configuration.Formatters.JsonFormatter) };
}
it is working for me....