SEAM IN ACTION 第11章

Part 4 Sinking the

business requirements

Sinking 业务需求

Seam goes well beyond being simply a web application framework. It gives

you support to cover all the business requirements, which you’ll learn to appreciate

in this part of the book.

SEAM所做的不只是简化WEB应用框架。它的支持可满足所有的业务需要,在这个部分你就可以了解到。

Chapter 11 shows how quickly you can weave security into a Seam application.

A single method on a POJO gives you both authentication and role-based

authorization. You use annotations and the EL to define restrictions. Going

deeper, you’ll get a crash course in the Drools rule engine and use it to create

fine-grained, contextual restrictions. Finally, you’ll learn to keep out pesky spammers

and bots using CAPTCHA, a nearly zero-effort integration.

11章讲述如何快速地向SEAM应用中织入安全性。一个POJO上的单独的方法可让你认证或基于角色的认证。你使用annotations和EL来定义restrictions。再进一步,你会在Drools rule引擎得到一个crash球场,使用它建立一个细粒度的上下文相关的restrictions.最后,你将学到如何使用CAPTCHA(一个轻松的集成)避开麻烦的spammers及bots。

Though critical, security can often be a dry topic. But everyone loves Ajax!

Chapter 12 highlights the two flavors of Ajax in a Seam application. First you’ll

study Ajax-enabled UI components, which honor the JSF life cycle and let you

avoid the JavaScript and CSS nightmares that typically come with adopting Ajax.

If you prefer the low-level control, the JavaScript Remoting library lets you interact

directly with server-side components from JavaScript, stepping outside of the

JSF life cycle. The latter approach opens the door to alternative front ends such

as GWT.

虽然饱受批评,安全经常是个枯燥的话题。但所有人都爱Ajax!第12章强调了SEAM应用中Ajax的两个偏爱。第一,你将学习引用了Ajax的UI部件,其遵循JSF生命周期,而让你避开JavaScript and CSS带来的Ajax恶梦。如果你更想低水平的控制,JavaScript Remoting让你直接与服务器端部件交互,超出了JSF生命周期。后面的方法为前端替代品如GWT打开了大门。

If this book is a full-course meal, then chapter 13 is definitely dessert. This is

the chapter where you’ll learn to make your application pop. It begins by showing

how to accept file uploads using a JSF input binding. You’ll then discover the

versatility of Facelets templates to create and serve PDF documents, compose

and send email messages with attachments, and produce RSS. Finally, you’ll

learn to use themes and i18n to customize the application.

如果本书是套餐,那么第13章就是甜点。本章能让你的应用流行开来。它以使用JSF录入绑定来接受文件上传开始。随后你会发现各式的Facelets模板来建立和处理PDF文档,编辑并发送带有附件的email信息,产生RSS。最后,你会学到使用主题和i18n来自定义应用。

That’s where the book ends and the online chapters pick up. Chapter 14 eases you

into Seam’s business process integration and shows that a business process is simply a

multiuser conversation, controlled using the same declarative approach as a singleuser

conversation. Chapter 15 reveals how Seam taps into the Spring container. The

Spring integration is vital because it allows Spring to leverage Seam’s proper management

of the persistence context.

在这个地方,本书结束,在线章节开始。第14章让你轻松进入SEAM业务过程集成并显示业务过程只是简单的多用户会话,控制使用相同的声明式方法为单个会话。第15章揭示SEAM如何加入到Spring容器。Spring集成很重要,因为它允许Spring使用SEAM恰当地管理存储上下文。

The underlying theme of this final part is that Seam’s programming model

remains consistent, regardless of which integration you use, making the technologies

accessible.

这最后部分的底层主题是SEAM的程序模型的一致性,不管你用了哪个集成,要保证技术的的可用。

11、Securing Seam applications

This chapter covers

■ Developing an authentication routine

■ Enforcing role-based authorization

■ Writing permission rules with Drools

■ Adding a CAPTCHA challenge to a form

SEAM应用的安全性

本章包括:

开发一个认证路线

使用基于角色的认证

用Drools写许可规则

向表单增加CAPTCHA挑战

[@more@]

11、Securing Seam applications

This chapter covers

■ Developing an authentication routine

■ Enforcing role-based authorization

■ Writing permission rules with Drools

■ Adding a CAPTCHA challenge to a form

SEAM应用的安全性

本章包括:

