Web Api Asp.Net Identity - asp.net

I'm just trying to authentication a user with Asp.Identity in DelegatingHandler.
Like this code above:
public class TokenAuthentication : DelegatingHandler {
private readonly AuthenticationIdentityManager _identityManager;
public TokenAuthentication() {
_identityManager = new AuthenticationIdentityManager(new IdentityStore(new NFeDb()));
}
private Microsoft.Owin.Security.IAuthenticationManager AuthenticationManager {
get {
return HttpContext.Current.GetOwinContext().Authentication;
}
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
if (request.Headers.Contains("X-TokenCliente")) {
var tokenCliente = request.Headers.GetValues("X-TokenCliente").First();
var s = _identityManager.Authentication.SignIn(this.AuthenticationManager, tokenCliente, false);
if (s.Success) {
return await base.SendAsync(request, cancellationToken);
}
}
return request.CreateResponse(HttpStatusCode.Unauthorized);
}
}
But, at my controller with the Authorize notation:
[Authorize]
public HttpResponseMessage Get() {
return Request.CreateResponse(HttpStatusCode.OK);
}
I recive 302 status e redirected to Login page. Is possible to authenticate in DelegatingHandler?
UPDATE: I don't know if I need to use OwinMiddleware

The 302 redirection is probably from Cookie middleware.
If you are going to use token authentication, you'd better use the OWIN bearer token middleware.
Please check out: https://blogs.msdn.microsoft.com/webdev/2013/09/20/understanding-security-features-in-the-spa-template-for-vs2013-rc/
The blog covers how to use bearer token in web api and how to work side by side with cookie middleware.

Related

.NET Core Identity Server dynamic Client app registration and authentication

I have created an Identity Server using .NET Core and IdentityServer4, I have set of APIs and all calls to these APIs must be authenticated but these APIs might be used by third-party applications so clients can be dynamic
Till now example I am finding is set Clients on startup statically like
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());
}
public class Config
{
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("resourceApi1", "API Application1")
new ApiResource("resourceApi2", "API Application2")
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "clientApp1",
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ClientCredentials,
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "resourceApi1" }
}
};
}
}
Is there a way in IdentityServer implementation to register Client Apps and set dynamically
For Example, If I have APIs
1. resourceApi1
2. resourceApi2
Each third-party APIs should be able to register and we should be able to generate ClientID and Client secret for each with what resources they can access and Identity Server authenticates that ClientID and Client Secret?
There is an option to use a client store. By default identity server uses in memory store for finding clients:
services.AddIdentityServer()
.AddInMemoryClients(Clients)
You can change this and register your own client store
services.AddIdentityServer()
.AddClientStore<MyClientStore>()
and implement the service
class MyClientStore : IClientStore
{
public Task<Client> FindClientByIdAsync(string clientId)
{
}
}
This would solve dynamic lookup of clients. For registration of clients and their management, you would need to implement your own infrastructure.
First of all configure your IdentityServer using EntityFramework, Then you need to some Apis to add Client and ApiResources.
IdentityServer has its own implementation of Stores using EntityFramework.
You can add new Api for this purpose.
[Route("api/[controller]")]
[ApiController]
[AllowAnonymous]
public class DynamicController : ControllerBase
{
private readonly ConfigurationDbContext context;
public DynamicController(ConfigurationDbContext context)
{
this.context = context;
}
[HttpPost]
public async Task<ActionResult> AddApiResource(ApiResource apiResource)
{
context.ApiResources.Add(apiResource);
await context.SaveChangesAsync();
return Ok();
}
[HttpPost]
public async Task<ActionResult> AddClient(Client client)
{
context.Clients.Add(client);
await context.SaveChangesAsync();
return Ok();
}
}

ASP.NET Authentication POST Policy

