GraphQLAuthorize attribute not firing [graphql] - graphql

I am working on the qraphQL api and I am trying to use authorization attribute GraphQLAuthorize in GraphQL.Server.Authorization.AspNetCore; I have created policy in startup.cd configureService but not recognized by GraphQLAuthorize attribute.
The [GraphQLAuthorize(Policy = "AUTHORIZED")] is not working.
while the AuthorizeWith("AUTHORIZED") is working
using GraphQL.Repository.GraphQL.Types;
using GraphQL.Repository.Repositories;
using GraphQL.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using GraphQL.Server.Authorization.AspNetCore;
namespace GraphQL.Repository.GraphQL
{
[GraphQLAuthorize(Policy = "AUTHORIZED")]
public class MenuQuery : ObjectGraphType
{
public MenuQuery(MenuRepository menuRepository)
{
Field<ListGraphType<NavigationMenuType>>(
"NavigationMenu",
arguments: new QueryArguments(new QueryArgument<NonNullGraphType<IdGraphType>> { Name = "applicationId" }),
resolve: context =>
{
var user = (ClaimsPrincipal)context.UserContext;
var applicationId = context.GetArgument<int>("applicationId");
return menuRepository.GetNavigationMenus(applicationId);
});
}
}
}
//startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
//using GraphQL;
using GraphQL.Server;
using Microsoft.EntityFrameworkCore;
using GraphQL.Repository.Entities;
using GraphQL.Repository.Repositories;
using GraphQL.Repository.GraphQL;
using GraphQL.Repository.GraphQL.Types;
using Microsoft.Extensions.DependencyInjection.Extensions;
using GraphQL.Server.Ui.GraphiQL;
using GraphQL.Server.Ui.Playground;
namespace GraphQL.Api
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MenuManagementDevContext>(options =>
options.UseSqlServer(Configuration["ConnectionStrings:CarvedRockContext"]));
services.AddScoped<MenuRepository>();
services.AddScoped<MenuQuery>();
services.AddScoped<NavigationMenuType>();
services.AddScoped<RoleNavigationMenuType>();
services.AddScoped<RoleType>();
services.AddScoped<IDependencyResolver>(s => new FuncDependencyResolver(s.GetRequiredService));
services.AddScoped<MenuSchema>();
services.AddGraphQL(o => { o.ExposeExceptions = true; })
.AddGraphQLAuthorization(options =>
{
options.AddPolicy("AUTHORIZED", p => p.RequireAuthenticatedUser());
})
.AddGraphTypes(ServiceLifetime.Scoped).AddUserContextBuilder(httpContext => httpContext.User)
.AddDataLoader()
.AddWebSockets();
services.AddCors();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(builder =>
builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
app.UseWebSockets();
app.UseGraphQLWebSockets<MenuSchema>("/graphql");
app.UseGraphQL<MenuSchema>();
app.UseGraphiQLServer(new GraphiQLOptions());
app.UseGraphQLPlayground(new GraphQLPlaygroundOptions());
}
}
}
Any help would be appreciated!

Related

AspNetBoilerplate - HttpContext is null in custom TenantResolveContributor

Documentation
I've read the documentation at https://aspnetboilerplate.com/Pages/Documents/Multi-Tenancy
I added a custom TenantResolveContributor to the application project and added it to the collection in WebModule.PreInitialize.
Configuration.MultiTenancy.Resolvers.Add<NameTenantResolveContributor>();
In WebModule.Initialize, I resolve my TenantAppService so it can be injected into RouteConfig.
TenantAppService tenantAppService = IocManager.Resolve<TenantAppService>();
RouteConfig.RegisterRoutes(RouteTable.Routes, tenantAppService);
When execution reaches RouteConfig, it correctly goes into NameTenantResolveContributor, but the HttpContext is null.
I'm not sure what I need to do to fix this.
Abp package version : 6.0.0
Base framework: .Net
Request is not available in this context
at System.Web.HttpContext.get_Request()
at DemoApp.MultiTenancy.NameTenantResolveContributor.ResolveTenantId() in >D:\src\ABP\DemoProject\6.0.0\src\DemoProject.Application\MultiTenancy\NameTenantResolveContributor.cs:line 40
at Abp.MultiTenancy.TenantResolver.GetTenantIdFromContributors()
The stack trace is oddly brief and undescriptive. When I copy the details, the message is
System.Web.HttpException
HResult=0x80004005
Message=Request is not available in this context
Source=<Cannot evaluate the exception source>
StackTrace:
<Cannot evaluate the exception stack trace>
using Abp.Configuration.Startup;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.MultiTenancy;
using Abp.Text;
using Abp.Web.MultiTenancy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace DemoApp.MultiTenancy
{
public class NameTenantResolveContributor : ITenantResolveContributor, ITransientDependency
{
private readonly IMultiTenancyConfig _multiTenancyConfig;
private readonly ITenantStore _tenantStore;
public NameTenantResolveContributor(IMultiTenancyConfig multiTenancyConfig, ITenantStore tenantStore)
{
_multiTenancyConfig = multiTenancyConfig;
_tenantStore = tenantStore;
}
public int? ResolveTenantId()
{
string tenancyName = "";
string[] urlParts = null;
var httpContext = HttpContext.Current;
if (httpContext == null)
{
return null;
}
//This is where the error occurs
urlParts = httpContext.Request.Url.Segments.Select(x => x.TrimEnd('/')).Skip(1).ToArray();
tenancyName = urlParts[0].ToLower();
var tenantInfo = _tenantStore.Find(tenancyName);
if (tenantInfo == null)
{
return null;
}
return tenantInfo.Id;
}
}
}

Why MapFallbackToController is not working: HTTP 401 UNAUTHORIZED Asp.net Core

I finished my app and i want to publish it into web.
Working on core 3.1.1 + angular2.
I created Fallback controller for routes.
It seems MapFallbackToController is not working. I don't have acceses to these files because i'm unauthorized, but why?
When i do "dotnet run" my page is blank and in the console:
Everything worked perfect until i moved angular files(wwwroot) into API proj.
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using RecipesApp.API.Controllers.Models.Data;
using RecipesApp.API.Data;
using RecipesApp.API.Helpers;
namespace RecipesApp.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataContext>( x=> x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllers().AddNewtonsoftJson(opt => {
opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
services.AddCors();
services.Configure<CloudinarySettings>(Configuration.GetSection("CloudinarySettings"));
services.AddAutoMapper(typeof(RecipesRepository).Assembly);
services.AddScoped<IAuthRepository, AuthRepository>();
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IRecipesRepository, RecipesRepository>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
.GetBytes(Configuration
.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddScoped<LogUserActivity>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(builder =>
{
builder.Run(async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
context.Response.AddApplicationError(error.Error.Message);
await context.Response.WriteAsync(error.Error.Message);
}
});
});
}
// app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapFallbackToController("Index", "Fallback");
});
}
}
}
My fallback class
public class Fallback : Controller
{
public IActionResult Index()
{
return PhysicalFile(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "index.html"), "text/HTML");
}
}
}
Somewhere in your startup file, i think you have specified that before a request gets to a controller, an authorization is needed, hence the error. In your case, can you try putting the AllowAnonymous attribute in your Fallback file as this tells netcore to map back to the fallback controller in search for angular index.html file. So, something like this;
[AllowAnonymous]
public class Fallback : ControllerBase
{
public IActionResult Index()
{
return PhysicalFile(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "index.html"), "text/HTML");
}
}
In your startup.cs file, inside your Configure() method, out the app.UseStaticFiles() after app.UseRouting(). That's all.

I am converting a .Net Framework 4.7.2 WebApi to asp.net Core3.0 and need to use Http.Sys with its listener set to an item in appsettings.json

