Search in sources :

Example 11 with JWT

use of com.auth0.android.jwt.JWT in project JustLive-Android by guyijie1211.

the class DanmuUtils method getWebSocketJwtParamsMap.

/**
 * 生成开放API Websocket连接参数
 * @param appId  开发者ID(https://ext.huya.com成为开发者后自动生成)
 * @param secret 开发者密钥(https://ext.huya.com成为开发者后自动生成)
 * @param roomId 要监听主播的房间号
 * @return
 */
public static Map<String, Object> getWebSocketJwtParamsMap(String appId, String secret, long roomId) {
    // 获取时间戳(毫秒)
    long currentTimeMillis = System.currentTimeMillis();
    // 超时时间:通常设置10分钟有效,即exp=iat+600,注意不少于当前时间且不超过当前时间60分钟
    long expireTimeMillis = System.currentTimeMillis() + 10 * 60 * 1000;
    Date iat = new Date(currentTimeMillis);
    Date exp = new Date(expireTimeMillis);
    try {
        Map<String, Object> header = new HashMap<String, Object>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");
        // 生成JWT凭证
        // 开发者密钥
        Algorithm algorithm = Algorithm.HMAC256(secret);
        String sToken = JWT.create().withHeader(// JWT声明
        header).withIssuedAt(// jwt凭证生成时间
        iat).withExpiresAt(// jwt凭证超时时间
        exp).withClaim("appId", // 开发者ID
        appId).sign(algorithm);
        Map<String, Object> authMap = new HashMap<String, Object>();
        // jwt凭证生成时间戳(秒)
        authMap.put("iat", currentTimeMillis / 1000);
        // jwt凭证超时时间戳(秒)
        authMap.put("exp", expireTimeMillis / 1000);
        // jwt签名串
        authMap.put("sToken", sToken);
        // 开发者ID
        authMap.put("appId", appId);
        // 接口默认参数
        authMap.put("do", "comm");
        // 需要监听主播的房间号
        authMap.put("roomId", roomId);
        return authMap;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
Also used : HashMap(java.util.HashMap) JSONObject(com.alibaba.fastjson.JSONObject) ByteString(okio.ByteString) Algorithm(com.auth0.jwt.algorithms.Algorithm) Date(java.util.Date) DataFormatException(java.util.zip.DataFormatException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 12 with JWT

use of com.auth0.android.jwt.JWT in project chemvantage by chuckwight.

the class Token method doGet.

// This servlet is the OpenID Connection starting point for platforms to reach ChemVantage
// The servlet identifies the deployment corresponding to the request, and returns a Java Web Token
// containing information needed for the subsequent launch request or other service request.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    StringBuffer debug = new StringBuffer("Issuing auth token:<br>");
    try {
        // store parameters required by third-party initiated login procedure:
        // this should be the platform_id URL (aud)
        String platform_id = request.getParameter("iss");
        debug.append("iss: " + platform_id + "<br>");
        String login_hint = request.getParameter("login_hint");
        debug.append("login_hint: " + login_hint + "<br>");
        String target_link_uri = request.getParameter("target_link_uri");
        debug.append("target_link_uri: " + target_link_uri + "<br>");
        debug.append("parameters: " + request.getParameterMap().keySet().toString() + "<br>");
        if (platform_id == null)
            throw new Exception("Missing required iss parameter.");
        if (login_hint == null)
            throw new Exception("Missing required login_hint parameter.");
        if (target_link_uri == null)
            throw new Exception("Missing required target_link_uri parameter.");
        String deployment_id = request.getParameter("lti_deployment_id");
        debug.append("deployment_id: " + deployment_id + "<br>");
        String client_id = request.getParameter("client_id");
        debug.append("client_id: " + client_id + "<br>");
        Deployment d = getDeployment(platform_id, deployment_id, client_id);
        if (d == null)
            throw new Exception("ChemVantage was unable to identify the deployment from your LMS. " + "Please check the registration to ensure the correct deployment_id and client_id. If your " + "platform registered multiple deployments with ChemVantage, it must provide the client_id " + "and/or deployment_id to uniquely identify one of them with each auth token request.<br/>" + "Contact admin@chemvantage.org for assistance.");
        String redirect_uri = target_link_uri;
        Date now = new Date();
        // 5 minutes from now
        Date exp = new Date(now.getTime() + 300000L);
        String nonce = Nonce.generateNonce();
        Algorithm algorithm = Algorithm.HMAC256(Subject.getHMAC256Secret());
        debug.append("JWT algorithm loaded OK.<br>");
        String iss = "https://" + request.getServerName();
        String token = JWT.create().withIssuer(iss).withSubject(login_hint).withAudience(platform_id).withExpiresAt(exp).withIssuedAt(now).withClaim("nonce", nonce).withClaim("deployment_id", d.getDeploymentId()).withClaim("client_id", d.client_id).withClaim("redirect_uri", redirect_uri).sign(algorithm);
        debug.append("JWT constructed and signed OK<br>");
        String lti_message_hint = request.getParameter("lti_message_hint");
        String oidc_auth_url = d.oidc_auth_url + "?response_type=id_token" + "&response_mode=form_post" + "&scope=openid" + "&prompt=none" + "&login_hint=" + login_hint + "&redirect_uri=" + redirect_uri + (lti_message_hint == null ? "" : "&lti_message_hint=" + lti_message_hint) + "&client_id=" + d.client_id + "&state=" + token + "&nonce=" + nonce;
        debug.append("Sending token: " + oidc_auth_url + "<p>");
        response.sendRedirect(oidc_auth_url);
    // d.claims = oidc_auth_url;
    // ofy().save().entity(d);
    } catch (Exception e) {
        response.getWriter().println("<h3>Failed Auth Token</h3>" + e.toString() + " " + e.getMessage() + "<br>" + debug.toString());
    }
}
Also used : Algorithm(com.auth0.jwt.algorithms.Algorithm) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) Date(java.util.Date)

Example 13 with JWT

use of com.auth0.android.jwt.JWT in project chemvantage by chuckwight.

the class LTIDeepLinks method validateDeepLinkRequest.

JsonObject validateDeepLinkRequest(HttpServletRequest request) throws Exception {
    // returns the validated Deployment
    Deployment d = validateIdToken(request);
    // Decode the JWT id_token payload as a JsonObject:
    JsonObject claims = null;
    try {
        DecodedJWT id_token = JWT.decode(request.getParameter("id_token"));
        String json = new String(Base64.getUrlDecoder().decode(id_token.getPayload()));
        claims = JsonParser.parseString(json).getAsJsonObject();
        d.claims = claims.toString();
        ofy().save().entity(d);
    } catch (Exception e) {
        throw new Exception("The id_token was not a valid JWT.");
    }
    try {
        verifyLtiMessageClaims(claims);
    } catch (Exception e) {
        throw new Exception("LTI message claims were invalid. " + e.getMessage());
    }
    try {
        verifyIsInstructor(claims);
    } catch (Exception e) {
        throw new Exception("Unauthorized: " + e.getMessage());
    }
    return claims;
}
Also used : JsonObject(com.google.gson.JsonObject) DecodedJWT(com.auth0.jwt.interfaces.DecodedJWT) ServletException(javax.servlet.ServletException) IOException(java.io.IOException)

Example 14 with JWT

use of com.auth0.android.jwt.JWT in project chemvantage by chuckwight.

the class LTILaunch method basicLtiLaunchRequest.

void basicLtiLaunchRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // check for required LTI launch parameters:
    try {
        String lti_message_type = request.getParameter("lti_message_type");
        if (lti_message_type == null || !"basic-lti-launch-request".contentEquals(lti_message_type)) {
            doError(request, response, "Invalid lti_message_type parameter.", null, null);
            return;
        }
        String lti_version = request.getParameter("lti_version");
        if (lti_version == null) {
            doError(request, response, "Missing lti_version parameter.", null, null);
            return;
        } else if (!lti_version.equals("LTI-1p0")) {
            doError(request, response, "Invalid lti_version parameter.", null, null);
            return;
        }
        String oauth_consumer_key = request.getParameter("oauth_consumer_key");
        if (oauth_consumer_key == null) {
            doError(request, response, "Missing oauth_consumer_key.", null, null);
            return;
        }
        String resource_link_id = request.getParameter("resource_link_id");
        if (resource_link_id == null) {
            doError(request, response, "Missing resource_link_id.", null, null);
            return;
        }
        Date now = new Date();
        BLTIConsumer tc;
        try {
            tc = ofy().load().type(BLTIConsumer.class).id(oauth_consumer_key).safe();
            if ("suspended".equals(tc.status)) {
                response.getWriter().println(Subject.header("ChemVantage Account Management") + suspendedAccount(tc) + Subject.footer);
                return;
            } else if (tc.expires != null && tc.expires.before(now)) {
                response.getWriter().println(Subject.header("ChemVantage Account Management") + expiredAccount(tc, request.getServerName()) + Subject.footer);
                return;
            }
            if (tc.secret == null)
                throw new Exception("Shared secret was not found in the ChemVantage database.");
            // 24 hrs ago
            Date yesterday = new Date(now.getTime() - 86400000L);
            if (tc.lastLogin == null || tc.lastLogin.before(yesterday)) {
                tc.lastLogin = now;
                tc.launchParameters = request.getParameterMap();
                try {
                    // this section synchronizes expiration dates from a single domain
                    String domain = new URL(tc.launchParameters.get("lis_outcome_service_url")[0]).getHost();
                    // domain may be null for instructors
                    if (domain != null)
                        tc.domain = domain;
                    if (tc.domain != null) {
                        // tc.domain may be null if grades are never returned to the LMS
                        List<BLTIConsumer> companions = ofy().load().type(BLTIConsumer.class).filter("domain", tc.domain).list();
                        companions.remove(tc);
                        for (BLTIConsumer tcc : companions) {
                            // assign the shortest expiration time found for this domain
                            if (tcc.expires != null && (tc.expires == null || tcc.expires.before(tc.expires)))
                                tc.expires = tcc.expires;
                        }
                    }
                } catch (Exception e) {
                }
                // update the lastLogin value and possibly the domain and expires fields
                ofy().save().entity(tc);
            }
        } catch (Exception e) {
            String use = request.getServerName().contains("dev-vantage") ? "dev" : "prod";
            throw new Exception("Invalid oauth_consumer_key. " + "Please verify that the oauth_consumer_key is entered into your LMS exactly as you are registered with ChemVantage. " + "If your account has been inactive for more than " + ("dev".equals(use) ? "30 days" : "six months") + ", it may have been " + "deleted in accordance with our <a href=https://www.chemvantage.org/About#privacy target=_blank>privacy policy</a>.<br/>" + "Please use the <a href=https://www.chemvantage.org/lti/registration target=_blank>ChemVantage Registration Page</a> " + "to reregister your LMS.");
        }
        OAuthMessage oam = OAuthServlet.getMessage(request, null);
        OAuthValidator oav = new SimpleOAuthValidator();
        OAuthConsumer cons = new OAuthConsumer("about:blank#OAuth+CallBack+NotUsed", oauth_consumer_key, tc.secret, null);
        OAuthAccessor acc = new OAuthAccessor(cons);
        OAuthSignatureMethod.getBaseString(oam);
        if (!Nonce.isUnique(request.getParameter("oauth_nonce"), request.getParameter("oauth_timestamp")))
            throw new Exception("Invalid nonce or timestamp.");
        try {
            oav.validateMessage(oam, acc);
        } catch (Exception e) {
            throw new Exception("OAuth validation failed, most likely due to an invalid shared_secret value in your LMS. Check carefully to eliminate leading or trailing blank spaces.");
        }
        // BLTI Launch message was validated successfully at this point
        // debug.append("Basic LTI launch message validated...");
        // Detect whether this is an anonymous LTI launch request per LTIv1p1p2. This is a security patch that
        // prevents a cross-site request forgery threat applicable to versions of LTI released prior to v1.3.
        // The launch procedure is for the TC to issue an anonymous BLTI launch request with no user information.
        // The TP wraps the TC-defined platform_state into an encrypted JSON Web Token (JWT) and redircects the browser
        // to the TC-specified relaunch_url with the original platform_state and the new tool_state parameters, where
        // tool_state is the encrypted JWT. The TC then relaunches to the TP with the user information and the
        // two state parameters, which must be verified by the TP to proceed with the launch. This security patch makes
        // ChemVantage compliant with LTIv1p1p2. If the parameters are not included, the TP may proceed with a
        // normal v1p0 BLTI launch; however this is subject to the following deprecation schedule:
        // LTIv1p0		last certification 12/31/2019 and last market availability 12/31/2020
        // LTIv1p1p2 	last certification 06/30/2021 and last market availability 06/30/2022
        String relaunch_url = request.getParameter("relaunch_url");
        String platform_state = request.getParameter("platform_state");
        String tool_state = request.getParameter("tool_state");
        Algorithm algorithm = Algorithm.HMAC256(Subject.getHMAC256Secret());
        if (tool_state != null && platform_state != null) {
            // This is a LTIv1.1.2 relaunch response. Validate the tool_state value
            try {
                JWT.require(algorithm).withIssuer("https://www.chemvantage.org").withClaim("platform_state", platform_state).build().verify(tool_state);
                if (tc.lti_version == null || !tc.lti_version.equals("LTI-1p1p2")) {
                    tc.lti_version = "LTI-1p1p2";
                    // should have to do this only once
                    ofy().save().entity(tc);
                }
            } catch (Exception e) {
                throw new Exception("Tool state could not be validated.");
            }
        } else if (relaunch_url != null && platform_state != null) {
            // Anonymous LRTIv1p1p2 launch request. Execute relaunch sequence:
            try {
                // 10 minutes from now
                Date expires = new Date(new Date().getTime() + 600000);
                tool_state = JWT.create().withIssuer("https://www.chemvantage.org").withClaim("platform_state", platform_state).withExpiresAt(expires).sign(algorithm);
                response.sendRedirect(relaunch_url + "?platform_state=" + platform_state + "&tool_state=" + tool_state);
                lti_version = "LTI-1p1p2_proposed";
            } catch (Exception e) {
                throw new Exception("Tool state JWT could not be created.");
            }
            // wait for relaunch from platform
            return;
        }
        // End of LTIv1p1p2 section. Continue with normal LTI launch sequence
        // Gather some information about the user
        String userId = request.getParameter("user_id");
        userId = oauth_consumer_key + ":" + (userId == null ? "" : userId);
        // Process user information, provision a new user account if necessary, and store the userId in the user's session
        User user = new User(userId);
        // check if user has Instructor or Administrator role
        String roles = request.getParameter("roles");
        if (roles != null) {
            roles = roles.toLowerCase();
            user.setIsInstructor(roles.contains("instructor"));
            user.setIsAdministrator(roles.contains("administrator"));
            user.setIsTeachingAssistant(roles.contains("teachingassistant"));
        }
        // user information OK;
        // debug.append("userId=" + userId + " and role=" + (user.isInstructor()?"Instructor":"Learner") + "...");
        // Gather information that may be needed to return a score to the LMS:
        String lis_result_sourcedid = request.getParameter("lis_result_sourcedid");
        // debug.append("lis_result_sourcedid=" + lis_result_sourcedid + "...");
        String lisOutcomeServiceUrl = request.getParameter("lis_outcome_service_url");
        // debug.append("lis_outcome_service_url=" + lisOutcomeServiceUrl + "...");
        // Use the resourceLinkId to find the assignment or create a new one:
        Assignment myAssignment = null;
        boolean saveAssignment = false;
        try {
            // load the requested Assignment entity if it exists
            myAssignment = ofy().load().type(Assignment.class).filter("domain", oauth_consumer_key).filter("resourceLinkId", resource_link_id).first().safe();
            if (lisOutcomeServiceUrl != null && !lisOutcomeServiceUrl.equals(myAssignment.lis_outcome_service_url)) {
                myAssignment.lis_outcome_service_url = lisOutcomeServiceUrl;
                saveAssignment = true;
            }
            if (saveAssignment)
                ofy().save().entity(myAssignment);
        } catch (Exception e) {
            // or create a new one with the available information (but no assignmentType or topicIds)
            myAssignment = new Assignment(oauth_consumer_key, resource_link_id, lisOutcomeServiceUrl, true);
            // we'll need the new id value immediately
            ofy().save().entity(myAssignment).now();
        }
        user.setAssignment(myAssignment.id, lis_result_sourcedid);
        if (myAssignment.isValid()) {
            // used for hashing userIds by Task queue
            Queue queue = QueueFactory.getDefaultQueue();
            queue.add(withUrl("/HashUserIds").param("sig", user.getTokenSignature()));
            response.sendRedirect("/" + myAssignment.assignmentType + "?sig=" + user.getTokenSignature());
        } else
            response.getWriter().println(Subject.header("Select A ChemVantage Assignment") + pickResourceForm(user, myAssignment, -1) + Subject.footer);
        return;
    } catch (Exception e) {
        doError(request, response, "LTI Launch failed. " + e.getMessage(), null, e);
    }
}
Also used : SimpleOAuthValidator(net.oauth.SimpleOAuthValidator) OAuthMessage(net.oauth.OAuthMessage) OAuthConsumer(net.oauth.OAuthConsumer) Algorithm(com.auth0.jwt.algorithms.Algorithm) Date(java.util.Date) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) URL(java.net.URL) OAuthAccessor(net.oauth.OAuthAccessor) SimpleOAuthValidator(net.oauth.SimpleOAuthValidator) OAuthValidator(net.oauth.OAuthValidator) Queue(com.google.appengine.api.taskqueue.Queue)

