我想验证JBoss 5中的会话是否仍处于活动状态并处于登录状态。实现JWT(json网络令牌)。
为此,我需要按ID进行会话。
答案 0 :(得分:0)
对其进行调试:JBoss使用称为JBoss web的特殊版本的tomcat。 然后我搜索了“ jboss web 2 * jar”,并将其添加为日蚀源,然后可以对其进行调试。同样在eclipse中,我已经从eclipse市场上安装了FernFlower反编译器(*我从https://developer.jboss.org/wiki/VersionOfTomcatInJBossAS获得了实际版本)
我引用了那些资料 how to refresh JSESSIONID cookie after login https://github.com/auth0/java-jwt
我的解决方案可能会帮助其他伪tomcat serverlet服务器
package com.mysoftware.controller.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.mysoftware.util.SqlInjectionAndXSSRequestWrapper;
import com.mysoftware.model.User;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestWrapper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.catalina.Manager;
import org.apache.catalina.Session;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.RequestFacade;
import org.jboss.seam.security.Identity;
import org.jboss.seam.web.ServletContexts;
import org.jboss.util.Base64;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Cipher;
public class JWTAuthorization {
public static String isSessionIdLoggedIn(String requestedSessionId) {
try {
// get the request
HttpServletRequest request =ServletContexts.instance().getRequest();
ServletRequest serverletRequest = ((ServletRequestWrapper)request).getRequest();
// first need to unwrap the request until the core - org.apache.catalina.connector.Request.
// i had additional wrapper around the request SqlInjectionAndXSSRequestWrapper. (you probably wont have it)
// for simplicity i added SqlInjectionAndXSSRequestWrapper.request to my class, just saved the constructor argument.
SqlInjectionAndXSSRequestWrapper injectionRequest = (SqlInjectionAndXSSRequestWrapper) serverletRequest;
// code may start here, I run it and cast it and debug it and when I see it crash: "can't convert class x to y'. I understand which class it is and unwrap it accordingly.
RequestFacade requestFacade = (RequestFacade) injectionRequest.request;
Field catalinaRequestField;
//Getting actual catalina request using reflection
catalinaRequestField = requestFacade.getClass().getDeclaredField( "request" );
catalinaRequestField.setAccessible( true ); // grant access to (protected) field
Request realRequest = (Request)catalinaRequestField.get( requestFacade );
Manager manager = realRequest.getContext().getManager();
HttpSession session = null;
try {
session=(HttpSession) manager.findSession(requestedSessionId);
} catch (IOException var7) {}
if (session != null && !((Session) session).isValid()) {session = null;}
if (session != null) {((Session) session).access();} // mark usage
if (session != null && session.isNew()) return "new";
if (session != null )
{
Identity identity = (Identity)session.getAttribute("org.jboss.seam.security.identity");
if (identity != null && identity.isLoggedIn()) return "login";
}
return "not login";
} catch (Exception e1) {
e1.printStackTrace();
return "exception";
}
}
protected final static String sessionidencryptionkey="1234567890ghdg";
protected final static String jwtsecret="1234567890sdghsg";
public static String getTokenForCRM(User user)
{
try {
Algorithm algorithm = Algorithm.HMAC256(jwtsecret);
String token = JWT.create()
.withSubject(user.getId().toString())
.withArrayClaim("CRM", new String[]{ user.getAccount().getCrm() } )
.withClaim("SessionID", encrypt( ServletContexts.instance().getRequest().getSession().getId() , sessionidencryptionkey) )
.sign(algorithm);
return token;
} catch (Exception exception){
//Invalid Signing configuration / Couldn't convert Claims.
}
return "ERROR_CREATEING_TOKEN";
}
public static String getSessionId(DecodedJWT token)
{
try {
return decrypt( token.getClaim("SessionID").asString() , sessionidencryptionkey) ;
} catch (Exception e) {
//e.printStackTrace();
return null;
}
}
public static DecodedJWT verifyToken(String token)
{
try {
Algorithm algorithm = Algorithm.HMAC256(jwtsecret);
JWTVerifier verifier = JWT.require(algorithm)
//.withIssuer("auth0")
.build(); //Reusable verifier instance
DecodedJWT jwt = verifier.verify(token);
return jwt;
} catch (JWTVerificationException exception){
//Invalid signature/claims
}
return null;
}
public static String encrypt(String strClearText,String strKey) throws Exception{
String strData="";
try {
SecretKeySpec skeyspec=new SecretKeySpec(strKey.getBytes(),"Blowfish");
Cipher cipher=Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, skeyspec);
byte[] encrypted=cipher.doFinal(strClearText.getBytes());
strData=new String(encrypted);
//strData=Base64.encodeBytes(encrypted);
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e);
}
return strData;
}
public static String decrypt(String strEncrypted,String strKey) throws Exception{
String strData="";
try {
SecretKeySpec skeyspec=new SecretKeySpec(strKey.getBytes(),"Blowfish");
Cipher cipher=Cipher.getInstance("Blowfish");
cipher.init(Cipher.DECRYPT_MODE, skeyspec);
final byte[] strEncryptedBytes=strEncrypted.getBytes();
// final byte[] strEncryptedBytes==Base64.encode(strEncrypted)
byte[] decrypted=cipher.doFinal(strEncryptedBytes);
strData=new String(decrypted);
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e);
}
return strData;
}
}
我的测试代码是
我有一个控制器内:
在不同的浏览器上调用时不会感到烦恼, 然后在其中一个浏览器中添加另一个会话ID的参数
@GET
@Path("testJWTSessionCheck")
@Produces("application/json")
public String testJWTSessionCheck( @QueryParam("s") String requestedSessionId) {
if(requestedSessionId!=null && requestedSessionId.length()>5) {
JWTAuthorization.isSessionIdLoggedIn(requestedSessionId);
}
HttpSession session1 = ServletContexts.instance().getRequest().getSession(false);
return session1.getId();
}