我正在尝试在Dropwizard Web应用程序中实现OAuth2身份验证。我创建了所需的Authenticator
和Authorizer
类,并在我的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)进行一些阅读之后,我发现必须在每个请求的标头中从客户端发送令牌。所以我的问题是如何告诉用户的浏览器(客户端)将令牌包含在未来请求的标题中?
答案 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