I have seen a number of solutions for .Net Core 2 that I cannot seem to translate to 3.0. In most cases they do not use the Templated Program and Startup, but are purpose-built.
I use the WebApi template supplied in Visual Studio 2019 Community (latest patches).
In Core 3.0, the Configuration appsettings.json is automatically loaded and via DI in startup, is available to the rest of my code.
I need a couple of the items from appsettings.json, Configuration.GetSection("OrAppSettings")["OrSvrBaseUrl"]
Configuration.GetSection("OrAppSettings")["OrSvrUrlPort"] to be available in order to set the Http.sys Options.UrlPrefixes variable serverName in the Program.cs file.
I use Http.sys, as the Apis will be running in internal servers, as self-hosted, and using Kestrel, would only run at localhost. Therefore they will be unreachable unless Kestrel is run behind IIS. Http.sys can run as a self-hosted service, reachable across the LAN.
The apis etc are part of a larger solution offered to many of our customers and must fit into a variety of scenarios over which we have no real control.
I probably also need the same appsettings items for configuring Swagger, but that will be done in Startup.
I also need to use appsettings.json to provide configuration in the WebAPI client asp.net programs, but I have that covered, since DI from Startup is all I need there.
My appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"OrAppSettings": {
"ClientName": "some customer name",
"AsoAka": "mwp",
"AsoLocation": "shadow-10",
"AsoRouting": "unauthenticated",
"AsoClientType": "3",
"AsoClientUserId": "0",
"AsoClientUserName": "shadow-10\\ingres",
"AsoClientIpAddress": "",
"ORSvrBaseUrl": "http://shadow-10",
"ORSvrUrlPort": "5003",
"EnableSwaggerUI": "true"
},
"AllowedHosts": "*"
}
My Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.HttpSys;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.EventLog;
namespace MwpOrApiCore30
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static string serverName = "http://localhost:5005";
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
// Services
.ConfigureServices(services =>
{
services.Configure<EventLogSettings>(config =>
{
config.LogName = "Mwp Or Api";
config.SourceName = "MwpOrApi Source";
});
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseHttpSys(options =>
{
options.AllowSynchronousIO = true;
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30000000;
//options.UrlPrefixes.Add("http://shadow-10:5005");
options.UrlPrefixes.Add(serverName);
});
webBuilder.UseStartup<Startup>();
})
//.ConfigureWebHost(config =>
//{
// config.UseKestrel().UseUrls("http://0.0.0.0:5003");
//})
.UseWindowsService();
}
}
My MODIFIED Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.HttpSys;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.EventLog;
namespace MwpOrApiCore30
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static string serverName = "http://localhost:5005";
public static IHostBuilder CreateHostBuilder(string[] args)
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
serverName = configuration.GetSection("OrAppSettings")["ORSvrBaseUrl"];
serverName += ":" + configuration.GetSection("OrAppSettings")["ORSvrUrlPort"];
return Host.CreateDefaultBuilder(args)
.UseWindowsService()
. ConfigureServices(services =>
{
// services.AddHostedService<worker>();
})
// Services
.ConfigureServices(services =>
{
services.Configure<EventLogSettings>(config =>
{
config.LogName = "Mwp Or Api";
config.SourceName = "MwpOrApi Source";
});
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseHttpSys(options =>
{
options.AllowSynchronousIO = true;
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30000000;
//options.UrlPrefixes.Add("http://shadow-10:5005");
options.UrlPrefixes.Add(serverName);
});
webBuilder.UseStartup<Startup>();
});
}
}
}
My Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
namespace MwpOrApiCore30
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Mwp OR WebApi",
Version = "v1" ,
Description = "An ASP.NET CORE 3.0 Web Api for MWP OpenRoad Server",
Contact = new OpenApiContact
{
Name = "xxxxxx",
Email = "someone#someplace.com.au"
});
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
string enableSwaggerUi = Configuration.GetSection("OrAppSettings").GetValue<string>("EnableSwaggerUI");
if (enableSwaggerUi == "true")
{
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Mwp OR API V1");
});
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

Property not found in web api

The Result property in actionExecutedContext.Result cannot be resolved. Any ideas why?
Here's my code.
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http.Filters;
using System.Net.Http;
public class ValidateFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var modelState = actionExecutedContext.ActionContext.ModelState;
if (!modelState.IsValid)
{
var errors = modelState
.Where(s => s.Value.Errors.Count > 0)
.Select(s => new KeyValuePair<string, string>(s.Key, s.Value.Errors.First().ErrorMessage))
.ToArray();
actionExecutedContext.Result = new HttpResponseMessage<KeyValuePair<string, string>[]>(errors, HttpStatusCode.BadRequest);
}
base.OnActionExecuted(actionExecutedContext);
}
}
Since the beta days of Web API, HttpActionExecutedContext hasn't had a Result property but a Response property instead.
You can assign the HttpResponseMessage instance to it.
See the framework source code here.

Accessing Office Clip Board using C#.net

I use Visual Studio 2005 to develop a "Windows Service" using c#.net. My code requires to access the MS office Clipboard. But on trying to access the Clipboard class, the debugger throws an error
"Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it."
during the run-time. On checking for the solutions, I found that this could be solved by adding "[STAThread]" before the main method. But on adding this, I get a compilation error
"The type or namespace name 'STAThread' could not be found (are you missing a using directive or an assembly reference?)"
Is it possible to access the clipboard with my current version of .NET(.NET 3.0)?
The main method is in a file titled "program.cs" and the logic is in a file titled "Service.cs". Clipboard is used by Service.cs.
/* Program.cs */
using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;
using System.Media;
using System.Threading;
namespace WindowsService1
{
static class Program
{
[STAThread]
static void Main(string[] args)
{
#if DEBUG
Service1 serv = new Service1();
serv.onDebug();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new Service1() };
ServiceBase.Run(ServicesToRun);
#endif
}
}
}
/* Service.cs */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Timers;
namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
public void onDebug()
{
OnStart(null);
}
protected override void OnStart(string[] args)
{
clear_cb();
}
protected void clear_cb()
{
Clipboard.Clear(); // This is the line where I get the exception
}
protected override void OnStop()
{
// TODO: To clear the back up Database
}
}
}

Resources