- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在Wildfly中实现自己的仅承载身份验证的实现。本质上,我将执行以下步骤:
收到请求后,我将检查它是否具有授权标头。
我获得令牌并针对数据库(在这种情况下,我将使用Redis)进行检查以确保其有效性。
我从数据库中获得了该用户的角色。
我希望能够在我的其余服务上使用@RolesAllowed
注释。
我该怎么办?我需要如何修改Wildfly配置文件?我需要实现哪些接口?如何将用户的角色传递给安全上下文,以便Wildfly为我执行@RolesAllowed
检查?
如果回答,请认为我是一位经验丰富的Java程序员,但对Wildfly还是陌生的,因此您可以跳过有关编程逻辑的详细信息,而不是有关Wildfly配置的详细信息。另外,在您的答案中,不必担心令牌最初是如何到达Redis的,或客户端如何获得的。
编辑
这是我所做的,但是还没有运气。我已经实现了实现AuthenticationFilter
的ContainerRequestFilter
。 (我在下面仅包括已实现的主要过滤器功能。请注意,有些帮助器功能未从数据库中获取角色)。即使在函数末尾用用户概要文件(包含角色)设置了请求上下文的安全性上下文时,我也无法在我的JAX-RS rest服务上使用@RolesAllowed
注释。关于我该怎么办的任何指示?
注意:我尚未修改任何Wildfly配置文件或web.xml文件。我知道每个请求都将调用过滤器,因为我能够在每个请求中记录来自该过滤器的消息。
/**
* (non-Javadoc)
* @see javax.ws.rs.container.ContainerRequestFilter#filter(javax.ws.rs.container.ContainerRequestContext)
*/
@Override
public void filter(ContainerRequestContext requestContext) {
//1. Read the JSON web token from the header
String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
return;
}
String token = authorizationHeader.substring("Bearer".length()).trim();
try{
//Note that if the token is not in the database,
//an exception will be thrown and we abort.
UserProfile userProfile = this.getUserProfile(token);
if (null == userProfile){
userProfile = this.decodeToken(token);
}
if (null == userProfile){
throw new Exception();
}
String role = userProfile.getUserRole();
if (null == role){
role = this.getRoleFromMod(userProfile);
if (null == role){
role = RoleType.READ_ONLY;
}
userProfile.setUserRole(role);
this.updateUserProfileForToken(token, userProfile);
}
userProfile.setUserRole(role);
//5. Create a security context class that implements the crazy interface
//and set it here.
requestContext.setSecurityContext(new ModSecurityContext(userProfile));
}
catch(Exception e){
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
}
}
最佳答案
是的,我不确定它在EE环境中如何工作,甚至使资源类成为无状态的Bean。 @RolesAllowed
批注旨在用于ejb。在这种情况下,从servlet请求中检索主体(我相信)。我要做的只是实现您自己的授权过滤器,该过滤器查找注释并在安全上下文中对照主体进行检查。
您可以看到how Jersey implements it。除了AnnotatedMethod
类之外,没有任何东西是真正针对泽西岛的。为此,您可以使用java.lang.reflect.Method
(resourceInfo.getResourceMethod())进行一些反射。除此之外,您几乎可以照原样复制代码。完成后,只需在应用程序中注册RolesAllowedDynamicFeature
。或者只是用@Provider
对其进行注释以进行扫描。
您还需要确保认证过滤器用@Priority(Priorities.AUTHENTICATION)
注释,以便在授权过滤器之前用@Priority(Priorities.AUTHORIZATION)
对其进行调用。
更新
这是我链接到的代码的重构,因此它不使用Jersey特定的类。 AnnotatedMethod
仅更改为Method
。
@Provider
public class RolesAllowedFeature implements DynamicFeature {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext configuration) {
Method resourceMethod = resourceInfo.getResourceMethod();
if (resourceMethod.isAnnotationPresent(DenyAll.class)) {
configuration.register(new RolesAllowedRequestFilter());
return;
}
RolesAllowed ra = resourceMethod.getAnnotation(RolesAllowed.class);
if (ra != null) {
configuration.register(new RolesAllowedRequestFilter(ra.value()));
return;
}
if (resourceMethod.isAnnotationPresent(PermitAll.class)) {
return;
}
ra = resourceInfo.getResourceClass().getAnnotation(RolesAllowed.class);
if (ra != null) {
configuration.register(new RolesAllowedRequestFilter(ra.value()));
}
}
@Priority(Priorities.AUTHORIZATION) // authorization filter - should go after any authentication filters
private static class RolesAllowedRequestFilter implements ContainerRequestFilter {
private final boolean denyAll;
private final String[] rolesAllowed;
RolesAllowedRequestFilter() {
this.denyAll = true;
this.rolesAllowed = null;
}
RolesAllowedRequestFilter(final String[] rolesAllowed) {
this.denyAll = false;
this.rolesAllowed = (rolesAllowed != null) ? rolesAllowed : new String[]{};
}
@Override
public void filter(final ContainerRequestContext requestContext) throws IOException {
if (!denyAll) {
if (rolesAllowed.length > 0 && !isAuthenticated(requestContext)) {
throw new ForbiddenException("Not Authorized");
}
for (final String role : rolesAllowed) {
if (requestContext.getSecurityContext().isUserInRole(role)) {
return;
}
}
}
throw new ForbiddenException("Not Authorized");
}
private static boolean isAuthenticated(final ContainerRequestContext requestContext) {
return requestContext.getSecurityContext().getUserPrincipal() != null;
}
}
}
DynamicFeature
的工作原理。为此,让我们首先将讨论的上下文更改为当前
AuthenticationFilter
的实现。
@Authenticated
批注
@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Authenticated{}
DynamicFeature
来检查注释,然后仅在找到注释时注册过滤器。例如
@Provider
public class AuthenticationDynamicFeature implements DynamicFeature {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext configuration) {
if (resourceInfo.getResourceMethod().isAnnotationPresent(Authenticated.class)) {
configuration.register(new AuthenticationFilter());
return;
}
if (resourceInfo.getResourceClass().isAnnotationPresent(Authenticated.class)) {
configuration.register(new AuthenticationFilter());
}
}
}
AuthenticationDynamicFeature
类,它将进行注册,以便仅过滤带有
@Authenticated
注释的方法和类。
ResourceInfo
中获得对
AuthenticationFilter
的引用。例如,检查注解(如果不存在),然后继续。
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
@Context
private ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext context) throws IOException {
boolean hasAnnotation = false;
if (resourceInfo.getResourceMethod().isAnnotationPresent(Authenticated.class)
|| resourceInfo.getResourceClass().isAnnotationPresent(Authenticated.class)) {
hasAnnotation = true;
}
if (!hasAnnotation) return;
// process authentication is annotation is present
DynamicFeature
。最好只使用
DynamicFeature
,我只是举一个例子进行演示。
RolesAllowedDynamicFeature
查看第一段代码,则可以更好地了解正在发生的情况。它仅为使用
@RolesAllowed
和
@DenyAll
注释的方法和类注册过滤器。您甚至可以对其进行重构,以将所有注释逻辑(而不是功能)包含在过滤器中。您只有过滤器。就像我在上面的
AuthenticationFilter
示例中所做的一样。同样,这只是出于示例目的。
DynamicFeature
的注册而言,它的工作方式与注册任何其他资源类或提供程序类(例如,您的身份验证过滤器)相同。因此,无论您如何注册,只需以相同的方式注册
RolesAllowedDynamicFeature
。有扫描,其中扫描
@Path
和
@Provider
批注。如果这是当前使用的功能,则只需使用
@Provider
注释要素类即可注册它。例如,只有一个空的
Application
子类将导致扫描发生
@ApplicationPath("/api")
public class RestApplication extends Application {}
Application
子类中进行了显式注册。例如
@ApplicationPath("/api")
public class RestApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<>();
classes.add(AuthenticationFilter.class);
classes.add(RolesAllowedFeature.class);
classes.add(SomeResource.class);
return classes;
}
}
AuthenticationFilter
用
@Priority(Priorities.AUTHENTICATION)
注释。这是为了确保在授权过滤器之前调用身份验证过滤器。这需要发生,因为身份验证筛选器是设置安全上下文的元素,而授权筛选器会对其进行检查。
SecurityContext.isUserInRole(role)
批注中调用
@RolesAllowed
传递角色。因此,您需要确保正确实施
isUserInRole
。
关于java - 不使用Keycloak的Wildfly中仅承载身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32471808/
我正在使用SQL Server 2008 R2,并且想创建一个触发器。 对于每个添加(仅添加),将像这样更新一列: ABC-CurrentYear-AutoIncrementCode 例子: ABC-
是否可以在显示最终一致性的数据存储中创建/存储用户帐户? 似乎不可能在没有一堆架构复杂性的情况下管理帐户创建,以避免可能发生具有相同 UID(例如电子邮件地址)的两个帐户的情况? 最终一致性存储的用户
您好, 我有一个带有 Identity 的 .NetCore MVC APP并使用 this指导我能够创建自定义用户验证器。 public class UserDomainValidator : IU
这与以下问题相同:HiLo or identity? 我们以本站的数据库为例。 假设该站点具有以下表格: 帖子。 投票。 注释。 使用它的最佳策略是什么: 身份 - 这是更常见的。 或者 HiLo -
我想将 Blazor Server 与 ASP.NET Identity 一起使用。但我需要使用 PostgreSQL 作为用户/角色存储,因为它在 AWS 中。 它不使用 EF,这是我需要的。 我创
我正在开发一个 .NET 应用程序,它可以使用 Graph API 代表用户发送电子邮件。 提示用户对应用程序进行授权;然后使用获取的访问 token 来调用 Graph API。刷新 token 用
我使用 ASP.NET 身份和 ClaimsIdentity 来验证我的用户。当用户通过身份验证时,属性 User.Identity 包含一个 ClaimsIdentity 实例。 但是,在登录请求期
所以我在两台机器上都安装了 CYGWIN。 如果我这样做,它会起作用: ssh -i desktop_rsa root@remoteserver 这需要我输入密码 ssh root@remoteser
我尝试在 mac osx 上的终端中通过 telnet 连接到 TOR 并请求新身份,但它不起作用,我总是收到此错误消息: Trying 127.0.0.1... telnet: connect to
我正在开发一个 .NET 应用程序,它可以使用 Graph API 代表用户发送电子邮件。 提示用户对应用程序进行授权;然后使用获取的访问 token 来调用 Graph API。刷新 token 用
我正在开发一项服务,客户可以在其中注册他们的 webhook URL,我将发送有关已注册 URL 的更新。为了安全起见,我想让客户端(接收方)识别是我(服务器)向他们发送请求。 Facebook和 G
在 Haskell 中,有没有办法测试两个 IORef 是否相同?我正在寻找这样的东西: IORef a -> IORef a -> IO Bool 例如,如果您想可视化由 IORef 组成的图形,这
我是 .NET、MVC 和身份框架的新手。我注意到身份框架允许通过注释保护单个 Controller 操作。 [Authorize] public ActionResult Edit(int? Id)
我有一列具有身份的列,其计数为19546542,我想在删除所有数据后将其重置。我需要类似ms sql中的'dbcc checkident'这样的内容,但在Oracle中 最佳答案 在Oracle 12
这是我用来创建 session 以发送电子邮件的代码: props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enabl
我想了解 [AllowAnonymous] 标签的工作原理。 我有以下方法 [HttpGet] public ActionResult Add() { return View(); } 当我没
在使用沙盒测试环境时,PayPal 身份 token 对某些人显示而不对其他人显示的原因是否有任何原因。 我在英国使用 API,终生无法生成或找到 token 。 我已经遵循协议(protocol)并
我对非常简单的事情有一些疑问:IDENTITY。我尝试在 phpMyAdmin 中创建表: CREATE TABLE IF NOT EXISTS typEventu ( typEventu
习语 #1 和 #5 是 FinnAPL Idiom Library两者具有相同的名称:“Progressive index of (without replacement)”: ((⍴X)⍴⍋⍋X⍳
当我第一次在 TFS 中设置时,我的公司拼错了我的用户名。此后他们将其更改为正确的拼写,但该更改显然未反射(reflect)在 TFS 中。当我尝试 checkin 更改时,出现此错误: 有没有一种方
我是一名优秀的程序员,十分优秀!