当前位置: 首页 > 知识库问答 >
问题:

Elytron通过表单身份验证进行编程登录

严知
2023-03-14

我们目前正在从遗留安全子系统迁移到Elytron,并在JBoss EAP 7.3.6中部署了一个基于Struts2的web应用程序,该应用程序应该支持多种“风格”的身份验证。

登录的标准方式应该是,用户以登录表单(j_security_check)手动提供凭据,然后单击相应的按钮。这在我们的设置中与Elytron配合得很好。

第二种可能性是,对Web应用程序受保护内容的GET请求可能包含包含JWT令牌的自定义cookie。这个cookie被一个io.undertow.server.HttpHandler拦截,它在它的io.undertow.server.HttpHandler#handleRequest方法中处理传入的请求。这个处理程序是由io.undertow.servlet.api.DeploymentInfo#addSecurityWrapper注册的,带有一个DeploymentInfo,它是由io.undertow.servlet.ServletExent的实现提供的。在META-INF/service/io.undertow.servlet.ServletExent中注册为服务提供程序。

我们实现的io中的请求处理。在船底。服务器HttpHandler#HandlerRequest从cookie中提取JWT令牌,对其进行预验证并确定包含的用户名。这个用户名和作为密码的令牌被用作调用javax的输入。servlet。http。HttpServletRequest#登录

对于旧版安全子系统,服务器的行为是,此登录调用触发了针对已配置旧版安全域的身份验证,并在下面创建了一个会话,以便前一个GET请求的HTTP 200响应包含一个带有新的JSESSIONIDCookie的Set Cookie头。

使用Elytron,javax.servlet.http.HttpServletRequest#log不会执行任何操作,不会触发针对Elytron安全域和安全域的身份验证,也不会触发会话的创建。浏览器只显示登录表单,该表单应该被描述的拦截过程跳过。

调试javax的实现。servlet。http。JBoss附带的HttpServletRequest#登录。我们从io开始。在船底。servlet。spec.HttpServletRequestImpl#login调用login=sc.login(用户名、密码)。当使用Elytron时,这个SecurityContextorg。野蝇。爱丽特龙。网状物在船底。服务器SecurityContextImpl<代码>组织。野蝇。爱丽特龙。网状物在船底。服务器SecurityContextImpl#login首先检查if(httpAuthenticator==null)httpAuthenticator仅在org中设置。野蝇。爱丽特龙。网状物在船底。服务器SecurityContextImpl#authenticate,通过调用javax来调用它。servlet。http。HttpServletRequest#验证

这就解释了为什么要简单地调用io。在船底。servlet。spec.HttpServletRequestImpl#login什么也没做。我试着调用javax。servlet。http。HttpServletRequest#先进行身份验证,在内部实例化httpAuthenticator,然后是javax。servlet。http。HttpServletRequest#登录。这至少最终触发了针对已配置的Elytron安全域和安全域的身份验证和授权。身份验证/授权成功,但Undertow仍然没有发出新的JSESSIONIDcookie,浏览器再次显示登录表单,而不是继续访问受保护的资源。

我目前没有主意,如何处理这个问题,以及如何实现与遗留安全子系统相同的行为。为什么Elytron实现了io。在船底。安全应用程序编程接口。SecurityContext的行为与传统安全性(io.undertow.security.impl.SecurityContextImpl)相比有很大不同?如何使用Elytron withjavax以编程方式登录基于表单的web应用程序。servlet。http。HttpServletRequest#登录和/或javax。servlet。http。HttpServletRequest#验证

所有这些的相关JBoss配置如下所示:

暗流:

<application-security-domains>
    <application-security-domain name="my_app_security_domain" http-authentication-factory="MyHttpAuthFactory"/>
</application-security-domains>

爱丽特龙:

<security-domains>
    <security-domain name="MySecurityDomain" default-realm="MyCachingRealm" permission-mapper="default-permission-mapper">
        <realm name="MyCachingRealm" role-decoder="FromRolesAttributeDecoder"/>
    </security-domain>
</security-domains>

