拦截实现HttpRequestHandler并在会话中设置用户的传入请求 - 播放2.4.6

时间:2016-03-11 19:51:45

标签: java playframework playframework-2.0

我试图在header param中拦截所有具有用户凭据的传入请求,一旦经过身份验证我尝试在会话中设置用户。来自外部应用程序的所有请求都将以app作为代码来告知其外部请求,因此需要首先进行身份验证。但是这一切都没有用,因为我没有看到在控制台上打印的任何东西,而且我也没有上下文。请协助。我的代码如下:

我正在使用post man发送请求,如下所示: Postman request

application.conf

play.http.requestHandler=settings.com.xyz.application.ApplicationRequestHandler

HttpRequestHandler实施:

public class ApplicationRequestHandler implements HttpRequestHandler {
    @Inject
    ActiveDirectoryService activeDirectoryService;

    @Override
    public Action createAction(Request request, Method method) {
        return new Action.Simple() {
            @Override
            public F.Promise<Result> call(Http.Context ctx) throws Throwable {
                String app = request.getHeader("app");
                //ActiveDirectoryService activeDirectoryService = Play.current().injector().instanceOf(ActiveDirectoryService.class);
                if(app != null && app.equals("app")) {
                  if(ctx.current().session().get("username") == null) {
                    String username = request.getHeader("username");
                    String password = request.getHeader("password");
                    System.out.println("#######################################################3" + username + "," + password + "," + activeDirectoryService);
                    if(activeDirectoryService.authenticate(username, password)) {
                        ctx.current().session().put("username", app + username);
                    }
                }
                }
                return delegate.call(ctx);
            }
        };
    }

    @Override
    public Action wrapAction(Action action) {
        return action;
    }
}

1 个答案:

答案 0 :(得分:0)

这里有一些可能的问题。

对邮差的一些滥用:

这是最合理的问题(但请参阅下面的其他问题)。更改处理程序代码以打印所有收到的标题:

public class ApplicationRequestHandler implements HttpRequestHandler {
    @Override
    public Action createAction(Http.Request request, Method method) {
        return new Action.Simple() {
            @Override
            public F.Promise<Result> call(Http.Context ctx) throws Throwable {

                // Print all headers
                request.headers().forEach((name, values) -> {
                    System.out.printf("%s: %s \n", name, java.util.Arrays.asList(values));
                });

                String app = request.getHeader("app");
                if(app != null && app.equals("app")) {
                    if(ctx.session().get("username") == null) {
                        String username = request.getHeader("username");
                        String password = request.getHeader("password");
                        System.out.println(username + "," + password);
                    }
                }
                return delegate.call(ctx);
            }
        };
    }

    @Override
    public Action wrapAction(Action action) {
        return action;
    }
}

上面的处理程序在使用curl的以下请求时非常适合我:

curl -v -I http://localhost:9000

这将打印curl发送的标题,以便您检查应用程序收到的标题。然后发送另一个发送app标题的请求:

curl -v -I -H "app: app" -H "username: marcospereira" -H "password: secret" http://localhost:9000

未找到行动

您确定有一条与POST/testapplication/getdata匹配的路线吗?如果未找到任何操作,您的处理程序将永远不会执行,因为要求选择了一个操作。如果路由器无法找到POST /testapplication/getdata的操作,则无法访问您的处理程序。

鉴于此,如果您需要HttpRequestHandlerFilter,您可以重新考虑。如果您决定使用过滤器,我强烈建议您upgrade to Play 2.5.0improvements made at the Java version of filters API而{{3}}。