在我的Java EE6,REST服务,我想使用的认证令牌从移动设备登录,用户将派出自己的用户名,密码,服务器会发送回一个令牌,将用于对用户进行授权他们对于给定的进一步请求时间。
我可以简单地创建令牌自己这样吗?(我想我不需要加密此,因为我将使用HTTPS)。
String token = UUID.randomUUID().toString().toUpperCase()
+ "|" + "userid" + "|"
+ cal.getTimeInMillis();
或者对建立我的令牌更非标准的方式? 也许它存在于API的一个
您实际上提出的方案允许客户端不受限制地访问你的服务。 初次登录后,UID和“用户ID”将被提供给客户端,可以与一个始终有效时间戳简单地结合起来。
如果您需要“登录”和会话令牌服务,那么为什么不使用一个HttpSession?
要创建一个难以猜测的令牌在Java中使用java.security.SecureRandom
如
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
String token = bytes.toString();
而不是包括令牌的用户名倒不如缓存用户:令牌地图在内存或数据库中。
public class SecureTokenGenerator {
public static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
// 2048 bit keys should be secure until 2030 - https://web.archive.org/web/20170417095741/https://www.emc.com/emc-plus/rsa-labs/historical/twirl-and-rsa-key-size.htm
public static final int SECURE_TOKEN_LENGTH = 256;
private static final SecureRandom random = new SecureRandom();
private static final char[] symbols = CHARACTERS.toCharArray();
private static final char[] buf = new char[SECURE_TOKEN_LENGTH];
/**
* Generate the next secure random token in the series.
*/
public static String nextToken() {
for (int idx = 0; idx < buf.length; ++idx)
buf[idx] = symbols[random.nextInt(symbols.length)];
return new String(buf);
}
}
截断并从显著凝结https://stackoverflow.com/a/41156/584947
有一种方法来创建它不能妥协,但可以用于身份验证令牌太大。
创建该组合令牌:
BASE64(用户名+期满+客户端+ 3DES编码(USENAME,到期,源IP,浏览器identitifier其它值,对于客户端的其它值))
客户端可以使用该令牌认证该请求,例如JSON网络令牌(RFC 7515)的使用。
在服务器端,其用于3DES编码密钥可以随时间而旋转,作为令牌。 每个请求包含令牌的认证和每个响应包含同样的道理或到期前一个新的。
在这种情况下,令牌包含用户名等要求认证只需要检查3DES编码部分是否有效(相同,要求IP的来源是一样的。在这种情况下,如果有人偷了令牌令牌的可用性更作为有限的会话ID您可以撰写其它标识令牌,如浏览器等更难伪造的请求,因为攻击者要假冒更多的东西 - 这对他来说是未知的,因为他不知道什么是对的编码部分令牌(作为事实上没有绝对的安全,不仅可以使较难破解)
该解决方案的优点是:
- 每件为标准,而不是整个在一起,攻击者必须知道的实施细则,能够攻击。
- 因为每一个未加密的部分被包含在加密部分的客户端可以使用该令牌的部件用于从令牌显示信息,而令牌本身被固定 - 因此没有令牌的服务器侧失效不能被修改 - 因此其易于检测攻击。
- 有没有需要会话复制/聚类粘性会话的。 该3DES密钥足够的节点之间进行复制 - 因此它适用于无状态的后端策略。
该缺点是
REST是基于HTTP,并使用底层协议鼓励而不是重新发明轮子。 HTTP使用Cookie来支持像记住验证状态的交互,并且还支持用户名和密码验证。
此外,Java EE的支持这一切的开箱。 检查教程
http://docs.oracle.com/javaee/6/tutorial/doc/bncas.html