Quarkus Security

affaan-m/ECC/docs/tr/skills/quarkus-security

作者 affaan-mef648e01899ba3e8dc6371642deaaf64b4477775無授權條款275K 個星標收錄於 2026年10月9日更新於 2026年10月9日儲存庫4 天前更新

Quarkus Security best practices for authentication, authorization, JWT/OIDC, RBAC, input validation, CSRF, secrets management, and dependency security.

AI 產生的概覽

Quarkus 安全性最佳實務,涵蓋驗證、授權、輸入檢查、密鑰管理與相依性掃描。

功能
此技能提供強化 Quarkus 應用程式的指引與程式碼範例:JWT/OIDC 與 Basic Auth 設定、以角色及程式化的 SecurityIdentity 授權、Bean Validation 輸入檢查、SQL 注入防範、密碼雜湊、CORS 與安全回應標頭、以 Vault 管理密鑰、流量限制、稽核記錄,以及相依性 CVE 掃描。它僅為說明內容,不會產生檔案或指令碼,只提供建議模式與設定片段。
適用情境
當你要為 Quarkus 服務加入驗證或授權、檢查使用者輸入、設定 CORS 或安全回應標頭、管理密鑰、加入流量限制,或檢查相依性的 CVE 時使用。
執行需求
未隨附指令碼或工具,僅為說明內容。套用這些建議需要具備相關擴充套件的 Quarkus 專案(例如 JWT/OIDC、Bean Validation、Vault);相依性掃描則需要搭配 OWASP dependency-check 外掛的 Maven 或 Gradle。

Quarkus Güvenlik İncelemesi

Kimlik doğrulama, yetkilendirme ve girdi doğrulama ile Quarkus uygulamalarını güvenli hale getirmek için en iyi uygulamalar.

When to Use

  • Kimlik doğrulama ekleme (JWT, OIDC, Basic Auth)
  • @RolesAllowed veya SecurityIdentity ile yetkilendirme uygulama
  • Kullanıcı girişini doğrulama (Bean Validation, özel doğrulayıcılar)
  • CORS veya güvenlik başlıklarını yapılandırma
  • Gizli bilgileri yönetme (Vault, ortam değişkenleri, config kaynakları)
  • Rate limiting veya brute-force koruması ekleme
  • Bağımlılıkları CVE için tarama
  • MicroProfile JWT veya SmallRye JWT ile çalışma

How It Works

Quarkus güvenliğini katmanlı uygulayın: JWT/OIDC veya Basic Auth ile kimliği doğrulayın, SecurityIdentity ve @RolesAllowed ile yetki kararlarını merkezileştirin, Bean Validation ile girdileri sınırlandırın, CORS ve güvenlik başlıklarını açıkça yapılandırın, gizli bilgileri Vault veya ortam değişkenleri üzerinden yönetin.

Examples

Kimlik Doğrulama

JWT Kimlik Doğrulama

java
// JWT ile korunan resource@Path("/api/protected")@Authenticatedpublic class ProtectedResource {
  @Inject  JsonWebToken jwt;
  @Inject  SecurityIdentity securityIdentity;
  @GET  public Response getData() {    String username = jwt.getName();    Set<String> roles = jwt.getGroups();    return Response.ok(Map.of(        "username", username,        "roles", roles,        "principal", securityIdentity.getPrincipal().getName()    )).build();  }}

Yapılandırma (application.properties):

properties
mp.jwt.verify.publickey.location=publicKey.pemmp.jwt.verify.issuer=https://auth.example.com
# OIDCquarkus.oidc.auth-server-url=https://auth.example.com/realms/myrealmquarkus.oidc.client-id=backend-servicequarkus.oidc.credentials.secret=${OIDC_SECRET}

Özel Kimlik Doğrulama Filtresi

