4
votes

I have a .NET MVC Project and I am using API controllers inside the project for REST API's. Authentication used in the project is based on OwinMiddleware.

The following piece of code is used in OwinMiddleware for authentication

 var authValue = context.Request.Headers["Authorization"];
 if (!string.IsNullOrEmpty(authValue) && (authValue.StartsWith("Basic ")))
  {
      authValue = authValue.Substring(6).Trim();
      authValue = Encoding.UTF8.GetString(Convert.FromBase64String(authValue));
      var credentials = authValue.Split(":".ToCharArray());
      var signInStatus = await _signinManager.PasswordSignInAsync(credentials[0], credentials[1], false, false);

          switch (signInStatus)
           {
             case Microsoft.AspNet.Identity.Owin.SignInStatus.Success:
                    var user = await _userManager.FindByNameAsync(credentials[0]);
                    var identity = await _signinManager.CreateUserIdentityAsync(user);
                    context.Request.User = new ClaimsPrincipal(identity);
                     await base.Next.Invoke(context);
                     break;

             default:
                   context.Response.StatusCode = 401;
// an aobject representing error
                   var res = GetResposeData() 
                   var format = GetResponseContentType(context.Request);
                   var data = ParseToString(res , format);
                   var dataByte = Encoding.UTF8.GetBytes(data);
                  context.Response.ContentType = GetContentType(format);
                  context.Response.Body.Write(dataByte, 0, dataByte.Length);
                   break;
             }

    }

In the startup.cs I have added the following code

public void ConfigureAuth(IAppBuilder app)
    {
        app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<CustomSignInManager>());
        app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<CustomUserManager>());
        app.UseCookieAuthentication(new CookieAuthenticationOptions()
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/account/index"),
            Provider = new CookieAuthenticationProvider()
            {
                OnApplyRedirect = ctx =>
                {
                    ctx.Response.Redirect(ctx.RedirectUri);
                }
            }
        });
        app.UseAutofacMiddleware(AutofacConfig.Container);
    }

When I call API continuously using postman the following response was found

Could not get any response. There was an error connecting to baseUrl/api/User?pageNumber=1&pageSize=500. Why this might have happened: The server couldn't send a response: Ensure that the backend is working properly Self-signed SSL certificates are being blocked: Fix this by turning off 'SSL certificate verification' in Settings > General Proxy configured incorrectly Ensure that proxy is configured correctly in Settings > Proxy Request timeout: Change request timeout in Settings > General

The following are some exceptions from the Windows event log.

Event code: 3005 Event message: An unhandled exception has occurred. Event time: 2/14/2019 7:04:10 PM Event time (UTC): 2/14/2019 8:04:10 AM Event ID: 22548ff89e3744adbfd5c3e2b3b66ef4 Event sequence: 5 Event occurrence: 1 Event detail code: 0 Application information: Application domain: /LM/W3SVC/1/ROOT/XYZ-2-131946050074629312 Trust level: Full Application Virtual Path: /XYZ Application Path: C:\inetpub\wwwroot\xyz\ Machine name: ABC Process information: Process ID: 15228 Process name: w3wp.exe Account name: IIS APPPOOL\DefaultAppPool Exception information: Exception type: HttpException Exception message: Server cannot append header after HTTP headers have been sent. at System.Web.HttpHeaderCollection.SetHeader(String name, String value, Boolean replace) at Microsoft.Owin.Host.SystemWeb.CallHeaders.AspNetResponseHeaders.Set(String key, String[] values) at Microsoft.Owin.Infrastructure.OwinHelpers.AppendHeaderUnmodified(IDictionary2 headers, String key, String[] values) at Microsoft.Owin.Infrastructure.ChunkingCookieManager.AppendResponseCookie(IOwinContext context, String key, String value, CookieOptions options) at Microsoft.Owin.Security.Cookies.CookieAuthenticationHandler.<ApplyResponseGrantAsync>d__f.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseCoreAsync>d__b.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseAsync>d__8.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<TeardownAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware1.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware2.<Invoke>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware2.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContextStage.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

API controller have the following code to return the response

   // create new response
// format can be json or xml
            var response = new HttpResponseMessage()
            {
                Content = new StringContent(data, Encoding.UTF8, format),
                StatusCode = httpStatus
            };

            //if last modified available
// some date value
            if (lastUpdated != null)
                response.Content.Headers.LastModified = lastUpdated; 

            return response;
1

1 Answers

1
votes

You have mixed up webapi and MVC authentication. Change your code startup.cs to below:

public void ConfigureAuth(IAppBuilder app)
    {
        app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<CustomSignInManager>());
        app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<CustomUserManager>());
        app.MapWhen((context) => {
                return !IsApiRequest(context.Request);                
            }, (mvcApp) => {
                mvcApp.UseCookieAuthentication(new CookieAuthenticationOptions()
                {
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                    LoginPath = new PathString("/account/index"),
                    Provider = new CookieAuthenticationProvider()
                });
            });
        app.UseAutofacMiddleware(AutofacConfig.Container);
    }