我正在用jersey
制作一个rest API。我使用java-jwt
(https://github.com/auth0/java-jwt)进行令牌生成工作。请检查下面的代码。
@Path ("/user_info")
public class UserInfoJSONService
{
@POST
@Path("/authenticateUser")
@Produces(MediaType.APPLICATION_JSON)
public Response authenticateUser(Credentials credentials)
{
UserInfoService service = new UserInfoService();
try{
UserInfo authenticateUser = service.authenticateUser(credentials.getUserName(), credentials.getPassword());
String generateToken = service.generateToken(AuthKey.authorizationSecret);
Authentication auth = new Authentication();
auth.setIdUser(authenticateUser.getIduser());
auth.setToken(generateToken);
return Response.status(Response.Status.OK).entity(auth).build();
//return authenticateUser;
}
catch(IndexOutOfBoundsException e)
{
throw new WebApplicationException(Response.Status.BAD_REQUEST);
} catch (JWTCreationException ex) {
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
} catch (UnsupportedEncodingException ex) {
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
}
UserInfoService-服务层
public class UserInfoService {
private static UserInfoDAOInterface userDAOInterface;
public UserInfoService() {
userDAOInterface = new UserInfoDAOImpl();
}
public Session getSession() {
Session session = userDAOInterface.openCurrentSession();
return session;
}
public Transaction getTransaction(Session session) {
Transaction transaction = userDAOInterface.openTransaction(session);
return transaction;
}
public UserInfo authenticateUser(String userName, String password)
{
return authenticate(userName, password);
}
private UserInfo authenticate(String userName, String password) throws IndexOutOfBoundsException
{
Session session = userDAOInterface.openCurrentSession();
Transaction transaction = null;
UserInfo user = new UserInfo();
try {
transaction = userDAOInterface.openTransaction(session);
user = userDAOInterface.authenticate(userName, password, session);
transaction.commit();
// } catch (Exception ex) {
// //ex.printStackTrace();
// System.out.println("OK");
//
} finally {
session.close();
}
return user;
}
public String generateToken(String secret) throws JWTCreationException, UnsupportedEncodingException
{
Token token = new Token();
return token.issueTokenHMAC256(secret);
}
}
AuthKey-仅包含秘密
public interface AuthKey {
public static String authorizationSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>ExampleServlet</servlet-name>
<servlet-class>test.ExampleServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>Jersey RESTful Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>rest</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ExampleServlet</servlet-name>
<url-pattern>/ExampleServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Jersey RESTful Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
package com.xyz.security;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.io.UnsupportedEncodingException;
/**
*
* @author Yohan
*/
public class Token {
/**
* Generate the HMAC256 Token
* @param secret
* Secret to generate the token
* @return
* Token as a String
* @throws UnsupportedEncodingException
* UTF-8 encoding not supported
* @throws JWTVerificationException
* Invalid Signing configuration / Couldn't convert Claims.
*/
public String issueTokenHMAC256(String secret) throws UnsupportedEncodingException, JWTCreationException
{
String token="";
try {
Algorithm algorithm = Algorithm.HMAC256(secret);
token = JWT.create()
.withIssuer("auth0")
.sign(algorithm);
} catch (UnsupportedEncodingException exception) {
//UTF-8 encoding not supported
exception.printStackTrace();
} catch (JWTCreationException exception) {
//Invalid Signing configuration / Couldn't convert Claims.
exception.printStackTrace();
}
return token;
}
/**
* Validate a HMAC256 Token
* @param token
* Token you need to validate
* @param secret
* Secret used to generate the token
* @return
* Returns `true` if token is valid.
* @throws UnsupportedEncodingException
* UTF-8 encoding not supported
* @throws JWTVerificationException
* Invalid Signing configuration / Couldn't convert Claims.
*/
public boolean validateTokenHMAC256(String token, String secret) throws UnsupportedEncodingException, JWTVerificationException
{
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("auth0")
.build(); //Reusable verifier instance
DecodedJWT jwt = verifier.verify(token);
return true;
}
}
在基于令牌的认证方案中,令牌成为用户的凭据。用户名和密码等硬凭据被交换为必须在每个请求中发送的令牌,然后服务器可以执行身份验证/授权。令牌可以在很短的时间内有效,可以被撤销,可以携带范围详细信息(可以用令牌请求什么),等等。
使用令牌,您必须能够识别针对您的API的用户。因此,为所有经过身份验证的用户提供一个令牌是没有意义的。
一旦您使用了JWT,您就可以拥有一个用户名的声明。还要考虑为令牌(exp
claim)添加过期日期。你不想让你的代币永远有效吧?
try {
Algorithm algorithm = Algorithm.HMAC256("secret");
Date expirationDate = Date.from(ZonedDateTime.now().plusMinutes(60).toInstant());
String token = JWT.create()
.withExpiresAt(expirationDate)
.withClaim("username", username)
.sign(algorithm);
} catch (UnsupportedEncodingException e){
// UTF-8 encoding not supported
} catch (JWTCreationException e){
// Invalid signing configuration / Couldn't convert claims
}
try {
Algorithm algorithm = Algorithm.HMAC256("secret");
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
Claim usernameClaim = jwt.getClaim("username");
String username = usernameClaim.asString();
} catch (UnsupportedEncodingException e){
// UTF-8 encoding not supported
} catch (JWTVerificationException e){
// Invalid signature/claims
}
仅接受有效的(未过期的)令牌进行刷新。客户端有责任在exp
声明中指示的过期日期之前刷新令牌。
为了避免令牌被无限期刷新,您可以通过向令牌添加两个声明(声明名称由您决定)来跟踪令牌刷新:
refreshlimit
:指示可刷新令牌的次数。refreshCount
:指示令牌已刷新多少次。exp>=now
)。refreshCount
)。
刷新令牌时:
- 更新过期日期(
exp=now+some-amount-of-time
)。 - 增加刷新令牌的次数(
refreshcount++
)。
另外,为了跟踪点心的数量,您可以使用一个声明来指示绝对过期日期。在此日期之前,任何数量的茶点都是可以接受的。
另一种方法涉及发出单独的长寿命刷新令牌,该令牌用于发出短寿命的JWT令牌。
最佳方法取决于您的需求。
出于安全目的,当用户更改密码时,吊销用户的所有令牌。
有关JAX-RS中基于令牌的身份验证的详细信息,请参阅本答案。
问题内容: 我正在使用制作REST API 。我正在使用(https://github.com/auth0/java- jwt )进行令牌生成工作。请检查以下代码。 UserJSONInfo -REST方法类 UserInfoService- 服务层 AuthKey-仅 包含 web.xml 我将令牌生成类维护为另一个Java项目,并将其作为库导入此处(我正在使用Netbeans)。下面是代码 现
我有两个Rest终点。 -身份提供程序,在用户通过用户名/密码的身份验证后,发送JWT令牌作为响应。 -接受上述JWT令牌作为头,对其进行验证,如果令牌有效,则发送用户JSON作为响应。 我已经使用Angular2创建了我的UI null
{“access_token”:“txxxxxxxxxxxxxxxxxxfb45a”,“expires_in”:36000,“token_type”:“承载”,“scope”:“读写组”,“refresh_token”:“16okxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxfb45a”} 到 {“access_token”:“xxxxxxxx.xxxxx.xxxxxx”,“e
我需要我的logstash conf文件向一个kafka主题发送一条消息,以指示已处理的文档已发送到ElasticSearch。我已经准备好了logstash文件来构造发送到ElasticSearch的数据,但是我需要通过同一个logstash文件向kafka主题发布“是”或“否”消息。
问题内容: 考虑类似: 这是好习惯吗?难道这会在我们读取输入文件的同时覆盖输入文件,还是总是先在内存中读取它,然后通过管道传递给第二个命令? 显然,我可以将临时文件用作中介步骤,但我只是想知道.. 问题答案: 不,那不行。管道中的所有命令同时执行,并且外壳程序在执行命令之前准备重定向。因此,该命令很可能在cat读取文件之前将其覆盖。 您需要moreutils提供的海绵(1)。