У меня есть собственный сервер авторизации, созданный на основе identityserver4, где я хочу защитить все API на хосте. Система - это просто имитация разработчиков Google или Facebook, где владельцы приложений регистрируются и получают идентификатор клиента и секреты клиента для предоставления доступа на API.
Итак, я проследил за потоком client_credentials в образцах identityserver4. Все работает нормально. Я создал общедоступный пользовательский интерфейс для владельцев приложений, чтобы они могли создавать приложения и выбирать API, к которым они будут обращаться из своих приложений. Я использую IConfigurationDbContext
для процедур CRUD на внутренних таблицах сервера идентификации.
Проблема в том, что я не мог найти способ защитить apis на основе выбора владельцев приложений, когда разработчик создает приложение и выбирает несколько логических конечных точек для доступа, они по-прежнему могут достичь всех конечных точек. Я сделал следующее:
Запуск сервера авторизации
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryCaching()
.AddOperationalStore(storeOpitons =>
{
storeOpitons.ConfigureDbContext = builder =>
builder.UseSqlServer(Configuration.GetConnectionString("Default"),
sql => sql.MigrationsAssembly(migrationsAssembly));
})
.AddConfigurationStore(storeOptions =>
{
storeOptions.ConfigureDbContext = builder =>
builder.UseSqlServer(Configuration.GetConnectionString("Default"),
sql => sql.MigrationsAssembly(migrationsAssembly));
});
Метод сохранения клиента
public IActionResult SaveApp(ClientViewModel model, List<SelectedApi> selectedApis)
{
//ommited for brevity
Client client = new Client
{
Description = model.Description,
ClientName = model.Name,
RedirectUris = new[] { model.CallBackUri }
};
client.AllowedScopes = selectedApis.Where(a => a.apiValue == "true").Select(a => a.apiName).ToList();
//e.g : client.AllowedScopes = {"employee_api"};
_isRepository.SaveClient(client, userApp);
}
Запуск проекта Api
services.AddAuthentication("Bearer").AddJwtBearer(opt => {
opt.Authority = "http://localhost:5000";
opt.Audience = "employee_api";
opt.RequireHttpsMetadata = false;
});
Пример контроллера API
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class EmployeeController : BaseController
{
private readonly IEmployeeRepository _employeeRepoistory;
public EmployeeController(IServiceProvider provider, IEmployeeRepository employeeRepository) : base(provider)
{
_employeeRepoistory = employeeRepository;
}
[HttpGet]
public IActionResult GetEmployees([FromQuery] EmployeeResourceParameter parameter)
{
return Ok(_mapper.Map<IEnumerable<EmployeeModel>>(_employeeRepoistory.GetAll(parameter)));
}
[HttpGet("{id:int}")]
public IActionResult GetEmployeeById(int id)
{
var emp = _employeeRepoistory.GetById(id);
return Ok(_mapper.Map<EmployeeModel>(emp));
}
}
Я хочу, чтобы если разработчик выбрал employee_api, они должны были просто добраться до конечных точек EmployeeController. Однако прямо сейчас они могут достичь всех API, независимо от их выбора. Какие шаги нужно предпринять для этого на стороне api или на стороне сервера аутентификации?