- Mенаџирање на лекови
- Додавање лекови
- Менањирање со производители
- Додавање производител
- регистрирање на корисник
Проектот е изработен во Spring Boot, со Spring Security 6 и Spring Data JPA со PostgreSQL датабаза. Корисничкиот интерфејс е изработен со Thymeleaf со додаден Bootstrap 5.
Изработена е со стандардна MVC слоевита архитектура.
User
: енкапсулира информации за корисниците: ЕМБГ (во улога на уникатно корисничко име), име, и тип на корисник (Ова е од значење бидејќи вака се чуваат roles ).UserType
: енумерација за roles (ADMIN, DOCTOR и PATIENT)Manufacturer
: производител на лековиMedicine
: тип/специфичен модел на лек за кој може да се издаде како рецепта.Prescription
: рецепта за даден лек на специфичен пациент.
Секој од моделите има соодветен JpaRepository интерфејс, како и сервисна логика потребна за CRUD операции.
Од особено значење е UserServiceImpl кој не само што имплементира UserService, туку и UserDetailsService, кој е потребен за Security да може да презема информации за корисник од база.
Контролер | Патекa | Контрола на пристап |
---|---|---|
MedicineController |
/medicine/** |
ADMIN |
ManufacturerController |
/manufacturer/** |
ADMIN |
PrescriptionController |
/prescription/** |
DOCTOR |
AccountController |
/accounts/** |
ADMIN |
MainController |
/ |
сите најавени корисници |
MainController
ги прикажува рецептите на моментално најавениот пациент. Во случај да е најавен друг вид на корисник, го пренасочува на соодветна патека.
Користев OpenSSL за генерирање на сертификатите. следуваат чекорите за генерирање на сертификати
- генерирање на приватен клуч:
openssl genrsa -des3 -out domain.key 2048
- креирање на CSR (Certificate Signing Request):
openssl req -key domain.key -new -out domain.csr
- генерирање на само-потпишан(self-signed) сертификат:
openssl x509 -signkey domain.key -in domain.csr -req -days 365 -out domain.crt
- креирање на само-потпишан Root CA>:
openssl req -x509 -sha256 -days 1825 -newkey rsa:2048 -keyout rootCA.key -out rootCA.crt
- конфигурациска датотека за потпишување
domain.ext
со содржина:
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[alt_names]
DNS.1 = domain
- потпишување на CSR со ново-креираниот root CA:
openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in domain.csr -out domain.crt -days 365 -CAcreateserial -extfile domain.ext
- конвертирање во PKCS12 формат за импортирање на серверот:
openssl pkcs12 -inkey domain.key -in domain.crt -export -out keystore.p12
- импортирање на
keystore.p12
во Spring и соодветна конфигурација воapplication.properties
:
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=daskalov
бидејќи користиме само-потпишан root CA, потребно е истиот да се импортира во browser за да биде препознаен како валиден сертификат. Ова не е потребно како чекор доколку користевме сертификат потпишан од познат CA
за генерирање на клиентските сертификати, во проектот имам креирано bash скрипта која ги извршува конандите за генерирање и потпишување на CSR, како и негово експортирање во p12 формат. Скриптата како аргумент прима име на корисникот, кое ќе го користи како име на датотеките кои се генерираат. Содржината е следна:
#!/bin/bash
if [[ $# -eq 0 ]]; then
echo "Usage: $0 <name>"
exit 1
fi
name=$1
# Generate CSR
openssl req -new -newkey rsa:4096 -nodes -keyout "${name}.key" -out "${name}.csr"
# Sign CSR with root CA and create certificate
openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in "${name}.csr" -out "${name}.crt" -days 365 -CAcreateserial
# Create PKCS#12 file containing private key and certificate
openssl pkcs12 -export -out "${name}.p12" -name "${name}" -inkey "${name}.key" -in "${name}.crt"
Како CN (Common Name) во prompt на командите се пишува ЕМБГ на корисникот и МОРА да се совпаѓа со вредноста зачувана во база.
- пакување на приватниот клуч на серверот со сертификатот во p12 фајл :
openssl pkcs12 -export -in domain.crt -inkey privateKey.key -out keystore.p12
- конвертирање во ЈКS датотека:
keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS
- импортирање на keystore во
resources
и додавање воapplication.properties
:
server.ssl.trust-store=classpath:truststore.jks
server.ssl.trust-store-password=daskalov
server.ssl.client-auth=need
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeHttpRequests(
(auth) -> {
try {
auth
.requestMatchers("/medicine/**", "/manufacturer/**", "/account/**").hasRole("ADMIN")
.requestMatchers("/prescription/**").hasRole("DOCTOR")
.anyRequest().authenticated()
.and()
.x509()
.subjectPrincipalRegex("CN=(.*?)(?:,|$)")
.and()
.logout()
.clearAuthentication(true)
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.logoutSuccessUrl("/");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
);
return http.build();
}
. овде Spring Security е конфигурирано да презема x509 сертификат и да го извлече CN преку regex (имплементирано со филтер во позадина), како и конфигурирано да ограничува пристап според патеки:
/medicine/**
,/manufacturer/**
и ```/accounts/**`` да се достапни само ако најавениот користник има ролја ADMIN/prescriptions/**
се само достапни на корисници со ролја DOCTOR
Дополнително, сите корисници мора да се автентицирани за пристап, т.е. да имаат сертификат.
Бидејќи некои од погледите се споделени од различни контролери, со тоа и различни видови на корисници, некои елементи во самите Thymeleaf templates се ограничени да рендерират само при присуство на одреден role.