카테고리 없음

[보안] Play 프레임 워크를 사용하여 로그인을위한 Https 라우팅 적용

행복을전해요 2020. 12. 11. 18:32

@Before사용자가 http : //를 직접 입력하더라도 인터셉터를 사용하여 모든 요청을 리디렉션 할 수 있습니다 . 아래는 제가 사용하는 코드입니다 (containerless play run를 실행할 때 또는 Heroku와 같은 프런트 엔드 뒤에서 실행할 때 작동합니다).

public class HttpsRequired extends Controller {
    /** Called before every request to ensure that HTTPS is used. */
        @Before
            public static void redirectToHttps() {
                    //if it's not secure, but Heroku has already done the SSL processing then it might actually be secure after all
                            if (!request.secure && request.headers.get("x-forwarded-proto") != null) {
                                        request.secure = request.headers.get("x-forwarded-proto").values.contains("https");
                                                }
                                                
                                                        //redirect if it's not secure
                                                                if (!request.secure) {
                                                                            String url = redirectHostHttps() + request.url;
                                                                                        System.out.println("Redirecting to secure: " + url);
                                                                                                    redirect(url);
                                                                                                            }
                                                                                                                }
                                                                                                                
                                                                                                                    /** Renames the host to be https://, handles both Heroku and local testing. */
                                                                                                                        @Util
                                                                                                                            public static String redirectHostHttps() {
                                                                                                                                    if (Play.id.equals("dev")) {
                                                                                                                                                String[] pieces = request.host.split(":");
                                                                                                                                                            String httpsPort = (String) Play.configuration.get("https.port");
                                                                                                                                                                        return "https://" + pieces[0] + ":" + httpsPort; 
                                                                                                                                                                                } else {
                                                                                                                                                                                            if (request.host.endsWith("domain.com")) {
                                                                                                                                                                                                            return "https://secure.domain.com";
                                                                                                                                                                                                                        } else {
                                                                                                                                                                                                                                        return "https://" + request.host;
                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                }    
                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                
-------------------

다음은 Java Play 2.1.1 및 Heroku에서 작동하는 예입니다.

public class ForceHttps extends Action<Controller> {

    // heroku header
        private static final String SSL_HEADER = "x-forwarded-proto";
        
            @Override
                public Result call(Context ctx) throws Throwable {
                        final Result result;
                                if (Play.isProd() && !isHttpsRequest(ctx.request())) {
                                            result = redirect("https://" + ctx.request().host()
                                                                + ctx.request().uri());
                                                                        }
                                                                                else {
                                                                                            // let request proceed
                                                                                                        result = this.delegate.call(ctx);
                                                                                                                }
                                                                                                                        return result;
                                                                                                                            }
                                                                                                                            
                                                                                                                                private static boolean isHttpsRequest(Request request) {
                                                                                                                                        // heroku passes header on
                                                                                                                                                return request.getHeader(SSL_HEADER) != null
                                                                                                                                                                && request.getHeader(SSL_HEADER)
                                                                                                                                                                                        .contains("https");
                                                                                                                                                                                            }
                                                                                                                                                                                            
                                                                                                                                                                                            }
                                                                                                                                                                                            

그런 다음 https를 확인하려는 컨트롤러에 @With (ForceHttps.class)를 추가합니다. 또는 모든 컨트롤러를 확인하려면 HttpsController가 Controller를 확장하고 모든 클래스가 HttpsController를 확장하도록 클래스를 추가하십시오.

예 :

@With(ForceHttps.class)
public class HttpsController extends Controller {

}
-------------------

컨트롤러에서 request.secure == true를 확인한 다음 https로 리디렉션 할 수 있다고 생각합니다.

-------------------

AWS를 사용하는 경우로드 밸런서에서 HTTPS를 종료하고 필터를 사용하여 HTTP 연결을 HTTPS로 리디렉션 할 수 있습니다.

AWS 회의 :

443 (로드 밸런서) ----------> 80 (서버)

80 (로드 밸런서) ----------> 80 (서버)

필터 :

object HTTPSRedirectFilter extends Filter with Logging {

    def apply(nextFilter: (RequestHeader) => Future[SimpleResult])(requestHeader: RequestHeader): Future[SimpleResult] = {
            //play uses lower case headers.
                    requestHeader.headers.get("x-forwarded-proto") match {
                                case Some(header) => {
                                                if ("https" == header) {
                                                                    nextFilter(requestHeader).map { result =>
                                                                                            result.withHeaders(("Strict-Transport-Security", "max-age=31536000"))
                                                                                                                }
                                                                                                                                } else {
                                                                                                                                                    Future.successful(Results.Redirect("https://" + requestHeader.host + requestHeader.uri, 301))
                                                                                                                                                                    }
                                                                                                                                                                                }
                                                                                                                                                                                            case None => nextFilter(requestHeader)
                                                                                                                                                                                                    }
                                                                                                                                                                                                        }
                                                                                                                                                                                                        }
                                                                                                                                                                                                        
-------------------

당신은 할 수 있어야합니다. 다음을 수행하십시오.

  1. application.config 파일에서 http.port 및 https.port 설정
  2. 보안 페이지를 가리켜 야하는 경우 @@ {Controller.action (). secure ()} 사용자. @@를 모두 사용하여 전체 URL (https 포함)을 생성하고 HTTPS 프로토콜을 원하는 Play에 대한 힌트를 확보하십시오.

이것은 작동합니다

-------------------

컨트롤러 관점에서는 불가능한 것 같습니다. 템플릿 Pere 솔루션에서 작동하지만 이것은 템플릿에서만 https URL을 생성합니다.

사용자가 수동으로 입력하거나 http url에 대한 링크를 따라 로그인 작업에 액세스하는 경우 https를 적용 / 리디렉션하는 방법이없는 것 같습니다.

가장 좋은 방법은 프런트 엔드 프록시를 사용하는 것 같습니다.



출처
https://stackoverflow.com/questions/7415030