Example 15 with JWT

use of com.auth0.android.jwt.JWT in project chemvantage by chuckwight.

the class LTIRegistration method createDeployment.

String createDeployment(HttpServletRequest request) throws Exception {
    DecodedJWT jwt = JWT.decode(request.getParameter("Token"));
    String client_name = jwt.getSubject();
    String email = jwt.getClaim("email").asString();
    String organization = jwt.getAudience().get(0);
    String org_url = jwt.getClaim("url").asString();
    String lms = jwt.getClaim("lms").asString();
    String client_id = request.getParameter("ClientId");
    if (client_id == null)
        throw new Exception("Client ID value is required.");
    String deployment_id = request.getParameter("DeploymentId");
    if (deployment_id == null)
        throw new Exception("Deployment ID value is required.");
    String platform_id;
    String oidc_auth_url;
    String oauth_access_token_url;
    String well_known_jwks_url;
    switch(lms) {
        case "blackboard":
            platform_id = "https://blackboard.com";
            oidc_auth_url = "https://developer.blackboard.com/api/v1/gateway/oidcauth";
            well_known_jwks_url = "https://developer.blackboard.com/api/v1/management/applications/" + client_id + "/jwks.json";
            oauth_access_token_url = "https://developer.blackboard.com/api/v1/gateway/oauth2/jwttoken";
            break;
        case "canvas":
            platform_id = "https://canvas.instructure.com";
            oidc_auth_url = "https://canvas.instructure.com/api/lti/authorize_redirect";
            well_known_jwks_url = "https://canvas.instructure.com/api/lti/security/jwks";
            URL account_url = new URL(request.getParameter("AccountUrl"));
            if (account_url.getHost().contains("instructure.com"))
                oauth_access_token_url = "https://" + account_url.getHost() + "/login/oauth2/token";
            else
                oauth_access_token_url = "https://canvas.instructure.com/login/oauth2/token";
            break;
        case "LTI Certification":
        case "IMS Certification":
            platform_id = "https://ltiadvantagevalidator.imsglobal.org";
            oidc_auth_url = "https://ltiadvantagevalidator.imsglobal.org/ltitool/oidcauthurl.html";
            well_known_jwks_url = "https://oauth2server.imsglobal.org/jwks";
            oauth_access_token_url = "https://ltiadvantagevalidator.imsglobal.org/ltitool/authcodejwt.html";
            break;
        default:
            platform_id = request.getParameter("PlatformId");
            if (platform_id == null || platform_id.isEmpty())
                throw new Exception("Platform ID value is required.");
            oidc_auth_url = request.getParameter("OIDCAuthUrl");
            if (oidc_auth_url == null || oidc_auth_url.isEmpty())
                throw new Exception("OIDC Auth URL is required.");
            oauth_access_token_url = request.getParameter("OauthAccessTokenUrl");
            if (oauth_access_token_url == null || oauth_access_token_url.isEmpty())
                throw new Exception("OAuth Access Token URL is required.");
            well_known_jwks_url = request.getParameter("JWKSUrl");
            if (well_known_jwks_url == null || well_known_jwks_url.isEmpty())
                throw new Exception("JSON Web Key Set URL is required.");
    }
    Deployment d = new Deployment(platform_id, deployment_id, client_id, oidc_auth_url, oauth_access_token_url, well_known_jwks_url, client_name, email, organization, org_url, lms);
    d.status = "pending";
    d.price = 20;
    Deployment prior = Deployment.getInstance(d.platform_deployment_id);
    String msg = "<h2>Congratulations. Registration is complete.</h2>" + "<br/><br/>Contact Chuck Wight at admin@chemvantage.org for support with any questions or issues.<br/><br/>Thank you.";
    if (prior != null) {
        // this is a repeat registration
        d.status = prior.status == null ? "pending" : prior.status;
        if (prior.client_id.equals(d.client_id))
            msg += "Note: this platform deployment was registered previously. The registration data have now been updated.<p>";
        else
            msg += "Note: This platform deployment was registered previously. The client_id and registration data have now been updated. If this is not correct, you should contact admin@chemvantage.org immediately.<p>";
    }
    // registration is now complete
    ofy().save().entity(d).now();
    return msg;
}
Also used : DecodedJWT(com.auth0.jwt.interfaces.DecodedJWT) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) URL(java.net.URL)

Aggregations

DecodedJWT (com.auth0.jwt.interfaces.DecodedJWT)305 Test (org.junit.Test)217 Algorithm (com.auth0.jwt.algorithms.Algorithm)110 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)82 JWTVerifier (com.auth0.jwt.JWTVerifier)79 IOException (java.io.IOException)60 JWTVerificationException (com.auth0.jwt.exceptions.JWTVerificationException)54 ECDSAAlgorithmTest (com.auth0.jwt.algorithms.ECDSAAlgorithmTest)53 Date (java.util.Date)50 Claim (com.auth0.jwt.interfaces.Claim)36 RSAPublicKey (java.security.interfaces.RSAPublicKey)34 ECPublicKey (java.security.interfaces.ECPublicKey)27 ECDSAKeyProvider (com.auth0.jwt.interfaces.ECDSAKeyProvider)26 HashMap (java.util.HashMap)25 JWTDecodeException (com.auth0.jwt.exceptions.JWTDecodeException)20 Instant (java.time.Instant)20 JsonObject (com.google.gson.JsonObject)19 ServletException (javax.servlet.ServletException)19 JWT (com.auth0.jwt.JWT)18 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)18