How to set up Basic Authentication with sessionId in ASP.NET Core MVC? - asp.net-core

I have an ASP.NET Core MVC application in the front-end and I have a back-end service which is built with ServiceStack. This service has BasicAuth, which requires to send encrypted username+password and if successful it returns the sessionId.
After the authentication this service requires a cookie with the name ss-id and the value of sessionId in order to authorize any further requests. In my application I have a service which is injected into the controllers, I add this service to the service container like this:
services.AddHttpClient<IMyService,MyService>();
Now my problem is that when I add the SessionId as a cookie to the HttpClient, after a few requests the application creates a new instance of it and my cookie is deleted.
I've been trying to solve this for weeks, I've searched everywhere and couldn't find any solution! Please help!
I can save the SessionId into the browser cookies and then manually add it to all HttpClients in my service, but I don't think it's right... I think that somehow in serviceContainer with AddAuthentication or AddAuthorization or AddHttpClient, it should be set up... And when user authenticates it should add this cookie to every request automatically.

Related

Validate external token asp net core

I'm doing a mobile app in Xamarin Forms, which should be able to connect to an ASP.NET core web service (API). I also want the information on the web service to be secured by limiting it to Microsoft account signed-in users. The idea I had was to send the user's credentials and retrieve back the security token from the Microsoft graph within the mobile app. Afterwards, the user would send that same bearer token to the web service, which checks its validity, and grants the requested information only if the validation is successful.
I am new to web development, so first of all, I want to ask if I am using a good approach for my project (if not, what do you recommend?).
If it is, how should I set up the ConfigureServices function in my Startup class? When I include the [Authorize] tag in the controllers, the service crashes, telling me I should define an authentication scheme. I don't need authentication, only authorization (since authentication is done from the mobile app), Since these two are handled independently in asp.net core, I added a dummy jwt authentication scheme as a placeholder. However, when I send an http request with the security token from my mobile app, it gives me a 401 unauthorized error, telling me I'm sending an "invalid token" (this token works fine when connecting to the Microsoft graph).
I've searched in countless documentations, but all of them only consider scenarios in which the authentication is done within the web service, and not externally, like me.
Any help is appreciated

Identity Server 4: 401 instead of redirect for specific controllers

I'm adding a couple of controllers to my Identity Server 4 asp.net core mvc app. To be clear, I have added these to the IdentityProvider app (which I use for SSO), not a client app.
When I send a request to my endpoint (ex. GET sso.app.com/api/users) and I'm not authenticated, I get redirected to my login page, otherwise it works just fine. I would like to intercept the redirect and have the controller return a 401 Unauthorized instead.
I've explored using a policy for the Authorize header, but that only gives me a pass/fail based on an already authenticated user, so I don't have enough control there. I read on another similar SO question that the aspnet core team doesn't want devs to extend the Authorize header, but use policies instead.
I poked around and didn't find any obvious options for this when adding the service in Startup either. Are there any options that let me set behavior for specific paths/endpoints such as '/api'?
Comment copied to an answer:
So you have three apps here? Identity Server, some Identity Provider (IDP) with the API, and a client? Or are you referring to Identity Server as the IDP (which is fine, sometimes it is, sometimes it isn't)?
But if I understand your setup, the redirect to login should receive the API endpoint as the return URL. Just inspect that in your login controller and return a 401 if the URL matches the endpoints that you want to block.
I don't think you can do interception elsewhere inside Identity Server.

Identity Server 4 User management API

I've managed to get a solution working with a single page application project (ReactJS), an API running on ASP.net Core project and an IdentityServer 4 project.
I want to be able to call an API on the IdentityServer 4 project from the single page application project.
I created a simple controller class in the IdentityServer 4 application, with the authorize attribute. If I call it via Postman, however, I get the HTML for the login page back.
This happens after I already logged in on the API, and I use that same token.
How am I supposed to log in to identity server to make calls to it to manage users?
As stated in the comments, you should definitely add more information to your question. Your controller is part of the identity server's mvc application? Are you using AspnetCore.Identity?
If so, your controller is protected by AspnetCore.Identities's cookie authentication scheme. You need to send the cookie to access the controller. This has nothing to do with identity server as you are on the local MVC application, it's just plain vanilla MVC.
Postman has problems sending cookies, you need the interceptor chrome extension. You also need to login though postman.
This will probably work if the SPA is hosted by the same MVC application. If not you will need to configure your mvc applications to validate access tokens (not just issue them), like this:
// Adds IdentityServer
app.UseIdentityServer();
// Accept access tokens from identity server
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
AuthenticationScheme = "Bearer"
ApiName = "api1"
});
This way you can request access tokens for your local api through identity server, (You also need to configure an api scope for 'api1').
To validate them in your api-controller add this to your controller:
[Authorize(ActiveAuthenticationSchemes = "Bearer")]
[HttpGet]
public string Bearer()
{
return "Access Token Accepted";
}

