[如果只想查看代码,请向下滚动]

动机

在RHQ中,我们需要一个安全域,该域可用于通过容器管理的安全性来保护REST-api及其Web应用程序。 过去,我只是使用经典的DatabaseServerLoginModuleDatabaseServerLoginModule进行身份验证。 现在RHQ还允许将用户包含在LDAP目录中,而上述模块未涵盖这些目录。 我有两个选择开始:

  • 将LDAP登录模块复制到REST的安全域中
  • 将安全域用于已经用于UI和CLI的REST-api

后一种选择当然有利于防止代码重复,所以我走了那条路。 并失败了。

我失败了,因为RHQ在启动时删除并重新创建了安全域,并且服务器检测到该错误并抱怨从rhq-rest.war引用的安全域突然消失了。

因此,下一个尝试:不要在启动时重新创建域,而仅添加/删除ldap-login模块(我说的是模块,因为实际上我们需要两个)。

这也没有按预期工作:

  • 基础AS有时会进入需要重新加载的模式,并且未应用更改
  • 除去ldap模块后,它们中的主体仍被缓存
  • 刷新缓存不起作用,服务器进入需要重新加载的模式

因此,我现在要做的是为rest-security-domain实现一个登录模块,该模块仅委派给另一个进行身份验证,然后在成功时添加角色。

这样,rhq-rest.war便具有对该rest-security-domain的固定引用,而另一个安全域则可以像以前一样处理。

实作

让我们从standalone.xml文件中的代码段开始,该代码段描述安全域并参数化模块

<security-domain name="RHQRESTSecurityDomain" cache-type="default"><authentication><login-module code="org.rhq.enterprise.server.core.jaas.DelegatingLoginModule" flag="sufficient"><module-option name="delegateTo" value="RHQUserSecurityDomain"/><module-option name="roles" value="rest-user"/></login-module></authentication></security-domain>

因此,此定义设置了一个安全域RHQRESTSecurityDomain ,该域使用我将在稍后描述的DelegatingLoginModule。 传递了两个参数:

  • proxyTo:要验证用户身份的另一个域的名称
  • 角色:以逗号分隔的要添加到主体的模块列表(以及web.xml的security-constraint部分中需要的模块)

对于代码,我没有显示完整清单。 你可以在git中找到它 。

为了使我们的生活更轻松,我们并没有自己实现所有功能,而是扩展了现有的UsernamePasswordLoginModule并仅覆盖某些方法。