开发一个认证路线

使用基于角色的认证

用Drools写许可规则

向表单增加CAPTCHA挑战

While winding down after a round of golf, I came across a magazine ad for Microsoft

Visual Studio 2005 that serves as an example of how not to treat security. The ad

shows side-by-side shots of a software development scene in which two developers

are discussing a web application, one before the product is introduced and one

after. The developer paraphernalia and the to-do list on the whiteboard reflect the

state of the project, with the before scene being far more cluttered and laden with

stress. But the contrast reveals a critical oversight in the after scene. An outstanding

item on the to-do list reads “TEST CODE FOR SECURITY!!” The items crossed off are

personalization features, consistency review of UI, accessibility, and breadcrumbs.

At least the application will look pretty while it’s being hacked.

在一个高尔夫回合的尾声,我看见一个Microsoft Visual Studio 2005杂志广告,示范如何可以不用关心安全。旁边是两个开发人员在讨论WEB应用。

Just because this chapter is in the final part of this book doesn’t mean you should

wait until the last minute to implement or test for security. A common misconception

is that security can be tacked onto the application when it’s ready to be sent off to QA,

or worse, production, as if it’s just polish. A complex application can’t be made secure

after the fact. Security must be present from the beginning and weaved into every

layer of the application, from the view down to the database. That’s why security is

such an integral part of Seam.

不要因为这一章在本书的末尾就认为你可以直到最后一分钟再实现和测试安全。一个常见的误解是安全可以在产品要发布时再加进去。安全必须在一开始时就考虑,并织入应用的每一层,从view到数据库。这就是为什么安全是SEAM的一个集成部分。

Seam helps you secure your application without spending a lot of time on the

details. In this chapter, you’ll learn how to implement an authentication routine and

how to protect areas of the application from unauthorized access across all layers. The

foundation of Seam’s security model is a role-based system that ensures a quick start.

Obviously, some applications require a more granular approach. To meet these needs,

Seam builds on this foundation by leveraging the Drools rule engine to support contextual,

rule-based permissions. The possibilities opened up by a rules system are limitless.

Seam 2.1 introduces an identity and permissions management module to make

administering security even easier. The best part of Seam’s security model is that you

don’t have to stomach a single line of XML, a breath of fresh air for those who have

used other Java security frameworks.

SEAM帮助你解决安全问题而不用你在细节上花太多时间。在这一章,你会学到如何实现一个认证路线,怎么保护应用的区域以防止各层的非认证的访问。SEAM的安全模型的基础是基于角色的系统。明显地,一些应用需要更细粒度的方法。为了满足这一需要,SEAM在此基础上使用Drools rule规则引擎来支持上下文的,基于角色的许可。规则系统带来的可能性是无限的。Seam 2.1引入了一个许可管理模块来安全的管理更轻松。SEAM的安全模块的最好的地方是不用加一行XML,这对那些已使用了其它JAVA安全框架的人来说是一丝新鲜空气。

Seeing is believing, so I want to start by showing you the quickest way to secure your

application after first defining some basic security terminology and how a user’s identity

is represented. As the chapter progresses, the security becomes more sophisticated.

眼见为实,在首先定义一些基本安全术语及用户的一致必怎样被体现后,让我们看看一种最快的方式来保卫你的应用。

11.1 Authentication jump-start

Why do you think security often gets the back seat in the design and development process?

My reasoning is that security frameworks, such as the Java Authentication and

Authorization Service (JAAS) and Spring Security (formally Acegi), are just too hard

to implement. The first is too cryptic and, let’s face it, primitive, and the second buries

you deep in XML Hell.

开始了解认证

为什么你经常认为安全应处于次要位置?我的理由是安全框架,如Java Authentication and Authorization Service (JAAS)及Spring Security (formally Acegi)太难实现。第一个太神秘,说实在的是太原始;第二个由将你埋入XML深渊。

The goal of a security layer is to prevent hackers, nonprivileged users, and rogue

client endpoints from accessing sensitive areas of the applicaion, and not scare off

developers from implementing it. Given its importance, security should be easy to

configure and use, and it should be integrated into the core of the application framework

rather than split off as an extension. Both are true in Seam. What’s more important

is that this ease of use is accomplished without compromising the ability of

Seam’s security model to scale in accordance with security requirements. I start by presenting

authentication, the foundation of security, and show you how to tie it into a

