如何在JBoss 5中按会话ID获取会话

问题描述 投票:0回答:1

我想验证JBoss 5中的会话是否仍处于活动状态并处于登录状态。实现JWT(json web令牌)。

为此,我需要通过id获取会话。

session servlets jboss jwt jboss5.x
1个回答
0
投票

调试它:JBoss使用一个名为JBoss web的特殊版本的tomcat。然后我搜索了“jboss web 2 * jar”并将其添加为eclipse的源代码然后我可以调试它。也是在eclipse中,我已经从eclipse市场安装了FernFlower反编译器(*我从https://developer.jboss.org/wiki/VersionOfTomcatInJBossAS获取了实际版本)

我引用了那些来源how to refresh JSESSIONID cookie after login https://github.com/auth0/java-jwt

我的解决方案可以帮助其他伪tomcat servlet服务器

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();
}
© www.soinside.com 2019 - 2024. All rights reserved.