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 从公开仓库中收录这些内容。

举报或申请下架