Play Framework 和 Deadbolt 重定向 onAuthFailure
Play Framework and Deadbolt redirect onAuthFailure
我已经从 Play Framework 实现了我自己的 Authenticator,从 Deadbolt 实现了 DeadboltHandler。
使用 onUnauthorized 和 onAuthFailure 方法,我可以将未登录的用户发送到 "login page" 而不是他们尝试访问的实际页面。
但是,我不想将用户直接发送到 "login page",而是想根据用户尝试访问的页面来指定应将用户发送到哪个页面。例如,如果用户试图访问 /settings,则用户应该被重定向到登录页面。如果用户试图访问 /player/1 用户应该被重定向到另一个页面,比如 "create user" 页面。
我希望有一些聪明的方法可以用注释来做到这一点,比如:@someannotation(redirect = route/id) 所以如果用户没有登录我可以重定向到相关的路由,否则符合标准 "login page".
有人有什么想法吗?
控制器和路由方法的代码片段示例:
@Security.Authenticated(Secured.class)
@SubjectPresent(content = "createuser")
@DeferredDeadbolt
public class Settings extends Controller {
@SubjectPresent(content = "login")
@CustomRestrict(value = { @RoleGroup({ UserRole.player}), @RoleGroup(UserRole.server_owner) })
public static Result settings() {
DeadboltHandler onAuthFailure 的代码片段示例:
@Override
public F.Promise<Result> onAuthFailure(Http.Context context, String content) {
return F.Promise.promise(new F.Function0<Result>() {
@Override
public Result apply() throws Throwable {
System.out.println(content);
有几种不同的方法可以做到这一点。
方法 1:重新利用 content
值
在这种方法中,您可以使用约束注释的 content
值向处理程序提供提示。您可以使用 class 级约束来定义默认重定向,例如转到登录页面,方法级约束覆盖默认重定向。所有约束都有 content
值,我只是以 SubjectPresent
为例;您还可以混合约束,例如SubjectPresent
在 class 级别和 Restrict
在方法级别。
@SubjectPresent(content = "login")
public class FooController extends Controller {
public Result settings() {
// ...
}
public Result somethingElse() {
// ...
}
@SubjectPresent(content = "create-user")
public Result viewUser() {
// ...
}
}
在您的 DeadboltHandler 实现中,您需要对内容进行测试:
public CompletionStage<Result> onAuthFailure(final Http.Context context,
final Optional<String> content) {
return CompletableFuture.supplyAsync(() -> content.map(redirectKey -> {
final Result result;
if ("login".equals(redirectKey)) {
result = [redirect to login action]
}
else if ("create-user".equals(redirectKey)) {
result = [redirect to create user action]
} else {
result = [redirect to default authorization failure action]
}
}).orElseGet(() -> [redirect to default authorization failure action]), executor);
}
方法 2:使用 ROUTE_PATTERN 标签
您可以使用请求中指定的路由来确定请求的操作,而不是在约束注释中指定键。
public CompletionStage<Result> onAuthFailure(final Http.Context context,
final Optional<String> content) {
final String route = requestHeader.tags().get(Router.Tags.ROUTE_PATTERN);
// examine the route and work out what you want to do
}
我已经从 Play Framework 实现了我自己的 Authenticator,从 Deadbolt 实现了 DeadboltHandler。
使用 onUnauthorized 和 onAuthFailure 方法,我可以将未登录的用户发送到 "login page" 而不是他们尝试访问的实际页面。
但是,我不想将用户直接发送到 "login page",而是想根据用户尝试访问的页面来指定应将用户发送到哪个页面。例如,如果用户试图访问 /settings,则用户应该被重定向到登录页面。如果用户试图访问 /player/1 用户应该被重定向到另一个页面,比如 "create user" 页面。
我希望有一些聪明的方法可以用注释来做到这一点,比如:@someannotation(redirect = route/id) 所以如果用户没有登录我可以重定向到相关的路由,否则符合标准 "login page".
有人有什么想法吗?
控制器和路由方法的代码片段示例:
@Security.Authenticated(Secured.class)
@SubjectPresent(content = "createuser")
@DeferredDeadbolt
public class Settings extends Controller {
@SubjectPresent(content = "login")
@CustomRestrict(value = { @RoleGroup({ UserRole.player}), @RoleGroup(UserRole.server_owner) })
public static Result settings() {
DeadboltHandler onAuthFailure 的代码片段示例:
@Override
public F.Promise<Result> onAuthFailure(Http.Context context, String content) {
return F.Promise.promise(new F.Function0<Result>() {
@Override
public Result apply() throws Throwable {
System.out.println(content);
有几种不同的方法可以做到这一点。
方法 1:重新利用 content
值
在这种方法中,您可以使用约束注释的 content
值向处理程序提供提示。您可以使用 class 级约束来定义默认重定向,例如转到登录页面,方法级约束覆盖默认重定向。所有约束都有 content
值,我只是以 SubjectPresent
为例;您还可以混合约束,例如SubjectPresent
在 class 级别和 Restrict
在方法级别。
@SubjectPresent(content = "login")
public class FooController extends Controller {
public Result settings() {
// ...
}
public Result somethingElse() {
// ...
}
@SubjectPresent(content = "create-user")
public Result viewUser() {
// ...
}
}
在您的 DeadboltHandler 实现中,您需要对内容进行测试:
public CompletionStage<Result> onAuthFailure(final Http.Context context,
final Optional<String> content) {
return CompletableFuture.supplyAsync(() -> content.map(redirectKey -> {
final Result result;
if ("login".equals(redirectKey)) {
result = [redirect to login action]
}
else if ("create-user".equals(redirectKey)) {
result = [redirect to create user action]
} else {
result = [redirect to default authorization failure action]
}
}).orElseGet(() -> [redirect to default authorization failure action]), executor);
}
方法 2:使用 ROUTE_PATTERN 标签
您可以使用请求中指定的路由来确定请求的操作,而不是在约束注释中指定键。
public CompletionStage<Result> onAuthFailure(final Http.Context context,
final Optional<String> content) {
final String route = requestHeader.tags().get(Router.Tags.ROUTE_PATTERN);
// examine the route and work out what you want to do
}