我花了一些时间来评估可用于在 Java EE 应用程序中对用户进行身份验证的选项。
因此,请建议以下列出的选项是否有效以及有关优缺点的陈述。可能是我缺少可能使身份验证方法可行的细节。或者可能是我错过了另一个选项(我们再次严格地谈论java EE所以没有查询身份验证除非可以在符合EE标准的方式)
1。 DIGEST / BASIC认证
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/protected/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>DIGEST/BASIC</auth-method>
<realm-name>as-defined-secuity-realm</realm-name>
</login-config>
优点
这是一种REST友好的身份验证方式。您可以通过AJAX调用发送授权凭据。一旦用户通过身份验证,浏览器将伴随具有正确Authorization: Basic/Digest QWxhZGRpbjpvcGVuIHNlc2FtZQ==
标头的任何请求。如果凭据不良,将向用户显示丑陋的浏览器登录屏幕 - 如果您可以使用它,那么BASIC / DIGEST auth就是您的选择。
在Digest的情况下,传递给服务器的字符串是MD5加密字符串,它比Basic更安全(这是&#39; user:password&#39;字符串的Base64编码)但是,decipherable。因此,在安全性方面,BASIC与FORM身份验证一样安全,而DIGEST是最安全的。总之,如果您的网站完全是HTTPS(我的意思是完全,因为如果某些资源是通过HTTP获取的,例如您的授权标题将对第三方可见)您可以安全地使用BASIC / DIGEST 。
缺点
2。基于表单的身份验证
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/protected/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>as-defined-security-realm</realm-name>
<form-login-config>
<form-login-page>/auth/login.html</form-login-page>
<form-error-page>/auth/error.html</form-error-page>
</form-login-config>
</login-config>
简而言之,如果用户访问protected/*
网址,则响应中的登录页面包含。因此,用户期望他将获得在form-login-page
标记中配置的登录页面而不是内容。如果密码正常,他将被转发(302 Paged Moved Permanently)到最初请求的protected/*
网址。如果密码为NOK,则会将用户转发(永久移动分页)到错误页面。
优点
缺点
第3。程序化身份验证
设置用于身份验证的URL。在该URL后面,您可以拥有一个servlet,它实例化一个登录模块(JAAS方式)并调用HttpServletRequest.login(user,pass)方法以及凭据。如果登录失败,它应该生成401/403响应。
您可以通过在web.xml中指定安全性约束来实现它:
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/protected/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
在服务器端,您只需设置一个RESTFul服务,该服务对呼叫者进行身份验证。以下是一些示例代码:
@Path("/auth")
@ApplicationPath("/rest")
public class AuthenticationRestFacade {
@POST
@Path("/login")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public User login(User loginInfo, @Context HttpServletRequest request) throws LoginException, ServletException {
// nasty work-around for Catalina AuthenticatorBase to be able to
// change/create the session cookie
request.getSession();
request.login(loginInfo.getName(), loginInfo.getPassword());
优点
缺点
总而言之,最好的可行选择:
真的很期待你们提出一些可行的替代解决方案。因为现在我讨厌采用PROGRAMMATIC方法
答案 0 :(得分:3)
根据我的经验,很难使用Java EE身份验证和授权服务来实现一个系统,该服务同时适用于REST服务和服务器端MVC(如JSP或JSF)。我的所有经验都倾向于为MVC部分使用基于表单的身份验证,以及为REST服务使用某种令牌身份验证(OAuth,Kerberos,LTPA)。使用REST服务的表单或基本身份验证通常很难实现,尽管我们这样做了,它在两个项目上运行良好。
它还取决于首选的服务器实现。
答案 1 :(得分:0)
可能有争议的是这些是否是RESTful,但至少可以解决以下问题:
Keberos 怎么样? 使用Windows AD等身份验证服务器
公钥证书怎么样?依靠客户提供的证书来识别用户......
令牌怎么样?第三方令牌发行商,例如OpenID ......