public class DelegatingLoginModule extends UsernamePasswordLoginModule {

首先,我们使用传递的选项初始化模块,并使用我们委派给的域创建一个新的LoginContext:

@Overridepublic void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,Map<String, ?> options) {super.initialize(subject, callbackHandler, sharedState, options);/* This is the login context (=security domain) we want to delegate to */String delegateTo = (String) options.get("delegateTo");/* Now create the context for later use */try {loginContext = new LoginContext(delegateTo, new DelegateCallbackHandler());} catch (LoginException e) {log.warn("Initialize failed : " + e.getMessage());}

有趣的部分是login()方法,在该方法中我们获取用户名/密码并将其存储以供以后使用,然后我们尝试登录到委托域,如果成功,则告诉super我们成功了,以便它可以发挥作用。 。

@Overridepublic boolean login() throws LoginException {try {// Get the username / password the user entred and save if for later useusernamePassword = super.getUsernameAndPassword();// Try to log in via the delegateloginContext.login();// login was success, so we can continueidentity = createIdentity(usernamePassword[0]);useFirstPass=true;// This next flag is important. Without it the principal will not be// propagatedloginOk = true;

这里需要loginOk标志,以便超类将调用LoginModule.commit()并选择主体和角色。

不将其设置为true将导致成功login()但没有附加主体。

if (debugEnabled) {log.debug("Login ok for " + usernamePassword[0]);}return true;} catch (Exception e) {if (debugEnabled) {LOG.debug("Login failed for : " + usernamePassword[0] + ": " + e.getMessage());}loginOk = false;return false;}}

成功后,super将调用以下两种方法来获取主体及其角色:

@Overrideprotected Principal getIdentity() {return identity;}@Overrideprotected Group[] getRoleSets() throws LoginException {SimpleGroup roles = new SimpleGroup("Roles");for (String role : rolesList ) {roles.addMember( new SimplePrincipal(role));}Group[] roleSets = { roles };return roleSets;}

现在,最后一部分是回调处理程序,我们委托的其他域将使用该回调处理程序从我们那里获取凭据。 它是经典的JAAS登录回调处理程序。 首先让我感到困惑的一件事是,该处理程序在登录期间被调用了几次,我认为这是错误的。 但是实际上,它被调用的次数与RHQUserSecurityDomain中配置的登录模块的数量相对应。

private class DelegateCallbackHandler implements CallbackHandler {@Overridepublic void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {for (Callback cb : callbacks) {if (cb instanceof NameCallback) {NameCallback nc = (NameCallback) cb;nc.setName(usernamePassword[0]);}else if (cb instanceof PasswordCallback) {PasswordCallback pc = (PasswordCallback) cb;pc.setPassword(usernamePassword[1].toCharArray());}else {throw new UnsupportedCallbackException(cb,"Callback " + cb + " not supported");}}}}

同样,完整的代码在RHQ git仓库中可用。

调试(在EAP 6.1 alpha或更高版本中)

如果您编写了这样的登录模块,但该模块不起作用,则需要对其进行调试。 从通常的方法开始,以了解我的login()方法是否按预期工作,但登录失败。 我添加了打印语句等,以发现从未调用过getRoleSets()方法。 但是,一切看起来还不错。 我进行了一些谷歌搜索,发现了这个不错的Wiki页面 。 可以告诉Web应用进行审核日志记录

<jboss-web><context-root>rest</context-root><security-domain>RHQRESTSecurityDomain</security-domain><disable-audit>false</disable-audit>

仅此标志是不够的,因为您还需要设置适当的记录器,这在Wiki页上进行了说明。 启用此功能后,我看到了类似

16:33:33,918 TRACE [org.jboss.security.audit] (http-/0.0.0.0:7080-1) [Failure]Source=org.jboss.as.web.security.JBossWebRealm;
principal=null;request=[/rest:….

因此很明显,登录模块未设置主体。 然后查看超类中的代码,将我带到上面提到的loginOk标志。

现在,一切都正确设置了,自动日志看起来像

22:48:16,889 TRACE [org.jboss.security.audit] (http-/0.0.0.0:7080-1) [Success]Source=org.jboss.as.web.security.JBossWebRealm;Step=hasRole; principal=GenericPrincipal[rhqadmin(rest-user,)]; request=[/rest:cookies=null:headers=authorization=user-agent=curl/7.29.0,host=localhost:7080,accept=*/*,][parameters=][attributes=];

因此,在这里您看到主体rhqadmin已登录并获得了剩余用户分配的角色,这是web.xml中security-constraint元素中的一个匹配对象。

进一步查看

我已将以上内容作为环聊直播进行了介绍 。 不幸的是,当我在解释时打字时,G +会不时使我静音。

视频播放完后,我还有其他问题,最终让我重新思考启动阶段,以防用户安装了启用了LDAP的RHQ先前版本。 在这种情况下,安装程序仍将安装初始的仅基于DB的RHQUserSecurityDomain,然后在启动bean中,检查a)系统设置中是否启用了LDAP,以及b)登录模块是否实际存在。 如果a)匹配并且不存在,我们将安装它们。

此Bugzilla条目还包含有关整个故事的更多信息。

参考:从JCG合作伙伴 Heiko Rupp在“ 一些事情要记住”博客中创建一个委派的登录模块(用于JBoss EAP 6.1) 。

翻译自: https://www.javacodegeeks.com/2013/05/creating-a-delegating-login-module-for-jboss-eap-6-1.html

创建委托登录模块(用于JBoss EAP 6.1)相关推荐

  1. jboss eap 7.0_创建委托登录模块(用于JBoss EAP 6.1)

    jboss eap 7.0 [如果只想查看代码,请向下滚动] 动机 在RHQ中,我们需要一个安全域,该域可用于通过容器管理的安全性来保护REST-api及其Web应用程序. 过去,我只是使用经典的Da ...

  2. jboss eap_带有自定义模块的JBoss EAP上的骆驼

    jboss eap Apache Camel -最好的开源集成库 Apache Camel是一个很棒的开放源代码集成库,可以用作ESB的主干或在独立的应用程序中进行系统的路由,转换或中介(请参阅:集成 ...

  3. 带有自定义模块的JBoss EAP上的骆驼

    Apache Camel -最好的开源集成库 Apache Camel是一个很棒的开放源代码集成库,可以用作ESB的主干或在独立的应用程序中进行系统的路由,转换或中介(请参阅:集成多个系统). Cam ...

  4. jboss as7 下载_JBoss AS 7:定制登录模块

    jboss as7 下载 JBoss AS 7很整洁,但是文档仍然很缺乏(错误消息没有那么有用). 这篇文章总结了如何创建自己的兼容JavaEE的登录模块,以对部署在JBoss AS上的Web应用程序 ...

  5. JBoss AS 7:自定义登录模块

    JBoss AS 7很整洁,但是仍然缺少文档(错误消息没有那么有用). 这篇文章总结了如何创建自己的兼容JavaEE的登录模块,以对部署在JBoss AS上的Web应用程序的用户进行身份验证. 提供了 ...

  6. jboss eap mysql_JBOSS EAP 6 系列三 Oracle、Mysql数据源的配置(驱动)—认识模块的使用...

    本文介绍JBOSS EAP 6.2中Oracle数据源的配置方式.结合之前JBOSS EAP 6.2新功能,本文初识JBOSS模块申明式容器这一特性. 模块申明式容器:JBOSS EAP不再有lib的 ...

  7. 登录模块与token的使用和创建

    登录模块的使用与创建 一.如何实现登录注册 1.在Vue里创建文件Login.vue和user.vue 2.在router里配置路由 {path: '/user',name: 'User',compo ...

  8. jboss eap_HawtIO在JBoss EAP上(第二部分)

    jboss eap 我刚刚发布了一篇关于在JBoss Wildfly 8.1上运行HawtIO的条目 . 从那篇文章中,您将了解HawtIO的出色表现 ,以及它必须具备的所有 出色 插件,才能从单个仪 ...

  9. HawtIO在JBoss EAP上(第二部分)

    我刚刚发布了一篇关于在JBoss Wildfly 8.1上运行HawtIO的条目 . 从那篇文章中,您将了解HawtIO多么出色 ,以及它必须具备的所有 出色 插件,才能从单个仪表板管理基于JVM的技 ...

最新文章

  1. IIS6 MVC3 配置
  2. 001PHP文件处理——文件处理disk_total_space disk_free_space basename dirname file_exists filetype...
  3. everything文件搜索_本地文件搜索神器,Everything、Listary、AnyTXT Searcher!
  4. 使用Dockerfile定制镜像-定制Tomcat为例
  5. 计算机二级vfp模拟考试题,计算机等级考试二级VFP模拟练习题[10]
  6. Exploring the Amazon Echo Dot, Part 2: Into MediaTek utility hell
  7. PDF 补丁丁 (修改PDF书签;拆分、合并、制作PDF;提取图片) 0.3.0.8 正式版
  8. JS里面的懒加载(lazyload)
  9. [Leedcode][JAVA][第72题][动态规划]
  10. 李宏毅《机器学习》作业班+带打比赛
  11. PostgreSQL 聚合、分组、排序
  12. vue项目创建步骤 和 路由router知识点
  13. ZFS 学习(转载)
  14. scala代码示例_Scala元组和地图示例
  15. 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔 (转帖)
  16. 服务器 端口映射 dmz,如何使用端口映射功能与 DMZ 主机设置
  17. 只能上QQ不能上网的解决方法
  18. Python脚本中调用其他Python脚本
  19. 【100%通过率】华为OD机试真题 JS 实现【最接近最大输出功率的设备 /查找充电设备组合】【2023 Q1 | 200分】
  20. Python逆向进阶:Web逆向私单

热门文章

  1. how to install nc on centos8及nc应用
  2. 朝着理想坚实迈进_坚实原则:单一责任原则
  3. java如何避免注释重复_Java 8中的可重复注释
  4. apache ignite_使用Spring Data的Apache Ignite
  5. input发送a.jax_Java EE 7 / JAX-RS 2.0 – REST上的CORS
  6. Java十六进制浮点文字
  7. java 泛型示例_使用Java泛型的模板方法模式示例
  8. maven mockito_如何:测试Maven项目(JUnit,Mockito,Hamcrest,AssertJ)中的依赖项
  9. cp ft wat_Java数组,Wat!
  10. spring 2.2 改进_Spring 4中@ControllerAdvice的改进