GodelTech.Microservices.Security contains initializer responsible for REST API endpoint security configuration.
In order to configure REST API security Startup.cs
and application configuration files must be updated. Startup
class must use ApiSecurityInitializer
. The following snippet demonstrates one of possible options how to Startup
may look like:
public class Startup : MicroserviceStartup
{
public Startup(IConfiguration configuration)
: base(configuration)
{
}
protected override IEnumerable<IMicroserviceInitializer> CreateInitializers()
{
yield return new DeveloperExceptionPageInitializer(Configuration);
yield return new HstsInitializer();
yield return new GenericInitializer(null, (app, _) => app.UseRouting());
yield return new ApiSecurityInitializer(
options => Configuration.Bind("ApiSecurityOptions", options),
new PolicyFactory()
);
yield return new ApiInitializer(Configuration);
}
}
PolicyFactory class:
public class PolicyFactory : IAuthorizationPolicyFactory
{
public IReadOnlyDictionary<string, AuthorizationPolicy> Create()
{
return new Dictionary<string, AuthorizationPolicy>
{
["add"] = GetAuthorizationPolicy("fake.add"),
["edit"] = GetAuthorizationPolicy("fake.edit"),
["delete"] = GetAuthorizationPolicy("fake.delete")
};
}
private static AuthorizationPolicy GetAuthorizationPolicy(string requiredScope)
{
var policyBuilder = new AuthorizationPolicyBuilder();
policyBuilder.RequireAuthenticatedUser();
policyBuilder.RequireClaim("scope", requiredScope);
return policyBuilder.Build();
}
}
Configuration file may have configuration section similar to this:
"ApiSecurityOptions": {
"RequireHttpsMetadata": false,
"Authority": "https://localhost:44300",
"Issuer": "https://localhost:44300",
"Audience": "DemoApi",
"TokenValidation": {
"ValidateAudience": true
}
}
NOTE: You controller or method must be decorated with [Authorize]
attribute which has policy name specified. Here is how it may look like:
[Authorize]
[Route("fakes")]
[ApiController]
public class FakeController : ControllerBase
{
[HttpGet]
[ProducesResponseType(typeof(IList<FakeModel>), StatusCodes.Status200OK)]
public IActionResult GetList()
{
...
}
[HttpGet("{id:int}")]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(FakeModel), StatusCodes.Status200OK)]
public IActionResult Get(int id)
{
...
}
[Authorize("add")]
[HttpPost]
[ProducesResponseType(typeof(FakeModel), StatusCodes.Status201Created)]
public IActionResult Post([FromBody] FakePostModel model)
{
...
}
}
In order to configure UI security Startup.cs
file needs to be updated. UiSecurityInitializer
must be added to list of initializers. Here is example how your Startup
class may look like:
public class Startup : MicroserviceStartup
{
public Startup(IConfiguration configuration)
: base(configuration)
{
}
protected override IEnumerable<IMicroserviceInitializer> CreateInitializers()
{
yield return new DeveloperExceptionPageInitializer();
yield return new ExceptionHandlerInitializer("/Home/Error");
yield return new HstsInitializer();
yield return new GenericInitializer(null, (app, _) => app.UseStaticFiles());
yield return new GenericInitializer(null, (app, _) => app.UseRouting());
yield return new UiSecurityInitializer(
options => Configuration.Bind("UiSecurityOptions", options)
);
yield return new MvcInitializer();
}
}
The following configuration secription need to be added to appsettings.json
:
"UiSecurityOptions": {
"Authority": "https://localhost:44300",
"Issuer": "https://localhost:44300",
"ClientId": "Mvc",
"ClientSecret": "secret",
"RequireHttpsMetadata": false,
"Scopes": [
"openid",
"profile",
"offline_access",
"api"
]
}
NOTE: You need to decorate your MVC / Razor Pages controllers with [Authorize]
attribute or apply corresponding conventions by creating subclass of RazorPagesInitializer
.
ApiSecurityInitializer
uses ApiSecurityOptions
class. Full list of settings can be found in the following snippet:
"ApiSecurityOptions": {
"RequireHttpsMetadata": false,
"Authority": "https://localhost:44300",
"Issuer": "https://localhost:44300",
"Audience": "DemoApi",
"TokenValidation": {
"ValidateAudience": true,
"ValidateIssuer": true,
"ValidateIssuerSigningKey": true,
"ValidateLifetime": true
},
"SaveToken": true,
"IncludeErrorDetails": true
}
IMPORTANT: By default all validation and security restrictions are turned ON.
UiSecurityInitializer
uses UiSecurityOptions
class. Full list of settings can be found in the following snippet:
"UiSecurityOptions": {
"Authority": "https://localhost:44300",
"Issuer": "https://localhost:44300",
"ClientId": "Mvc",
"ClientSecret": "secret",
"GetClaimsFromUserInfoEndpoint": true,
"RequireHttpsMetadata": false,
"ResponseType": "code",
"Scopes": [
"openid",
"profile",
"offline_access",
"api"
],
"UsePkce": true,
"PublicAuthorityUri": "https://localhost:44300",
"SaveTokens": true
}
NOTE: PublicAuthorityUri
specific public address of identity provider. This setting might be useful when server-to-server communication happens within internal network (Kubernetes, docker-compose) but user uses public address to navigate to service.
The following resources might be useful to understand internals of current project: