JSP for Discourse SSO

因为JAVA的Base64实现和Ruby不同,在使用SSO时会有异常,根据meta.discoursecn.org管理员的指点及资料查阅和代码分析,实现如下:

<%@ page contentType="text/html; charset=utf-8" %>
<%@ page import="org.apache.commons.codec.binary.Base64" %>
<%@ page import="org.apache.commons.codec.binary.Hex" %>
<%@ page import="javax.crypto.Mac" %>
<%@ page import="javax.crypto.spec.SecretKeySpec" %>
<%@ page import="java.io.UnsupportedEncodingException" %>
<%@ page import="java.net.URLDecoder" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="java.security.InvalidKeyException" %>
<%@ page import="java.security.NoSuchAlgorithmException" %>
<%
    response.setHeader("Pragma", "no-cache");
    response.setDateHeader("Expires", -1);
    Info info = (Info) session.getAttribute("Info");
    if (info == null) {
        response.sendRedirect("login.html");
        return;
    }
    String key = "yourssosecret";
    String payload = request.getParameter("sso");
    String sig = request.getParameter("sig");
    if (payload == null || sig == null) {
        response.getWriter().println("error parameter");
        return;
    }
    if (!checksum(key, payload).equals(sig)) {
        response.getWriter().println("checksum failed");
        return;
    }
    String urlDecode = URLDecoder.decode(payload, "UTF-8");
    String nonce = new String(Base64.decodeBase64(urlDecode));
    String urlEncode = nonce
            + "&name=" + URLEncoder.encode(info.name, "UTF-8")
            + "&username=" + URLEncoder.encode(info.nickname, "UTF-8")
            + "&email=" + URLEncoder.encode(info.email, "UTF-8")
            + "&external_id=" + URLEncoder.encode(info.id + "", "UTF-8");
    String urlBase64 = new String(Base64.encodeBase64(urlEncode.getBytes("UTF-8")));
    int length = 0;
    int maxLength = urlBase64.length();
    final int STEP = 60;
    String urlBase64Encode = "";
    while (length < maxLength) {
        urlBase64Encode += urlBase64.substring(length, length + STEP < maxLength ? length + STEP : maxLength) + "\n";
        length += STEP;
    }
    response.sendRedirect("http://yoursite.com/session/sso_login?sso=" + URLEncoder.encode(urlBase64Encode, "UTF-8") + "&sig=" + checksum(key, urlBase64Encode));
%>
<%!
    String checksum(String macKey, String macData) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        Mac mac = Mac.getInstance("HmacSHA256");
        byte[] keyBytes = macKey.getBytes("UTF-8");
        byte[] dataBytes = macData.getBytes("UTF-8");
        SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "HmacSHA256");
        mac.init(secretKey);
        byte[] doFinal = mac.doFinal(dataBytes);
        byte[] hexBytes = new Hex().encode(doFinal);
        return new String(hexBytes);
    }
%>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值