Dropwizard身份验证标头令牌

时间:2018-01-25 12:15:39

标签: authentication login oauth-2.0 dropwizard

我正在尝试在Dropwizard Web应用程序中实现OAuth2身份验证。我创建了所需的AuthenticatorAuthorizer类,并在我的Application的run-method中添加了Dropwizard manual中提供的代码,如下所示:

environment.jersey().register(new AuthDynamicFeature(
                new OAuthCredentialAuthFilter.Builder<User>()
                .setAuthenticator(new TokenAuthenticator(service))
                .setAuthorizer(new TokenAuthorizer())
                .setPrefix("Bearer")
                .buildAuthFilter()));
        environment.jersey().register(RolesAllowedDynamicFeature.class);
        //If you want to use @Auth to inject a custom Principal type into your resource
        environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));

我的所需行为是,在我的客户端通过在我的登录页面上提供他/她的凭据登录后,我想将客户端重定向到我使用Dropwizard视图创建的问候页面,并且在路径下:“/ me “如下:

//After succesfull login and token generation
return Response.seeOther(new URI("/me")).build(); // redirect to greeting page

我的问候语资源如下:

@Path("/me")
@Produces(MediaType.TEXT_HTML)
public class UserResource {

    @GET
    public UserView getView(@Auth User user) {
            return new UserView(user);
    }

}

目前我收到“需要凭据才能访问此资源”。登录后的响应。在对令牌认证(nice explanation here)进行一些阅读之后,我发现必须在每个请求的标头中从客户端发送令牌。所以我的问题是如何告诉用户的浏览器(客户端)将令牌包含在未来请求的标题中?

1 个答案:

答案 0 :(得分:0)

我设法通过以下方式解决了这个问题:

为了验证用户,必须以module.name_mapper='^\(.*\)\.json$' -> '<PROJECT_ROOT>/path/to/json/files' 的形式在请求的标头中发送令牌。该令牌在验证时由服务器发送,并且必须由客户端/用户存储以在将来的请求中发送。当我的登录表单提交时,我设法使用ajax请求存储令牌,如下所示:

Authorization: Bearer <token-value>

登录资源然后生成JSON,该JSON在上面的代码中的数据变量中接收。所需的令牌位于data.token中 - 然后存储。我在名为“url”的JSON中添加了第二个条目,以指示成功验证后重定向到的路径。

现在,令牌在需要时存储在客户端。为了在请求标头中发送此标记,我需要更改使用Dropwizard提供的视图的方法。我不是直接要求身份验证,而是拆分View的资源和经过身份验证的数据资源。为了澄清,请考虑以下示例。用户登录,获取令牌,然后转到显示其用户名的页面。对于该页面,使用.ftl文件创建View资源以用作模板。类似的东西:

<#-- Handle form submission response to save the token on the client side-->
<script>
    $('#loginForm').submit(function(event){
        event.preventDefault();
        $.ajax({
          url: $(this).attr('action'),
          type: 'POST',
          data : $(this).serialize(),
          dataType: 'json',
          success: function(data){
            //alert("The server says success!!: " +data);
            console.log(data);
            window.sessionStorage.accessToken = data.token;
            window.location = data.url;

          },
          error: function(data){
            alert("The server says error! : ");
            console.log(data);
          }
        });
});
</script>

和...

@Path("/me")
@Produces(MediaType.TEXT_HTML)
public class UserResource {


    @GET
    public UserView getView() {
       return new UserView();

    }
}

和user.ftl:

public class UserView extends View {

    public UserView() {
        super("user.ftl");

    }
}

现在要检索用户名,我创建了一个在新路径上生成JSON的新资源。例如:

<#include "include/head.html">
<#include "include/header.html">

<!-- Header --> 
<div id ="headerWrapper">
</div>

<div class="container-fluid">

<div id="name">
    <p>Hello user</p>
</div>

</div>

<#include "include/footer.html">

此资源需要身份验证并提供可从中检索用户名的JSON。现在要获取用户名并将其放在视图中,只需向@Path("/getdetails") @Produces(MediaType.APPLICATION_JSON) public class UserDetailsResource { @GET @Timed @UnitOfWork public User getDetails(@Auth User user) { return user; } } 添加一个脚本,并向getdetails资源发送ajax请求,在标头中提供令牌并使用结果将用户名放在视图中。见下面的脚本。

users.ftl