2024-09-02 10:07:25 +00:00
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 ;
2024-09-26 06:06:05 +00:00
using DurnyklyYol.Module.Services ;
2024-09-02 10:07:25 +00:00
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 ( ) ;
2024-09-26 06:06:05 +00:00
services . AddSingleton < INotificationService , NotificationService > ( ) ;
2024-09-02 10:07:25 +00:00
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 ( ) ;
} ) ;
}
}