Hi,
I am trying to implement XAF security to my RestAPI server. But I noticed, that Microsoft.AspNetCore.Authorization.Authorize attribute with Roles is not working and returns 403. Also ControllerBase.User.IsInRole("Viewer") is not working. And SecuritySystem.CurrentUser is null.
Security is implemented steb-by-step based on your template projects.
Can you tell me what I'm doing wrong?
Thank you for your time.
Tomáš
C#[HttpGet("Test")]
[Microsoft.AspNetCore.Authorization.Authorize(Roles = "Viewer")]
public IActionResult Test()
{
var isInViewer = User.IsInRole("Viewer");
var currentUser = DevExpress.ExpressApp.SecuritySystem.CurrentUser;
return Ok(User?.Identity?.Name);
}
C#public class Startup
{
IConfiguration Configuration;
public Startup()
{
Configuration = ServiceProvider.Configuration;
}
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IXpoDataStoreProvider>((serviceProvider) =>
{
string connectionString = null;
if (Configuration.GetConnectionString("ConnectionString") != null)
{
connectionString = Configuration.GetConnectionString("ConnectionString");
}
return XPObjectSpaceProvider.GetDataStoreProvider(connectionString, null, true);
})
.AddScoped<IAuthenticationTokenProvider, JwtTokenProviderService>()
.AddScoped<IObjectSpaceProviderFactory, ObjectSpaceProviderFactory>();
services.AddXafAspNetCoreSecurity(Configuration, options =>
{
options.RoleType = typeof(Module.BusinessObjects.UserModels.UserRole);
// 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(Module.BusinessObjects.UserModels.UserAccount);
// 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(BusinessObjects.ApplicationUserLoginInfo);
options.Events.OnSecurityStrategyCreated = securityStrategy => ((SecurityStrategy)securityStrategy).RegisterXPOAdapterProviders();
options.SupportNavigationPermissionsForTypes = false;
}).AddAuthenticationStandard(options =>
{
options.IsSupportChangePassword = true;
});
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.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.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var mvcBuilder = services
.AddControllers();
services.Configure<KestrelServerOptions>(options =>
{
options.Limits.MaxRequestBodySize = int.MaxValue;
});
services.AddCors(options =>
{
options.AddPolicy("AnyOrigin", builder1 =>
{
builder1
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
services.AddSwaggerGen(options =>
{
options.EnableAnnotations();
options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "API", Version = "v1" });
options.OperationFilter<IITHeader>();
var xmlPath = Path.Combine(AppContext.BaseDirectory, "comments.xml");
options.IncludeXmlComments("comments.xml");
options.AddSecurityDefinition("JWT", new OpenApiSecurityScheme()
{
Type = SecuritySchemeType.Http,
Name = "Bearer",
Scheme = "bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme() {
Reference = new OpenApiReference() {
Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme,
Id = "JWT"
}
},
new string[0]
},
});
});
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
public void Configure(IApplicationBuilder app)
{
var configuration = ApiServerConfiguration.Get();
var serverAddress = configuration.Url;
if (serverAddress.Last() == '/')
serverAddress = serverAddress.Remove(serverAddress.Length - 1, 1);
app.UseCors("AnyOrigin");
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint($"{serverAddress}/swagger/v1/swagger.json", "API V1");
});
app.UseRequestLocalization();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
}
}