java
@Provider@Priority(Priorities.AUTHENTICATION)public class CustomAuthFilter implements ContainerRequestFilter {
  @Inject  SecurityIdentity identity;
  @Override  public void filter(ContainerRequestContext requestContext) {    String authHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
    // Başlık yoksa veya hatalıysa hemen reddet    if (authHeader == null || !authHeader.startsWith("Bearer ")) {      requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());      return;    }
    String token = authHeader.substring(7);    if (!validateToken(token)) {      requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());    }  }
  private boolean validateToken(String token) {    // Token doğrulama mantığı    return true;  }}

Yetkilendirme

Rol Tabanlı Erişim Kontrolü

java
@Path("/api/admin")@RolesAllowed("ADMIN")public class AdminResource {
  @GET  @Path("/users")  public List<UserDto> listUsers() {    return userService.findAll();  }
  @DELETE  @Path("/users/{id}")  @RolesAllowed({"ADMIN", "SUPER_ADMIN"})  public Response deleteUser(@PathParam("id") Long id) {    userService.delete(id);    return Response.noContent().build();  }}
@Path("/api/users")public class UserResource {
  @Inject  SecurityIdentity securityIdentity;
  @GET  @Path("/{id}")  @RolesAllowed("USER")  public Response getUser(@PathParam("id") Long id) {    // Sahipliği kontrol et    if (!securityIdentity.hasRole("ADMIN") &&        !isOwner(id, securityIdentity.getPrincipal().getName())) {      return Response.status(Response.Status.FORBIDDEN).build();    }    return Response.ok(userService.findById(id)).build();  }
  private boolean isOwner(Long userId, String username) {    return userService.isOwner(userId, username);  }}

Programatik Güvenlik

java
@ApplicationScopedpublic class SecurityService {
  @Inject  SecurityIdentity securityIdentity;
  public boolean canAccessResource(Long resourceId) {    if (securityIdentity.isAnonymous()) {      return false;    }
    if (securityIdentity.hasRole("ADMIN")) {      return true;    }
    String userId = securityIdentity.getPrincipal().getName();    return resourceRepository.isOwner(resourceId, userId);  }}

Girdi Doğrulama

Bean Validation

java
// KÖTÜ: Validation yok@POSTpublic Response createUser(UserDto dto) {  return Response.ok(userService.create(dto)).build();}
// İYİ: Doğrulanmış DTOpublic record CreateUserDto(    @NotBlank @Size(max = 100) String name,    @NotBlank @Email String email,    @NotNull @Min(18) @Max(150) Integer age,    @Pattern(regexp = "^\\+?[1-9]\\d{1,14}$") String phone) {}
@POST@Path("/users")public Response createUser(@Valid CreateUserDto dto) {  User user = userService.create(dto);  return Response.status(Response.Status.CREATED).entity(user).build();}

Özel Doğrulayıcılar

java
@Target({ElementType.FIELD, ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy = UsernameValidator.class)public @interface ValidUsername {  String message() default "Invalid username format";  Class<?>[] groups() default {};  Class<? extends Payload>[] payload() default {};}
public class UsernameValidator implements ConstraintValidator<ValidUsername, String> {  @Override  public boolean isValid(String value, ConstraintValidatorContext context) {    if (value == null) return false;    return value.matches("^[a-zA-Z0-9_-]{3,20}$");  }}
// Kullanımpublic record CreateUserDto(    @ValidUsername String username,    @NotBlank @Email String email) {}

SQL Injection Önleme

Panache Active Record (Varsayılan Olarak Güvenli)

java
// İYİ: Panache ile parametreli sorgularList<User> users = User.list("email = ?1 and active = ?2", email, true);
Optional<User> user = User.find("username", username).firstResultOptional();
// İYİ: İsimlendirilmiş parametrelerList<User> users = User.list("email = :email and age > :minAge",    Parameters.with("email", email).and("minAge", 18));

Native Sorgular (Parametre Kullanın)

java
// KÖTÜ: String birleştirme@Query(value = "SELECT * FROM users WHERE name = '" + name + "'", nativeQuery = true)
// İYİ: Parametreli native sorgu@Entitypublic class User extends PanacheEntity {  public static List<User> findByEmailNative(String email) {    return getEntityManager()        .createNativeQuery("SELECT * FROM users WHERE email = :email", User.class)        .setParameter("email", email)        .getResultList();  }}

Parola Hash'leme

java
@ApplicationScopedpublic class PasswordService {
  public String hash(String plainPassword) {    return BcryptUtil.bcryptHash(plainPassword);  }
  public boolean verify(String plainPassword, String hashedPassword) {    return BcryptUtil.matches(plainPassword, hashedPassword);  }}
// Servis içinde@ApplicationScopedpublic class UserService {  @Inject  PasswordService passwordService;
  @Transactional  public User register(CreateUserDto dto) {    String hashedPassword = passwordService.hash(dto.password());    User user = new User();    user.email = dto.email();    user.password = hashedPassword;    user.persist();    return user;  }
  public boolean authenticate(String email, String password) {    return User.find("email", email)        .firstResultOptional()        .map(u -> passwordService.verify(password, u.password))        .orElse(false);  }}

CORS Yapılandırması

properties
# application.propertiesquarkus.http.cors=truequarkus.http.cors.origins=https://app.example.com,https://admin.example.comquarkus.http.cors.methods=GET,POST,PUT,DELETEquarkus.http.cors.headers=accept,authorization,content-type,x-requested-withquarkus.http.cors.exposed-headers=Content-Dispositionquarkus.http.cors.access-control-max-age=24Hquarkus.http.cors.access-control-allow-credentials=true

Gizli Bilgi Yönetimi

properties
# application.properties - BURADA GİZLİ BİLGİ YOK
# Ortam değişkenlerini kullanınquarkus.datasource.username=${DB_USER}quarkus.datasource.password=${DB_PASSWORD}quarkus.oidc.credentials.secret=${OIDC_CLIENT_SECRET}
# Or use Vaultquarkus.vault.url=https://vault.example.comquarkus.vault.authentication.kubernetes.role=my-role

HashiCorp Vault Entegrasyonu

java
@ApplicationScopedpublic class SecretService {
  @ConfigProperty(name = "api-key")  String apiKey; // Vault'tan alınır
  public String getSecret(String key) {    return ConfigProvider.getConfig().getValue(key, String.class);  }}

Rate Limiting (Hız Sınırlama)

Güvenlik Notu: X-Forwarded-For doğrudan kullanmayın — istemciler bunu taklit edebilir. Servlet request'ten gerçek uzak adresi veya kimliği doğrulanmış bir kimlik (API anahtarı, JWT subject) kullanın.

java
@ApplicationScopedpublic class RateLimitFilter implements ContainerRequestFilter {  private final Map<String, RateLimiter> limiters = new ConcurrentHashMap<>();
  @Inject  HttpServletRequest servletRequest;
  @Override  public void filter(ContainerRequestContext requestContext) {    String clientId = getClientIdentifier();    RateLimiter limiter = limiters.computeIfAbsent(clientId,        k -> RateLimiter.create(100.0)); // Saniyede 100 istek
    if (!limiter.tryAcquire()) {      requestContext.abortWith(          Response.status(429)              .entity(Map.of("error", "Too many requests"))              .build()      );    }  }
  private String getClientIdentifier() {    // Konteyner tarafından sağlanan uzak adresi kullanın (X-Forwarded-For değil).    // Güvenilir proxy arkasındaysanız quarkus.http.proxy.proxy-address-forwarding=true ayarlayın.    return servletRequest.getRemoteAddr();  }}

Güvenlik Başlıkları

java
@Providerpublic class SecurityHeadersFilter implements ContainerResponseFilter {
  @Override  public void filter(ContainerRequestContext request, ContainerResponseContext response) {    MultivaluedMap<String, Object> headers = response.getHeaders();
    // Clickjacking'i önle    headers.putSingle("X-Frame-Options", "DENY");
    // XSS koruması    headers.putSingle("X-Content-Type-Options", "nosniff");    headers.putSingle("X-XSS-Protection", "1; mode=block");
    // HSTS    headers.putSingle("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
    // CSP — script-src için 'unsafe-inline' kullanmayın, XSS korumasını etkisiz kılar;    // bunun yerine nonce veya hash kullanın    headers.putSingle("Content-Security-Policy",        "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'");  }}

Denetim Loglama

java
@ApplicationScopedpublic class AuditService {  private static final Logger LOG = Logger.getLogger(AuditService.class);
  @Inject  SecurityIdentity securityIdentity;
  public void logAccess(String resource, String action) {    String user = securityIdentity.isAnonymous()        ? "anonymous"        : securityIdentity.getPrincipal().getName();
    LOG.infof("AUDIT: user=%s action=%s resource=%s timestamp=%s",        user, action, resource, Instant.now());  }}
// Resource içinde kullanım@Path("/api/sensitive")public class SensitiveResource {  @Inject  AuditService auditService;
  @GET  @RolesAllowed("ADMIN")  public Response getData() {    auditService.logAccess("sensitive-data", "READ");    return Response.ok(data).build();  }}

Bağımlılık Güvenliği Taraması

bash
# Mavenmvn org.owasp:dependency-check-maven:check
# Gradle./gradlew dependencyCheckAnalyze
# Check Quarkus extensionsquarkus extension list --installable

En İyi Uygulamalar

  • Production'da her zaman HTTPS kullanın
  • Stateless kimlik doğrulama için JWT veya OIDC etkinleştirin
  • Bildirimsel yetkilendirme için @RolesAllowed kullanın
  • Bean Validation ile tüm girişleri doğrulayın
  • Parolaları BCrypt ile hash'leyin (asla düz metin saklamayın)
  • Gizli bilgileri Vault veya ortam değişkenlerinde saklayın
  • SQL injection'ı önlemek için parametreli sorgular kullanın
  • Tüm yanıtlara güvenlik başlıkları ekleyin
  • Genel endpoint'lerde rate limiting uygulayın
  • Hassas işlemleri denetleyin
  • Bağımlılıkları güncel tutun ve CVE için tarayın
  • Programatik kontroller için SecurityIdentity kullanın
  • Uygun CORS politikaları belirleyin
  • Kimlik doğrulama ve yetkilendirme yollarını test edin

來源與署名

來源:affaan-m/ECC位於docs/tr/skills/quarkus-security提交ef648e0

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架