I am currently working on a POST controller. In the past I've handled logic regarding authentication in the controller itself like this:
[HttpPost]
public HttpResponseMessage Post([FromBody] Foo foo)
{
if (foo.bar !== user.bar){
return;
}
I am not the best c# programmer, so have no clue how this should be handled. While researching I stumbled upon Policies. So I already use a [Authenticated] tag above the controller, but based on if the foo.bar in this example is the same as me.bar I am not allowed to make this post. (So the authenticated tag is for authentication but I want to change the Authorization)
Is it possible that I can make a [Policy=("fooPoster")] and can use the body of the post in there to determine whether I am authorized or not to access the post, or can I only access the global state to determine it?
You can try custom authorization. Refer to the code below.
[HttpPost]
[CustomAuthorization(Foo.bar)]
public HttpResponseMessage Post([FromBody] Foo foo)
{
if (foo.bar !== user.bar)
{
return;
}
}
public class CustomAuthorizationAttribute : AuthorizeAttribute
{
private readonly string allowedroles;
public CustomAuthorizationAttribute(string roles)
{
this.allowedroles = roles;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool authorize = false;
if (Me.bar != allowedroles)
{
authorize = true;
}
return authorize;
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
For more details you can go through here :

Authenticate WEB API request with action params

I am interested how to do a MVC WEB API autorization. I have checked basic authentication , but I have a different scenario. In my case login params are expected as an action parameter and not inside header.
namespace Test.Controllers
{
public class TestController : Controller
{
[RequireHttps]
[Authorize]
public void TestRequest(int actionParam, string username, string token, int appID)
{
something.......
}
}
}
I have also found this explanation http://www.codeproject.com/Tips/867071/WebAPI-Security-Custom-Authorization-Filters but would like to know is it possible to access action parameters instead of header value from Authorize?
Simply get the query string parameters in your OnAuthorization override either from the HttpActionContext or from HttpContext.Current.Request:
see: How to get Request Querystring values?
public override void OnAuthorization(HttpActionContext actionContext)
{
var queryString = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query.Substring( 1 ));
var username = queryString["username"];
}
or see: Accessing QueryString in a custom AuthorizeAttribute
Add using System.Web; then:
public override void OnAuthorization(HttpActionContext actionContext)
{
var username = HttpContext.Current.Request.QueryString["username"];
}

OWIN Authentication - redirect loop - The request filtering module is configured to deny a request where the query string is too long

I'm trying to use OWIN Authentication with just google authentication
ie - users of my app exist only if they have a google account
I've configured my Auth Config like this:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
CookieName = CookieAuthenticationDefaults.CookiePrefix + "External",
ExpireTimeSpan = TimeSpan.FromMinutes(5),
LoginPath = new PathString("/authentication"),
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions
{
ClientId = "xxx123",
ClientSecret = "xxx456",
});
}
}
My AuthenticationController has an Index method:
[AllowAnonymous]
public ActionResult Index()
{
Request.GetOwinContext().Authentication.Challenge(new AuthenticationProperties
{
RedirectUri = Url.Action("ExternalLoginCallback")
});
return new HttpUnauthorizedResult();
}
When I got to a restricted page, I get
HTTP Error 404.15 - Not Found The request filtering module is
configured to deny a request where the query string is too long.
... it is hitting my AuthenticationControllers Index method many many times...
Any idea what I've not configured correctly?
EDIT
My ExternalLoginCallback looks like:
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
}
Note - this method is never hit, if I put a breakpoint on it
My issue was that I wasn't passing in the provider type to the Challenge method -
Changing my Index action method to:
[AllowAnonymous]
public ActionResult Index()
{
var properties = new AuthenticationProperties
{
RedirectUri = Url.Action("ExternalLoginCallback")
};
//challenge
Request.RequestContext.HttpContext.GetOwinContext().Authentication.Challenge(properties, "Google");
//if above didn't handle it, return unauth.
return new HttpUnauthorizedResult();
}

Forms authentication in MVC3: return 401 (unauthorized) instead of redirect if user tries to access resource they're not authorized to

I have a public facing MVC3 site using forms authentication. Using forms authentication, if a user isn't authorized it sends a redirect to a login page. I don't desire this behavior, and would instead like the server to respond with 401 unauthorized. Is there a simple way of accomplishing this?
Do you mean something like this?
public class 401AuthorizeAttribute : AuthorizeAttribute
{
private class Http401Result : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
// Set the response code to 401.
context.HttpContext.Response.StatusCode = 401;
context.HttpContext.Response.End();
}
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new Http401Result();
}
}
You'll have to use this attribute instead of [Authorize].

Resources