Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One MVC web application as API and client

I have an MVC web app, and a WPF client and Web API server. I would very much like to pull the API controllers into the MVC app, and have only one app/api. My main reason for this is to have one sign-in procedure for application users and API clients alike.

What I would have liked to do is inject a SignInManager<ApplicationUser into the Token controller and use

var result = await _signInManager.PasswordSignInAsync(login.Username, login.Password, false, false);

to authenticate the username and password using the same password hasher as build into the MVC project. I don't want to duplicate any of that type of functionality. I also hope, with this, to achieve a sign-in that gives a JWT token, for the WPF app to access the API side of things, and a standard signed-in cookie, for normal MVC app requests to be authorized.

How should I go about this with minimum code duplication?

IDEA: Use one MVC application as a REST server as well. If my Login action that gets the JWT also signs me in, e.g. with _signInManager.PasswordSignInAsync, I should also get the cookie that will allow me to access protected actions internally, and use them externally with the authorization header containing the JWT.

like image 497
ProfK Avatar asked Mar 13 '18 10:03

ProfK


People also ask

Can I use MVC as Web API?

Mvc Hence Web API can also be used with Asp.Net and as a stand-alone service layer. You can mix Web API and MVC controller in a single project to handle advanced AJAX requests which may return data in JSON, XML or any others format and building a full-blown HTTP service.

Are MVC and Web API into one in MVC 6?

ASP.NET MVC 6 comes with some new features as well. Some prominent ones are: - MVC, WEB API and Web Pages are merged into one single framework.

What is Web API in MVC with example?

Advertisements. ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the . NET Framework.


1 Answers

You can consider the following options

Option #1: Move the logic which is used in MVC app to new class library which then can be referenced by API project. This will allow you to follow SRP and use the same logic in both MVC and API apps. If you want to make ASP.NET Identity related functionality to be common for MVC and API apps take a look at Moving ASP.NET Identity Model to Class Library and follow provided steps.

Option #2: You can move all controllers and models from API to MVC app. You can configure then API controllers to use JWT authentication scheme and continue using cookie authentication scheme fr MVC apps' controllers. If you want to follow this approach you will need to configure your Authentication middleware. For example your Startup class would look something like this:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddMvc();

    services.AddAuthentication(o =>
    {
        o.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        o.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        o.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    }).AddCookie(options =>
    {
        options.AccessDeniedPath = new PathString("/Account/Login/");
        options.LoginPath = new PathString("/Account/Login/");
    }).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => {
        options.TokenValidationParameters = new TokenValidationParameters 
        {       
            ValidateAudience = false,
            ValidateIssuer = false,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("<put_your_secret_here>")),
            ValidateLifetime = true,
            ClockSkew = TimeSpan.FromMinutes(5)            
        };
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
    app.UseAuthentication();
    app.UseMvcWithDefaultRoute();
    ...
}    

Then you can define BaseApiController which can be used to setup a route to API controllers and authorize them using e.g.

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api/[controller]")]
public abstract class BaseApiController {}

and make all API controllers inherit this base controller. You can also use policy based authorization which is more flexible. After you accomplish you will be able to authenticate with cookie in MVC app controllers and with JWT token in API controllers.

Option #3: You can leave API and MVC app running separately and use IdentityServer to implement OAuth protocol. Add it to MVC app since it integrates well with ASP.NET Identity and configure it so that to continue using the cookie authentication scheme for MVC app. Then configure one of the OAuth flow to setup the authorization between WPF app and API. IdentityServer is well documented and provides samples for different flows in their GitHub. The advantage of this approach is that you will never have such problem in future even if you consider adding more APIs, SPA or MVC apps which will have to use the same user base. Also it allows to implement Single Sign On(SSO) so if you ever need another MVC app it will be easy integrate it into existing infrastructure.

like image 105
Alexey Andrushkevich Avatar answered Oct 20 '22 00:10

Alexey Andrushkevich