实现 UserAuthenticationSecurityCheck 类
improve this page | report issue
概述
此抽象类扩展 CredentialsValidationSecurityCheck
,且基于其而构建以适合最常见的简单用户认证用例。 除了验证凭证,它还创建了可从框架的各个部分访问的用户身份,从而使您能够标识当前用户。 (可选)UserAuthenticationSecurityCheck
还提供记住我功能。
本教程使用的安全性检查示例会请求用户名和密码,并使用用户名来表示已认证的用户。
先决条件:确保阅读 CredentialsValidationSecurityCheck 教程。
跳转至:
创建安全性检查
创建 Java 适配器,并添加名为 UserLogin
且可扩展 UserAuthenticationSecurityCheck
的 Java 类。
public class UserLogin extends UserAuthenticationSecurityCheck {
@Override
protected AuthenticatedUser createUser() {
return null;
}
@Override
protected boolean validateCredentials(Map<String, Object> credentials) {
return false;
}
@Override
protected Map<String, Object> createChallenge() {
return null;
}
}
创建验证问题
验证问题与实现 CredentialsValidationSecurityCheck 中描述的内容完全相同。
@Override
protected Map<String, Object> createChallenge() {
Map challenge = new HashMap();
challenge.put("errorMsg",errorMsg);
challenge.put("remainingAttempts",getRemainingAttempts());
return challenge;
}
验证用户凭证
在客户机发送验证问题答案时,此答案会作为 Map
传递至 validateCredentials
。 使用此方法来实施您的逻辑。 如果凭证是有效的,那么该方法将返回 true
。
在此示例中,在 username
和 password
相同时,凭证被认为是“有效”的:
@Override
protected boolean validateCredentials(Map<String, Object> credentials) {
if(credentials!=null && credentials.containsKey("username") && credentials.containsKey("password")){
String username = credentials.get("username").toString();
String password = credentials.get("password").toString();
if(!username.isEmpty() && !password.isEmpty() && username.equals(password)) {
return true;
}
else {
errorMsg = "Wrong Credentials";
}
}
else{
errorMsg = "Credentials not set properly";
}
return false;
}
创建 AuthenticatedUser 对象
UserAuthenticationSecurityCheck
类在持久数据中存储当前客户机(用户、设备和应用程序)的表示,使您能够在代码的各个部分中检索当前用户,例如,验证问题处理程序或适配器。
通过类 AuthenticatedUser
的实例来表示用户。 其构造方法采用 id
、displayName
和 securityCheckName
参数。
此示例针对 id
和 displayName
参数使用 username
。
-
首先,修改
validateCredentials
方法以保存username
自变量:private String userId, displayName; @Override protected boolean validateCredentials(Map<String, Object> credentials) { if(credentials!=null && credentials.containsKey("username") && credentials.containsKey("password")){ String username = credentials.get("username").toString(); String password = credentials.get("password").toString(); if(!username.isEmpty() && !password.isEmpty() && username.equals(password)) { userId = username; displayName = username; return true; } else { errorMsg = "Wrong Credentials"; } } else{ errorMsg = "The credentials are not set properly."; } return false; }
-
然后,覆盖
createUser
方法以返回AuthenticatedUser
的新实例:@Override protected AuthenticatedUser createUser() { return new AuthenticatedUser(userId, displayName, this.getName()); }
您可以使用 this.getName()
来获取当前安全性检查名称。
在成功的 validateCredentials
之后,UserAuthenticationSecurityCheck
会调用 createUser()
实现。
在 AuthenticatedUser 中存储属性
AuthenticatedUser
具有一个替代构造方法:
AuthenticatedUser(String id, String displayName, String securityCheckName, Map<String, Object> attributes);
此构造方法添加要使用用户表示存储的定制属性的 Map
。 映射可用于存储其他信息,例如,个人档案图片、Web 站点等。此信息可供客户机端(验证问题处理程序)和资源(使用自省数据)访问。
注: 属性
Map
必须仅包含 Java 库中绑定的类型/类对象(例如,String
、int
和Map
等),而不能包含定制类。
添加 RememberMe 功能
缺省情况下,UserAuthenticationSecurityCheck
使用 successStateExpirationSec
属性来确定成功状态的持续时间。 此属性继承自 CredentialsValidationSecurityCheck
。
如果想要允许用户保持登录的时间超过 successStateExpirationSec
值,那么 UserAuthenticationSecurityCheck
可添加此功能。
UserAuthenticationSecurityCheck
会添加一个名为 rememberMeDurationSec
的属性,其缺省值为 0
:缺省情况下,将记住用户 0 秒,这意味着缺省情况下禁用此功能。 将该值更改为对您的应用程序有意义的数字(一天、一周、一个月……)。
您还可以通过覆盖 rememberCreatedUser()
方法来管理该功能,此方法缺省情况下返回 true
,表示缺省情况下激活此功能(前提是更改了持续时间属性)。
在此示例中,客户通过发送 boolean
值作为所提交凭证的一部分来决定启用/禁用 RememberMe 功能。
-
首先,修改
validateCredentials
方法以保存rememberMe
选择:private String userId, displayName; private boolean rememberMe = false; @Override protected boolean validateCredentials(Map<String, Object> credentials) { if(credentials!=null && credentials.containsKey("username") && credentials.containsKey("password")){ String username = credentials.get("username").toString(); String password = credentials.get("password").toString(); if(!username.isEmpty() && !password.isEmpty() && username.equals(password)) { userId = username; displayName = username; //Optional RememberMe if(credentials.containsKey("rememberMe") ){ rememberMe = Boolean.valueOf(credentials.get("rememberMe").toString()); } return true; } else { errorMsg = "Wrong Credentials"; } } else{ errorMsg = "Credentials not set properly"; } return false; }
-
然后,覆盖
rememberCreatedUser()
方法:@Override protected boolean rememberCreatedUser() { return rememberMe; }
配置安全性检查
在 adapter.xml 文件中,添加 <securityCheckDefinition>
元素:
<securityCheckDefinition name="UserLogin" class="com.sample.UserLogin">
<property name="maxAttempts" defaultValue="3" description="How many attempts are allowed."/>
<property name="blockedStateExpirationSec" defaultValue="10" description="How long before the client can try again (seconds)."/>
<property name="successStateExpirationSec" defaultValue="60" description="How long is a successful state valid for (seconds)."/>
<property name="rememberMeDurationSec" defaultValue="120" description="How long is the user remembered by the RememberMe feature (seconds)."/>
</securityCheckDefinition>
如前所述,UserAuthenticationSecurityCheck
继承所有 CredentialsValidationSecurityCheck
属性,例如,blockedStateExpirationSec
和 successStateExpirationSec
等。
此外,您还可以配置 rememberMeDurationSec
属性。
样本安全性检查
下载安全性检查 Maven 项目。
Maven 项目包含 UserAuthenticationSecurityCheck
的实现。
Inclusive terminology note: The Mobile First Platform team is making changes to support the IBM® initiative to replace racially biased and other discriminatory language in our code and content with more inclusive language. While IBM values the use of inclusive language, terms that are outside of IBM's direct influence are sometimes required for the sake of maintaining user understanding. As other industry leaders join IBM in embracing the use of inclusive language, IBM will continue to update the documentation to reflect those changes.