Seam application in three simple steps.

安全层的目标是防止黑客,未授权用户及坏客户去访问应用的敏感数据区域,又不会困难得吓跑开发者。不单重要,还要容易配置和使用,并且要集成到应用框架的核心而不是分离成扩展的结构。这两个对于SEAM来说都是真的。更重要的是这种使用并不需要组织SEAM安全模型以适应安全需求。我以认证开始,安全的基础,展示如果用三步绑定到一个SEAM应用。

11.1.1 Giving the user an identity

Authentication is just a fancy way of saying “login.” The login routine, which you are

about to implement, prefaces nearly every action we perform in today’s online world.

But it’s not just about making you ransack the piles of papers on your desk to find the

scribbled characters that get you past the login challenge. Authentication is about

giving an anonymous user a face, as depicted in figure 11.1.

给用户一个标识

认证只是“登录”的一个漂亮说法。你即将实现的登录路线,几乎是当今在线世界的每个action都不可少的开端。认证只是给匿名用户一张脸,如图11.1

clip_image001.png

SHOW ME YOUR FACE

The transformation in figure 11.1 symbolizes the user establishing an identity.

During authentication, Seam assembles an instance of Subject from the JAAS API and associates it with the user’s session,

allowing the server to recognize the user until the session expires or the user explicitly logs out.

让我看一下你的脸

图中的变形表示建立了用户的标识。在认证过程中,SEAM从JAAS API组装了Subject实例,并将其关联到用户session,让服务器认识用户直到session过期或用户明确地登出。

The Subject instance is a digital representation of the user. It consists of a collection

of principals, filling in the user’s facial features. A principal implements the

Principal interface from the JAAS API. There can be an unbounded set of principals,

but Seam limits it to just two. The first principal holds the username of the authenticated

user and is called the user principal. The second principal, known as the roles

group, implements the Group interface and holds a collection of roles. Each role is a

Principal as well, though distinct from the user principal and roles group and appropriately

referred to as a role principal.

Subject实例是用户的数字表示。它组成了规则的集合,填入用户的外表特性。一个规则实现了JAAS API的Principal接口。可以有无数类型的规则集合,但SEAM将其限制为两个。第一个规则保持授权用户的用户名,被叫做用户规则。第二个规则,叫做角色组,实现组接口,保存角色的集合。每个角色也是一个Principal,即然从用户规则中区分出,角色组被称作角色特性。

But the details about the structure of the Subject don’t really matter because Seam

provides a simple abstraction layer that you use to establish a user’s principals during

authentication and to access those principals when performing authorization checks.

但Subject结构的细节是无关紧要的,因为SEAM提供了一个简单的抽象层,在认证时你可以用来建立用户的规则,当做认证检查时,可访问这些规则。

JAAS A LA CARTE

Seam uses JAAS, but only select parts of it. Don’t panic when you see that four-letter

word because, by and large, Seam’s JAAS integration is completely transparent to you.

Behind the scenes, Seam relies on JAAS to handle the authentication handoff, which

delegates to one of your components to give the approval, and also uses the identity

portion of the API as mentioned above. The only time you even come in contact with

JAAS is to assert a user’s role using Servlet security (e.g., isUserInRole()). Seam

ignores the permission and policy piece of JAAS, instead offering its own multifaceted

authorization strategy. We cover authorization after we finish with authentication.

Let’s take it one A at a time.

JAAS A LA CARTE

SEAM使用JAAS,但只使用其中一部分。在看到四个字符时,不要怕,因为SEAM的JAAS集成对你是完全透明的。在后台,SEAM依靠JAAS来处理认证,这表示你的部件之一会投用,或也会用到上面提到的API的标识部分。你唯一你会接触JAAS的时候是声称用户的角色是使用Servlet security(如isUserInRole())SEAM忽略许可 和JAAS的策略部分,而是提供了自己的授权策略。我们会在认证后讲解。让我们一次看一个。

LOCATING THE USER ACCOUNTS

To implement authentication, you need to decide where the user accounts for your

application are stored. Seam leaves this task entirely up to you. If you do want Seam to

help out, you have the option in Seam 2.1 of letting the identity manager consult your

database or LDAP to find an account, though it requires that you follow a standard, yet

flexible, model.

定位用户的账户