<security-realms>
    <custom-realm name="MyCustomRealm" module="module name redacted" class-name="class name redacted"/>
    <caching-realm name="MyCachingRealm" realm="MyCustomRealm" maximum-age="300000"/>
    <identity-realm name="local" identity="$local"/>
</security-realms>

<mappers>
    <simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
        <permission-mapping>
            <principal name="anonymous"/>
            <permission-set name="default-permissions"/>
        </permission-mapping>
        <permission-mapping match-all="true">
            <permission-set name="login-permission"/>
            <permission-set name="default-permissions"/>
        </permission-mapping>
    </simple-permission-mapper>
    <constant-realm-mapper name="local" realm-name="local"/>
    <constant-realm-mapper name="MyRealmMapper" realm-name="MyCachingRealm"/>
    <simple-role-decoder name="FromRolesAttributeDecoder" attribute="Roles"/>
</mappers>

<http>
    <http-authentication-factory name="MyHttpAuthFactory" security-domain="MySecurityDomain" http-server-mechanism-factory="global">
        <mechanism-configuration>
            <mechanism mechanism-name="FORM" realm-mapper="MyRealmMapper">
                <mechanism-realm realm-name="MyRealm"/>
            </mechanism>
        </mechanism-configuration>
    </http-authentication-factory>
    <provider-http-server-mechanism-factory name="global"/>
</http>

共有1个答案

虞博涛
2023-03-14

这是JBoss EAP中的一个错误,已在EAP 7.3.8和7.4.1中修复。看见https://issues.redhat.com/browse/JBEAP-21737和https://issues.redhat.com/browse/JBEAP-21738详细信息。

 类似资料:
  • 问题: 我们有一个spring的基于MVC的RESTful API,它包含敏感信息。API应该是安全的,但是不希望在每个请求中发送用户的凭据(User/Pass组合)。根据REST指南(和内部业务需求),服务器必须保持无状态。API将由另一台服务器以混搭方式使用。 要求: > 客户端请求使用凭据(不受保护的URL);服务器返回一个安全令牌,该令牌包含足够的信息,供服务器验证未来的请求并保持无状态。

  • 我的身份验证系统完全正常工作(我遵循了文档教程)https://symfony.com/doc/current/security/form_login_setup.html). 但我有一个问题:当恶意用户禁用必需的密码字段并尝试登录时,我会收到一个错误500“警告:空密码” 认证系统在一种情况下不起作用: 当用户名与数据库中存储的用户名匹配,但密码为空,并且我尝试登录时,就会出现500 Twig错

  • 问题内容: 在(带有)中,我尝试使用以下语句通过基本身份验证访问我的网页: 但是Google Chrome浏览器在控制台中向我发出以下警告: [弃用]其URL包含嵌入式凭据(例如https://user:pass@host/)的子资源请求被阻止。有关更多详细信息,请参见https://www.chromestatus.com/feature/5669008342777856。 在标记的链接中提到该

  • (我曾在SO上回顾过类似的问题,但没有一个建议对我有效) 我有一个API服务,运行在Google App Engine上(在Google云平台上)。我需要通过谷歌管理目录API的身份验证,以便我可以在我们的GSuite域上创建组。 我最初尝试了隐式授权,遵循指南,以手动获取和提供服务帐户凭据,但我认为这可能仅限于在Google App Engine上运行的应用程序之间的通信。我的理解是,在App

  • 问题内容: 注销HTTP身份验证受保护的文件夹的 正确 方法是什么? 有一些解决方法可以实现这一目标,但是它们可能会带来危险,因为它们可能有故障或在某些情况下/浏览器中无法使用。这就是为什么我要寻找正确和清洁的解决方案。 问题答案: 亩。 没有正确的方法 ,甚至没有跨浏览器一致的方法。 这是来自HTTP规范(第15.6节)的问题: 现有的HTTP客户端和用户代理通常会无限期地保留身份验证信息。HT

  • 目前用户名总是匿名的。设置调用方主体的正确方法是什么?我在拦截器里做这个吗?还是在豆子本身?我的目标是基本上能够调用一个方法loginUserWithEJBOnJboss(String user,String pass),该方法使用在jboss中配置的登录方法并正确设置主体。 我在这里不知所措,谷歌什么也没找到。也许我只是在寻找错误的单词。