我习惯于使用 WildFly 进行 Java/Jakarta EE 开发,最近我想将一个使用 JAAS 进行身份验证/授权的项目更新为 Jakarta EE 9.1 中的新 Jakarta Security API。
我无法让它工作,所以我决定创建尽可能简单的示例并在不同的应用程序服务器上进行实验。我从Soteria中获取了一个示例(据我所知,Jakarta Security 的参考实现),并创建了一个新的 Jakarta EE 项目来部署在我的应用程序服务器上。该代码可在此处获取。
reza
该示例包含一个非常简单的带有密码的用户身份存储secret1
:
@ApplicationScoped
public class TestIdentityStore implements IdentityStore {
public CredentialValidationResult validate(UsernamePasswordCredential usernamePasswordCredential) {
if (usernamePasswordCredential.compareTo("reza", "secret1")) {
return new CredentialValidationResult("reza", new HashSet<>(asList("foo", "bar")));
}
return INVALID_RESULT;
}
}
Run Code Online (Sandbox Code Playgroud)
Servlet 包含自定义表单身份验证机制定义,/login.jsf
如果用户未通过身份验证,该机制会将用户重定向到该定义。经过身份验证后,它会显示用户名(主体名称)并测试用户角色。还有一个注销功能:
@CustomFormAuthenticationMechanismDefinition(
loginToContinue = @LoginToContinue(
loginPage="/login.jsf",
errorPage="" // DRAFT API - must be set to empty for now
)
)
@WebServlet("/servlet") …
Run Code Online (Sandbox Code Playgroud) 我正在用Hibernate开发一个简单的例子,在任何容器之外使用它.我正在使用Maven,因此配置了JBoss存储库(请参阅https://community.jboss.org/wiki/MavenGettingStarted-Users)并将以下依赖项添加到我的项目的POM中:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.0.CR1</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.170</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
然后我继续配置Hibernate来使用像这样的H2数据库(文件hibernate.cfg.xml):
<?xml version='1.0' encoding='utf-8'?>
<hibernate-configuration xmlns="http://www.hibernate.org/xsd/hibernate-configuration">
<session-factory>
<property name="hibernate.connection.driver_class">org.h2.Driver</property>
<property name="hibernate.connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.connection.pool_size">1</property>
<property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>
Run Code Online (Sandbox Code Playgroud)
最后,我为一个简单的联系人类创建了一个POJO,如下所示:
@Entity
public class Contact {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Basic
private String name;
@Basic
private String email;
/* Getters and setters omitted for brevity. */
}
Run Code Online (Sandbox Code Playgroud)
最后,我创建了一个获取会话工厂,会话并最终持久化实体的类.代码如下:
ServiceRegistry registry = new ServiceRegistryBuilder().configure().buildServiceRegistry();
MetadataSources sources = new …
Run Code Online (Sandbox Code Playgroud) 我在Java EE 6应用程序服务器(GlassFish v3)中使用带有Facelets的JSF 2.0.我在web.xml中为异常配置了一个错误页面:
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error-all.xhtml</location>
</error-page>
Run Code Online (Sandbox Code Playgroud)
这是/error-all.xhtml
测试页面:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
template="/resources/templates/decorator.xhtml">
<ui:define name="title">Title</ui:define>
<ui:define name="body">
<h1>Body</h1>
</ui:define>
</ui:composition>
Run Code Online (Sandbox Code Playgroud)
我实现了一个托管bean,当我点击我的一个commandLinks时,它会故意抛出RuntimeException.当发生这种情况时,会显示/error-all.xhtml页面的内容,但它不会通过Facelets获取进程,因此不会应用template ="/ resources/templates/decorator.xhtml".
使用谷歌浏览器,我只看到"标题"和"正文",结果没有布局.如果我要求Chrome检查这些元素,我会得到完整的源代码,其中包括ui:composition和ui:define标记,Chrome显然无法理解.这证实了我的理论,即Facelets页面没有被处理.
所以,我的问题是,如何解决这个问题?如何处理错误页面并返回HTML代码,该代码是模板与错误页面内容组合的结果?