Pertanyaan Intercept request dan periksa otorisasi di playframework


saya menggunakan play framework 2.4.2 dengan Java dan saya ingin memvalidasi bahwa pengguna login dengan mencegat semua permintaan dan memeriksa apakah nilai sesi diatur. Jadi saya telah memperpanjang DefaultHttpRequestHandler dan menimpa createAction Metode untuk mencegat semua permintaan. Namun, saya belum menemukan cara yang baik untuk memvalidasi sesi.

Opsi 1 - Gagal

Saat saya mencoba mengambil nilai sesi, saya mendapatkan pengecualian waktu proses: There is no HTTP Context available from here

Di bawah ini adalah kelas yang saya kerjakan:

public class RequestHandler extends DefaultHttpRequestHandler {
    @Override
    public Action createAction(Http.Request request, Method method) {
        session("loggedIn"); // Throws runtime Exception: no HTTP Context
    }
}

Opsi 2 - Jelek

Karena sesi secara teknis adalah cookie saya dapat mengambil nilai dari header dengan kode seperti berikut:

for(String cookie : request.headers().get("Cookie")){
    System.out.println("cookie: "+cookie);
}

Tapi kemudian saya harus mem-parsing string cookie yang terlihat seperti baris berikut untuk mendapatkan nilai loggedIn. Untuk kotor untuk seleraku.

_ga=GA1.1.1508004144.1421266376; ki_r=; ki_t=1438789543788%378129908%3B1438789543788%3B1%3B1; PLAY_SESSION=0570411c3eb55ad230681539ddcfaa4220583fd-loggedIn=1

Opsi 3 - Terlalu mudah melupakan anotasi

Saya melihat beberapa situs web mendokumentasikan pendekatan yang berbeda dan malah membuat
komposisi aksi dan tambahkan anotasi yang sesuai untuk setiap kelas atau metode pengontrol.

Masalah dengan pendekatan ini adalah mengharuskan pengembang untuk mengingat untuk menambahkan anotasi. Saya lebih suka membalik ini untuk memblokir setiap rute secara default dan kemudian menambahkan anotasi ke rute yang tidak memerlukan validasi.

Beberapa situs yang mendokumentasikan komposisi tindakan:

  1. http://alexgaribay.com/2014/06/16/authentication-in-play-framework-using-java/
  2. https://www.playframework.com/documentation/2.2.1/JavaGuide4

Pertanyaan

Apakah ada cara untuk memvalidasi secara global jika pengguna harus memiliki akses ke halaman dan bagaimana saya mendapatkan variabel sesi?

* Harap dicatat bahwa saya tidak tertarik menggunakan plugin pihak ketiga untuk otentikasi.


4
2017-08-05 19:29


asal


Jawaban:


Bahkan jika saya akan mempertimbangkan kembali menggunakan komposisi tindakan, Anda dapat memperbaiki Opsi 1.

Buat anotasi khusus untuk menandai tindakan yang tidak perlu validasi.

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface NoAuthRequired {}

Kemudian ubah implementasi HttpRequestHandler Anda.

public class RequestHandler extends DefaultHttpRequestHandler {
    @Override
    public Action createAction(Http.Request request, Method actionMethod) {
        return new Action.Simple() {
            @Override
            public F.Promise<Result> call(Http.Context ctx) throws Throwable {
                // if the action is annotated with @NoAuthRequired or user is logged in delegate to it
                if (actionMethod.isAnnotationPresent(NoAuthRequired.class) || ctx.session().containsKey("loggedIn")) {
                    return delegate.call(ctx);
                }
                // otherwise, block access
                else {
                    return F.Promise.pure(forbidden("You're not allowed"));
                }
            }
        };
    }
}

Dengan cara ini, setiap rute memerlukan validasi kecuali secara eksplisit dianotasi.

Seperti yang Anda lihat dari kode, sesi ini tersedia melalui Konteks.


6
2017-08-05 22:08