Identityserver4 and Api Resource in same Asp.net Application

If i host my Identityserver4 and the Api in the same Asp.net Application.
What will be used for authentication for the API Controllers?
The Cookie from Identityserver or the token which i get from the oidc-client in my SPA application?
I my tests i can access the API, also if i didn't send the token within the angular http reqeuest as long as i have the Cookie...
But is this a correct and save way???
The MVC Controllers for Identityserver are protected with ValidateAntiforgeryKey, but not the API Controllers.
Does it make sense to host both in the same Application???
Edit:
In Details, the API is used for managing the IdentityServer.
CRUD Operations for Clients, Users, Resources,...
For example:
The IdentityServer is reachable at http://localhost:5000
I want build an Angular2 SPA Admin UI which is available at http://localhost:5000/admin
The reason for mentioning ValidateAntiforgeryKey is, because if i only use Cookie Authentication for the CRUD API i should also protect these API'S with ValidateAntiforgerKey, or?
It sounds like your API and Identity Server are two separate concerns and should be handled as two separate apps. This makes it a lot easier to maintain.
You need to set up an ApiResource and a Client where you add the ApiResource as an AllowedScope in your Identity Server configuration.
Then in your API app, you must add add the authentication middleware UseIdentityServerAuthentication.
The details are explained here:
http://docs.identityserver.io/en/latest/topics/apis.html
I can see you are mentioning ValidateAntiforgeryKey. This attribute is not used for protecting against unauthorized users, but to make sure form data is being posted from legitimate forms.

Letting a pure HTML/CSS/JS SPA application ask the user for his username/password and pass it to ADFS?

I'm writing a fairly large application, with a HTML/CSS/JS frontend, using AngularJS and a ASP.NET MVC Web API as a backend.
I would like users to be able to authenticate, I've installed ThinkTecture AuthorizationServer on a separate machine, and there is an ADFS instance running on the Domain Controller. Currently, I'm using the web page supplied with ADFS for login, but it would be nice if I could use my own page, which would ask for the username/password combo, pass it to AuthorizationServer/ADFS, and then just use the authentication token after that.
Has anyone done something similar?
Regards,
DanĂ­el
In fact you user will be log in your SPA then you have a server side (Java or .NET or *) that get this request.
The server ask the token to ADFS , ADFS send the token and your server pass the token to AngularJS in the response via a cookie.
In Angular side nothing to do expect an http interceptor to check the status of the response (401,403) ...
The cookie will be resent automatically by AngularJS in each request if you want to know how implements an htppInterceptor on AngularJS just check :
AngularJs -.net MVC WebApi Authentication example
In this thread i explain how to implements this step.
Anyway : your SPA is a RIA ok but still the client part of a webapp. I don't think that it's really good (i think it's really bad) to let the client part contact directly the ADFS ... How to prevent Man-In-The-Middle if you do that ?