要实现认证,你需要知道应用的用户帐户保存在哪里。SEAM完全让你决定这些。如果你真的要SEAM来帮你,Seam 2.1中你就有了选择让标识管理器咨询你的数据库,或LDAP,以找到账户,需要你遵循标准,但依然有弹性的模型。

In Open 18, the accounts are mapped to a table in the database through the Member

entity and retrieved using the EntityManager. The Member entity, introduced in

chapter 4, has fields to store the member’s username and hashed password, but

doesn’t have a field to hold the member’s roles. Though not mandatory, you may want

to assign roles to the user during authentication, which are pulled from the database.

First, you need a Role entity:

在Open 18中, 账户通过Member实体,用EntityManager映射到数据库的一个表。在第4章引用的Member实体,有字段可以保存成员的用户名和密码,不是没有字段可以保存成员的角色。虽然不是强制的,你应在认证时指定一个角色到用户,其被从数据库中取出。首先,你需要一个Role实体:

clip_image002.png

Next, you add a Role collection to the Member entity, related through a join table:

然后,你增加一个Role集合到Member实体,通过一个join表关联:

private Set roles = new HashSet();

@ManyToMany(fetch = FetchType.LAZY)

@JoinTable(name = "MEMBER_ROLE",

joinColumns = @JoinColumn(name = "member_id"),

inverseJoinColumns = @JoinColumn(name = "role_id"))

public Set getRoles() { return this.roles; }

public void setRoles(Set roles) { this.roles = roles; }

While roles are optional for authentication, they are essential when it comes to implementing

authorization. In a sense, authentication is the binary part of security: The

user is either authenticated or the user is not authenticated. Only after establishing

the user’s identity can we begin talking about authorization. Let’s find out, in three

steps, how a 0 becomes a 1.

当角色是认证的可选,对于实现认证,他们很重要。可以这样认为:认证是安全的分界线,要么是认证了的,要么是没认证的。只在了解了认证后,我们才能谈授权。通过三步,0变成了1

11.1.2 Implementing authentication in three steps

The three steps for setting up authentication in Seam are as follow:

1 Switch on authentication by configuring an authentication method.

2 Verify the user’s credentials in the authentication method.

3 Create a JSF login form.

三步实现授权

SEAM中三步设置认证如下:

通过配置认证方法来切换认证

在认证方法中校验用户的评证

建立JSF登录表单

When these steps are complete, your application will support form-based authentication.

Later on, you’ll learn that in Seam 2.1, you can let Seam’s identity manager handle

the second step for you. If you would rather not bother with the login form, you

can plug in Seam’s support for HTTP authentication, in which case the credentials are

negotiated by the browser. Let’s put these alternatives aside for now and continue with

the steps laid out here.

这些步骤完成后,你的应用即支持基于表单认证。后面,你将学到在Seam 2.1中,你可以让SEAM身份管理器为你处理第二步。如果你不想使用登录表单,可以插入SEAM对HTTP认证的支持,在这种情况下,身分由浏览器处理。让我们先将这些选择放一放,继续看看那些步骤:

STEP 0: ZERO PREREQUISITES

The first step isn’t a step at all but simply a fact. You don’t need any extra libraries to

implement authentication and role-based security in Seam. Only when you branch

out to Seam’s rule-based security, covered in section 11.4, are additional dependencies

needed.

0:无前题

第一步不是步,但是一个简单的事实。在SEAM中,你无须任何额外的库来实现认证和基于角色的安全。只有当你走出SEAM基于角色的安全,才会需要附加的依赖。在11.4中讲述。

In fact, projects created using the seam-gen tool already have the authentication

routine configured. It just leaves out one critical detail. The default configuration

accepts any username and password. To heighten security (to put it lightly) and keep

out the imposters, the user’s login credentials need to be validated against the database

of registered members.

事实上,用seam-gen建立的项目已经有了配置好的认证路线。它只是没有具体认证细节。默认的配置接受任何用户名和密码。为了让安全更强、更聪明、远离骗子。用户的登录凭据需要匹配数据库中已注册用户信息。

STEP 1: SWITCHING ON AUTHENTICATION

Enabling security in Seam is a bit of a misnomer. Security is enabled by default, unless

you purposely disable it (perhaps in a test). However, out of the box, there’s no way

for users to authenticate themselves. To make that possible, you first need to tell Seam

which method handles the authentication logic (i.e., the authentication delegate).

This method is provided by one of your components. Three requirements must be

met by the authentication method:

1:认证中的开关

SEAM中启用安全本身有些误解。安全是默认启用的,除非你有意禁用了它(可能测试时会这样)。不管怎样,刚拿过来时,用户是无法认证他们自己的。要能这样,你必须先告诉SEAM是哪个方法处理认证逻辑(如认证代表)。这个方法由我的一个部件提供。认证方法有三个前提条件:

■ It must take no arguments.

■ It must return a boolean indicating whether the credentials could be verified.

■ It must be accessible via the EL (which isn’t much of a problem in Seam).

没有参数

返回布尔值,指示是否通过

必须可以通过EL访问(这对SEAM来说毫无问题)

The authentication method can have any name, it can reside on any class, and that

class doesn’t have to implement any special security interfaces. Seam plugs your

authentication method into JAAS, but hides the complexity of JAAS in the SeamLogin-

Module. Internally, JAAS invokes your authentication method and adds the appropriate

principals to the security subject if the method returns true. This authentication

routine is activated through Seam’s identity component, freeing you from having to

interact with the colossus that lies beneath.

认证方法可以用任何名,可存在于任何类,这个类也不用实现任何特殊的安全接口。SEAM插入你的认证方法到JAAS,但隐藏JAAS的复杂性于

SeamLoginModule。内部,如果返回为true,JAAS调用你的认证方法并增加适当的规则到安全主题,认证路线被SEAM身份部件激,使你不必与底层的细节打交道。

The built-in Identity component, named identity, maintains a reference to the

authentication method as a method-binding expression. The identity component

lives in the component namespace http://jboss.com/products/seam/security,

declared in the component descriptor using the prefix identity. The authentication

method can be assigned to the identity component using component configuration:

名为identity的内建的身份部件用一个方法绑定表达式维护一个到认证方法的参考。identity部件存在于名字空间http://jboss.com/products/seam/security,在部件描述文件中声明,使用identity前缀。使用部件配置,认证方法可以被指定到identity部件:

authenticate-method="#{authenticationManager.authenticate}"/>

Here, the authentication method is provided by the authenticationManager component.

The next step is to implement this method.

这里,认证方法由authenticationManager部件提供。下一步则实现这一方法。

STEP 2: AUTHORING AN AUTHENTICATION METHOD

As I mentioned earlier, the authentication method can reside on any class. We use a

JavaBean component in this example. Here’s a naïve, but valid, implementation of the

method:

2:写认证方法

前面提过,认证方法不附着在任何类上。本例中我们用JavaBean部件。这是个简单但有效的方法实现:

@Name("authenticationManager")

public class AuthenticationManager {

public boolean authenticate() {

return true;

}

}

To get serious, we need credentials to validate. If the authenticate() method doesn’t

take any arguments, where do the credentials come from? One of the roles of the

identity component, which is scoped to the session context and instantiated when

the user’s session begins, is to capture the credentials being challenged. The credentials

are stored in the username and password properties on this component, and are

typically populated by a JSF form. Thus, you get to the credentials by obtaining a reference

to the identity component.

更认真的话,我们需要验证凭据。如果authenticate()没有带任何参数,凭据从哪儿来?这是identity部件的一个作用,其范围定为session上下文,当用户session开始时,其初始化以得到凭据。凭据保存在这个部件的username 和password属性,典型地,由JSF表单产生。因此你通过获得identity部件来得到凭据的参考。

NOTE

If your authentication routine requires additional credentials, you can

extend Seam’s security infrastructure to capture them. In Seam 2.0, you

extend the Identity class and register it using the component name

org.jboss.seam.security.identity. In Seam 2.1, you extend the Credentials

class and register it using the component name org.jboss.

seam.security.credentials. The credentials component was introduced

in Seam 2.1 to hold the credentials. Although the credentials can

still be accessed using the identity component, the credentials component

is the preferred means of access.

如果你的认证路线需要额外的凭证,你可以扩展SEAM基础安全架构来获得它们。在Seam 2.0扩展Identity类并使用部件名org.jboss.seam.security.identity对其注册。在Seam 2.1,你扩展Credentials类,用部件名org.jboss.seam.security.credentials来注册。credentials部件在Seam 2.1被引入来存储凭证。虽然凭证仍然可以通过identity部件访问,但通过凭证部件访问会更好。

To pull the credentials into the authentication method, you simply inject identity

(or credentials in Seam 2.1) into the authentication component using @In:

向认证方法中加入凭证,你可以简单地注入identity(或Seam 2.1的credentials)到认证部件。

@Name("authenticationManager")

public class AuthenticationManager {

@Logger private Log log;

@In private Identity identity;

public boolean authenticate() {

log.info("username: #0, password: #1",

identity.getUsername(), identity.getPassword());

identity.addRole("member");

return true;

}

}

As you see here, the role of the identity component in the authentication method is

twofold. It delivers the login credentials and it’s used to store a set of roles. In this

implementation, we assign all users the member role. JAAS transfers the roles to the

security subject during the post login routine. Let’s consider how that works.

如你所见,认证方法中identity部件的作用是双重的。它发出了登录凭据,并且那用于保存一套角色。在这个实现中,我们指定所有用户的成员角色。在登录路线的后末尾,JAAS转换角色到安全主体。让我们考虑一下是如何工作的。

When the authentication method is called, the user principal and roles group

haven’t yet been established on the Subject instance (because the user hasn’t been

authenticated). That initialization takes place inside the JAAS login module after the

authentication method returns true. In the interim, the identity component provides

temporary storage for roles—appended using the addRoles() method—that

need to be transferred to the user’s group identity. During the post-authentication

routine, Seam converts the role names into role principals and adds them to the roles

group on the Subject instance.

当认证方法被调用,用户规则和角色组还没有在Subject实例上建立(因为用户还没有被认证)。在认证方法返回true后,初始化在JAAS登录模块内部发生。在这期间,identity部件为角色提供临时的存储,这由addRoles()方法加入,需要被转化为用户组身份。在认证路线后期,SAM转换用户名到角色规则,并将其加入Subject实例的角色组。

NOTE

Seam doesn’t impose a naming convention for roles, so feel free to use

your own scheme.

SEAM不对角色强加命名转换,所以可以自在地使用自己的scheme.

The authentication routine produces a standard Java security principal, meaning Servlet

security just works. You can use the HttpServletRequest#isUserInRole() method

to check if a user has been granted a role, and it enables transparent integration with

libraries that depend on this method. To get all of this, you only have to write a couple

lines of code (even counting the XML). That number grows when you add the authentication

logic.

认证路线产生一个标准和JAVA安全规则,这意味着Servlet安全可用。你可以使用HttpServletRequest#isUserInRole()方法来检查是否用户被授与了一个角色,它与依赖于这个方法的库有透明的集成。要得到这些,你只要写几行代码(甚至可以依赖XML)

The authentication logic for Open 18 is presented in listing 11.1. The username

on the identity component is used to look up a matching Member entity in the database

using the EntityManager. If an instance is found, the password is validated by

comparing its hash to the hashed password from the database. If both checks succeed,

the roles are added and the method returns true, returning control to JAAS to establish

the security principals. If either check fails, a return value of false sends the user

back to the login page with a failure message. We examine the details of the failure

scenario a bit later.

Open 18的认证逻辑列于表11.1,identity部件的用户名用于EntityManager查找数据库中匹配的Member实体。如果找到,密码也对,角色会被增加并用方法返回true,控制返回JAAS以建立安全规则。如果任何一下检查失败,返回值false将用户送到登录页面并给出失败信息。稍后我们再看失败场景的细节。

clip_image003.png

clip_image004.png

If the member is a golfer, currentGolfer is outjected for convenience. To ensure it

hangs around for the duration of the session, we define a role for it on the Golfer

class:

如果成员是球员,可以方便地注出currentGolfer。为了确保在session中有效,我们在Golfer类中定义一个角色。

@Role(name = "currentGolfer", scope = ScopeType.SESSION)

All that’s left is to create a form for the user to enter credentials and attempt a login.

剩下的是建立一个表单,让用户录入凭证信息。

STEP 3: CREATING THE LOGIN FORM

You’ll be thrilled to discover that the j_username and j_password request parameters

and the /j_security_check servlet path, defined in the Servlet specification for implementing

form-based logins, have finally been retired under Seam. And for those of

you who have had to invent a custom handoff to get a JAAS login module to play nicely

with JSF, you’ll be happy to know that you can use a native JSF form on the login page.

The login form boils down to two value-binding expressions, #{identity.username}

and #{identity.password}, which capture the user’s login cred

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21802202/viewspace-1027642/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/21802202/viewspace-1027642/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值