2016-02-20 4 views
2

Я ищу какой-нибудь способ, чтобы сделать некоторые проверки подлинности для моей игры рамочного приложения: Я хочу, чтобы разрешить/запретить весь доступ к не прошедшей проверке подлинности пользователей наHTTP Basic Authentication для рамок Play 2,4

ли существует какое-то рабочий модуль/решения Это? Мне не нужны никакие формы для auth, всего 401 HTTP-ответ для пользователей без аутентификации (например, Apache .htacccess «AuthType Basic»).

+0

Вы МАЕ хотите взглянуть на список модулей: https://www.playframework.com/modules – cchantep

+0

@cchantep _ Эти модули предназначены только для Play 1.x и теперь доступны только для чтения. – biesior

ответ

1

Я боюсь, что такого решения нет, причина проста: обычно, когда разработчикам необходимо добавить стек авторизации/проверки подлинности, они строят полное решение.

Самый простой и быстрый способ - использовать HTTP front-end server в качестве обратного прокси для вашего приложения (я выбрал бы nginx для этой задачи, но если у вас есть Apache на машине, он также может быть использован). Это позволит вам фильтровать/аутентифицировать трафик с помощью правил общего сервера.

Кроме того, это дает вам другие преимущества, то есть: вы можете создать путь, подобный CDN, чтобы вы не тратили ресурсы своих приложений на обслуживание публичных, статических активы. Вы можете использовать балансировки нагрузки для переброски приложения, не останавливая его полностью в течение х минут и т.д.

+0

Вот пример конфигурации для apache http://bjeanes.com/2009/09/using-apache-as-a-basicauth-proxy-to-an-internal-re source – biesior

2

Вы также можете решить это с помощью play.mvc.Action, например.

Сначала ваше действие:

import org.apache.commons.codec.binary.Base64; 
import play.libs.F; 
import play.libs.F.Promise; 
import play.mvc.Action; 
import play.mvc.Http.Context; 
import play.mvc.Result; 
import util.ADUtil; 

public class BasicAuthAction extends Action<Result> { 
    private static final String AUTHORIZATION = "authorization"; 
    private static final String WWW_AUTHENTICATE = "WWW-Authenticate"; 
    private static final String REALM = "Basic realm=\"yourRealm\""; 

    @Override 
    public Promise<Result> call(Context context) throws Throwable { 
     String authHeader = context.request().getHeader(AUTHORIZATION); 
     if (authHeader == null) { 
      context.response().setHeader(WWW_AUTHENTICATE, REALM); 
      return F.Promise.promise(new F.Function0<Result>() { 
       @Override 
       public Result apply() throws Throwable { 
        return unauthorized("Not authorised to perform action"); 
       } 
      }); 
     } 

     String auth = authHeader.substring(6); 
     byte[] decodedAuth = new Base64().decode(auth); 
     String[] credString = new String(decodedAuth, "UTF-8").split(":"); 


     String username = credString[0]; 
     String password = credString[1]; 
     // here I authenticate against AD, replace by your own authentication mechanism 
     boolean loginCorrect = ADUtil.loginCorrect(username, password); 

     if (!loginCorrect) { 
      return F.Promise.promise(new F.Function0<Result>() { 
       @Override 
       public Result apply() throws Throwable { 
        return unauthorized("Not authorised to perform action"); 
       } 
      }); 
     } else { 
      return delegate.call(context); 
     } 
    } 
} 

Следующая ваша аннотаций:

import java.lang.annotation.Documented; 
import java.lang.annotation.ElementType; 
import java.lang.annotation.Inherited; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 

import play.mvc.With; 


@With(BasicAuthAction.class) 
@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.METHOD, ElementType.TYPE}) 
@Inherited 
@Documented 
public @interface BasicAuth { 
} 

Теперь вы можете аннотировать функции контроллера следующим образом:

@BasicAuth 
public Promise<Result> yourControllerFunction() { 
... 
3

Я обновленный Jonck ван дер Ответ Когеля должен быть более строгим при анализе заголовка авторизации, чтобы не терпеть неудачу с уродливыми исключениями, если auth заголовок недействительный, чтобы пароли с ':', и работать с Play 2.6:

Итак, BasicAuthAction класс:

import java.io.UnsupportedEncodingException; 
import java.util.concurrent.CompletableFuture; 
import java.util.concurrent.CompletionStage; 

import org.apache.commons.codec.binary.Base64; 

import play.Logger; 
import play.Logger.ALogger; 
import play.mvc.Action; 
import play.mvc.Http; 
import play.mvc.Http.Context; 
import play.mvc.Result; 

public class BasicAuthAction extends Action<Result> { 
    private static ALogger log = Logger.of(BasicAuthAction.class); 

    private static final String AUTHORIZATION = "Authorization"; 
    private static final String WWW_AUTHENTICATE = "WWW-Authenticate"; 
    private static final String REALM = "Basic realm=\"Realm\""; 

    @Override 
    public CompletionStage<Result> call(Context context) { 
     String authHeader = context.request().getHeader(AUTHORIZATION); 
     if (authHeader == null) { 
      context.response().setHeader(WWW_AUTHENTICATE, REALM); 
      return CompletableFuture.completedFuture(status(Http.Status.UNAUTHORIZED, "Needs authorization")); 
     } 

     String[] credentials; 
     try { 
      credentials = parseAuthHeader(authHeader); 
     } catch (Exception e) { 
      log.warn("Cannot parse basic auth info", e); 
      return CompletableFuture.completedFuture(status(Http.Status.FORBIDDEN, "Invalid auth header")); 
     } 

     String username = credentials[0]; 
     String password = credentials[1]; 
     boolean loginCorrect = checkLogin(username, password); 

     if (!loginCorrect) { 
      log.warn("Incorrect basic auth login, username=" + username); 
      return CompletableFuture.completedFuture(status(Http.Status.FORBIDDEN, "Forbidden")); 
     } else { 
      context.request().setUsername(username); 
      log.info("Successful basic auth login, username=" + username); 
      return delegate.call(context); 
     } 
    } 

    private String[] parseAuthHeader(String authHeader) throws UnsupportedEncodingException { 
     if (!authHeader.startsWith("Basic ")) { 
      throw new IllegalArgumentException("Invalid Authorization header"); 
     } 

     String[] credString; 
     String auth = authHeader.substring(6); 
     byte[] decodedAuth = new Base64().decode(auth); 
     credString = new String(decodedAuth, "UTF-8").split(":", 2); 
     if (credString.length != 2) { 
      throw new IllegalArgumentException("Invalid Authorization header"); 
     } 

     return credString; 
    } 

    private boolean checkLogin(String username, String password) { 
     /// change this 
     return username.equals("vlad"); 
    } 
} 

И затем, в классах контроллеров:

@With(BasicAuthAction.class) 
public Result authPage() { 
    String username = request().username(); 
    return Result.ok("Successful login as user: " + username + "! Here's your data: ..."); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^