213 lines
11 KiB
C#
213 lines
11 KiB
C#
using DevExpress.ExpressApp.Security;
|
|
using DevExpress.ExpressApp.ApplicationBuilder;
|
|
using DevExpress.ExpressApp.Blazor.ApplicationBuilder;
|
|
using DevExpress.ExpressApp.Blazor.Services;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using Microsoft.AspNetCore.Components.Server.Circuits;
|
|
using DurnyklyYol.Blazor.Server.Services;
|
|
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
|
|
using System.Text;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using Microsoft.OpenApi.Models;
|
|
using Microsoft.AspNetCore.OData;
|
|
using DevExpress.ExpressApp.WebApi.Services;
|
|
using DurnyklyYol.WebApi.JWT;
|
|
using DevExpress.ExpressApp.Security.Authentication.ClientServer;
|
|
using DurnyklyYol.Blazor.Server.OData;
|
|
using Microsoft.AspNetCore.OData.Query.Validator;
|
|
using DurnyklyYol.Module.Services;
|
|
|
|
namespace DurnyklyYol.Blazor.Server;
|
|
|
|
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.
|
|
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
|
public void ConfigureServices(IServiceCollection services) {
|
|
services.AddSingleton(typeof(Microsoft.AspNetCore.SignalR.HubConnectionHandler<>), typeof(ProxyHubConnectionHandler<>));
|
|
|
|
services.AddRazorPages();
|
|
services.AddSingleton<INotificationService, NotificationService>();
|
|
services.AddServerSideBlazor();
|
|
services.AddHttpContextAccessor();
|
|
services.AddScoped<IAuthenticationTokenProvider, JwtTokenProviderService>();
|
|
services.AddScoped<CircuitHandler, CircuitHandlerProxy>();
|
|
services.AddXaf(Configuration, builder => {
|
|
builder.UseApplication<DurnyklyYolBlazorApplication>();
|
|
|
|
builder.AddXafWebApi(webApiBuilder => {
|
|
webApiBuilder.AddXpoServices();
|
|
|
|
webApiBuilder.ConfigureOptions(options => {
|
|
// Make your business objects available in the Web API and generate the GET, POST, PUT, and DELETE HTTP methods for it.
|
|
// options.BusinessObject<YourBusinessObject>();
|
|
options.BusinessObject<Module.BusinessObjects.Contact>();
|
|
});
|
|
});
|
|
|
|
builder.Modules
|
|
.AddConditionalAppearance()
|
|
.AddFileAttachments()
|
|
.AddReports(options => {
|
|
options.EnableInplaceReports = true;
|
|
options.ReportDataType = typeof(DevExpress.Persistent.BaseImpl.ReportDataV2);
|
|
options.ReportStoreMode = DevExpress.ExpressApp.ReportsV2.ReportStoreModes.XML;
|
|
})
|
|
.AddValidation(options => {
|
|
options.AllowValidationDetailsAccess = false;
|
|
})
|
|
.AddViewVariants()
|
|
.Add<DurnyklyYol.Module.DurnyklyYolModule>()
|
|
.Add<DurnyklyYolBlazorModule>();
|
|
builder.ObjectSpaceProviders
|
|
.AddSecuredXpo((serviceProvider, options) => {
|
|
string connectionString = null;
|
|
if(Configuration.GetConnectionString("ConnectionString") != null) {
|
|
connectionString = Configuration.GetConnectionString("ConnectionString");
|
|
}
|
|
#if EASYTEST
|
|
if(Configuration.GetConnectionString("EasyTestConnectionString") != null) {
|
|
connectionString = Configuration.GetConnectionString("EasyTestConnectionString");
|
|
}
|
|
#endif
|
|
ArgumentNullException.ThrowIfNull(connectionString);
|
|
options.ConnectionString = connectionString;
|
|
options.ThreadSafe = true;
|
|
options.UseSharedDataStoreProvider = true;
|
|
})
|
|
.AddNonPersistent();
|
|
builder.Security
|
|
.UseIntegratedMode(options => {
|
|
options.Lockout.Enabled = true;
|
|
|
|
options.RoleType = typeof(PermissionPolicyRole);
|
|
// ApplicationUser descends from PermissionPolicyUser and supports the OAuth authentication. For more information, refer to the following topic: https://docs.devexpress.com/eXpressAppFramework/402197
|
|
// If your application uses PermissionPolicyUser or a custom user type, set the UserType property as follows:
|
|
options.UserType = typeof(DurnyklyYol.Module.BusinessObjects.ApplicationUser);
|
|
// ApplicationUserLoginInfo is only necessary for applications that use the ApplicationUser user type.
|
|
// If you use PermissionPolicyUser or a custom user type, comment out the following line:
|
|
options.UserLoginInfoType = typeof(DurnyklyYol.Module.BusinessObjects.ApplicationUserLoginInfo);
|
|
options.UseXpoPermissionsCaching();
|
|
options.Events.OnSecurityStrategyCreated += securityStrategy => {
|
|
// Use the 'PermissionsReloadMode.NoCache' option to load the most recent permissions from the database once
|
|
// for every Session instance when secured data is accessed through this instance for the first time.
|
|
// Use the 'PermissionsReloadMode.CacheOnFirstAccess' option to reduce the number of database queries.
|
|
// In this case, permission requests are loaded and cached when secured data is accessed for the first time
|
|
// and used until the current user logs out.
|
|
// See the following article for more details: https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.Security.SecurityStrategy.PermissionsReloadMode.
|
|
((SecurityStrategy)securityStrategy).PermissionsReloadMode = PermissionsReloadMode.NoCache;
|
|
};
|
|
})
|
|
.AddPasswordAuthentication(options => {
|
|
options.IsSupportChangePassword = true;
|
|
});
|
|
});
|
|
var authentication = services.AddAuthentication(options => {
|
|
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
|
});
|
|
authentication.AddCookie(options => {
|
|
options.LoginPath = "/LoginPage";
|
|
});
|
|
authentication.AddJwtBearer(options => {
|
|
options.TokenValidationParameters = new TokenValidationParameters() {
|
|
ValidateIssuerSigningKey = true,
|
|
//ValidIssuer = Configuration["Authentication:Jwt:Issuer"],
|
|
//ValidAudience = Configuration["Authentication:Jwt:Audience"],
|
|
ValidateIssuer = false,
|
|
ValidateAudience = false,
|
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:Jwt:IssuerSigningKey"]))
|
|
};
|
|
});
|
|
services.AddAuthorization(options => {
|
|
options.DefaultPolicy = new AuthorizationPolicyBuilder(
|
|
JwtBearerDefaults.AuthenticationScheme)
|
|
.RequireAuthenticatedUser()
|
|
.RequireXafAuthentication()
|
|
.Build();
|
|
});
|
|
|
|
services
|
|
.AddControllers()
|
|
.AddOData((options, serviceProvider) => {
|
|
options
|
|
.AddRouteComponents("api/odata", new EdmModelBuilder(serviceProvider).GetEdmModel(),
|
|
odataServices => {
|
|
odataServices.AddSingleton<ODataQueryValidator, MyODataQueryValidator>();
|
|
})
|
|
.EnableQueryFeatures(100);
|
|
});
|
|
|
|
services.AddSwaggerGen(c => {
|
|
c.EnableAnnotations();
|
|
c.SwaggerDoc("v1", new OpenApiInfo {
|
|
Title = "DurnyklyYol API",
|
|
Version = "v1",
|
|
Description = @"Use AddXafWebApi(options) in the DurnyklyYol.Blazor.Server\Startup.cs file to make Business Objects available in the Web API."
|
|
});
|
|
c.AddSecurityDefinition("JWT", new OpenApiSecurityScheme() {
|
|
Type = SecuritySchemeType.Http,
|
|
Name = "Bearer",
|
|
Scheme = "bearer",
|
|
BearerFormat = "JWT",
|
|
In = ParameterLocation.Header
|
|
});
|
|
c.AddSecurityRequirement(new OpenApiSecurityRequirement() {
|
|
{
|
|
new OpenApiSecurityScheme() {
|
|
Reference = new OpenApiReference() {
|
|
Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme,
|
|
Id = "JWT"
|
|
}
|
|
},
|
|
new string[0]
|
|
},
|
|
});
|
|
});
|
|
|
|
services.Configure<Microsoft.AspNetCore.Mvc.JsonOptions>(o => {
|
|
//The code below specifies that the naming of properties in an object serialized to JSON must always exactly match
|
|
//the property names within the corresponding CLR type so that the property names are displayed correctly in the Swagger UI.
|
|
//XPO is case-sensitive and requires this setting so that the example request data displayed by Swagger is always valid.
|
|
//Comment this code out to revert to the default behavior.
|
|
//See the following article for more information: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions.propertynamingpolicy
|
|
o.JsonSerializerOptions.PropertyNamingPolicy = null;
|
|
});
|
|
}
|
|
|
|
// 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();
|
|
app.UseSwagger();
|
|
app.UseSwaggerUI(c => {
|
|
c.SwaggerEndpoint("/swagger/v1/swagger.json", "DurnyklyYol WebApi v1");
|
|
});
|
|
}
|
|
else {
|
|
app.UseExceptionHandler("/Error");
|
|
// The default HSTS value is 30 days. To change this for production scenarios, see: https://aka.ms/aspnetcore-hsts.
|
|
app.UseHsts();
|
|
}
|
|
app.UseHttpsRedirection();
|
|
app.UseRequestLocalization();
|
|
app.UseStaticFiles();
|
|
app.UseRouting();
|
|
app.UseAuthentication();
|
|
app.UseAuthorization();
|
|
app.UseXaf();
|
|
app.UseEndpoints(endpoints => {
|
|
endpoints.MapXafEndpoints();
|
|
endpoints.MapBlazorHub();
|
|
endpoints.MapFallbackToPage("/_Host");
|
|
endpoints.MapControllers();
|
|
});
|
|
}
|
|
}
|