基于springboot的csa客户端搭建

基于springboot的csa客户端搭建

  • 环境:CAS服务端
  • hosts文件中配置:127.0.0.1 cas.example.org
springboot + cas
  • 导入依赖包
        <dependency>
            <groupId>net.unicon.cas</groupId>
            <artifactId>cas-client-autoconfig-support</artifactId>
            <version>1.4.0-GA</version>
        </dependency>
  • 在application.properties文件中添加如下配置
cas.server-url-prefix=https://cas.example.org:8443/cas
cas.server-login-url=https://cas.example.org:8443/cas/login
cas.client-host-url=http://cas.example.org:8088
cas.validation-type=CAS
cas.use-session=true
cas.redirect-after-validation=true
遇到的问题
未认证授权的服务
  • 访问客户端时跳转到cas服务端显示未认证授权的服务,内容如下:

未认证授权的服务。
CAS的服务记录是空的,没有定义服务。希望通过CAS进行认证的应用程序必须在服务记录中明确定义

  • 解决办法:

    • 修改cas服务端http支持的配置文件,路径:cas\WEB-INF\classes\services\HTTPSandIMAPS-10000001.json
    	{
    	  "@class" : "org.apereo.cas.services.RegexRegisteredService",
    	  // "serviceId" : "^(https|imaps)://.*",
    	  "serviceId" : "^(https|http|imaps)://.*",
    	  "name" : "HTTPS and IMAPS",
    	  "id" : 10000001,
    	  "description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.",
    	  "evaluationOrder" : 10000
    	}
    
    • CAS服务端启用记载JSON配置文件,在cas\WEB-INF\classes\application.properties添加如下配置:
    	cas.tgc.secure=false
    	cas.serviceRegistry.initFromJson=true
    
  • 修改后重启CSA服务端和客户端。

域名问题
  • 从服务端验证之后,跳转回来时出错,内容如下:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching cas.example.org found

  • 原因:由于配置CAS服务端使用HTTPS时,创建的证书中CN配置和域名不一致导致的。

  • 解决办法:

    • 重新创建证书:
     keytool -genkey -alias cas -keyalg RSA -keysize 2048 -keypass changeit -storepass changeit -keystore casexample.keystore -dname "CN=cas.example.org,OU=casexample.com,O=casexample,L=casexample,ST=casexample,C=CN" -deststoretype pkcs12
    
    • 将证书替换原来的证书。
  • 重启CAS服务端和客户端。

PKIX path building failed
  • 从服务端验证之后,跳转回来时出错,内容如下:

java.lang.RuntimeException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

  • 原因:服务端的证书是不安全的,Cas的客户端在调用时因为安全提醒造成调用失败。CAS的客户端需要导入服务端的证书后,就正常了。

  • 解决办法:

    • 创建文件InstallCert.java,内容如下:
    	import java.io.*;
    	import java.net.URL;
    	//
    	import java.security.*;
    	import java.security.cert.*;
    	//
    	import javax.net.ssl.*;
    	//
    	public class InstallCert {
    	//
    	    public static void main(String[] args) throws Exception {
    	    String host;
    	    int port;
    	    char[] passphrase;
    	    if ((args.length == 1) || (args.length == 2)) {
    	        String[] c = args[0].split(":");
    	        host = c[0];
    	        port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
    	        String p = (args.length == 1) ? "changeit" : args[1];
    	        passphrase = p.toCharArray();
    	    } else {
    	        System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
    	        return;
    	    }
    	//
    	    File file = new File("jssecacerts");
    	    if (file.isFile() == false) {
    	        char SEP = File.separatorChar;
    	        File dir = new File(System.getProperty("java.home") + SEP
    	            + "lib" + SEP + "security");
    	        file = new File(dir, "jssecacerts");
    	        if (file.isFile() == false) {
    	        file = new File(dir, "cacerts");
    	        }
    	    }
    	    System.out.println("Loading KeyStore " + file + "...");
    	    InputStream in = new FileInputStream(file);
    	    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    	    ks.load(in, passphrase);
    	    in.close();
    	//
    	    SSLContext context = SSLContext.getInstance("TLS");
    	    TrustManagerFactory tmf =
    	        TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    	    tmf.init(ks);
    	    X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
    	    SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
    	    context.init(null, new TrustManager[] {tm}, null);
    	    SSLSocketFactory factory = context.getSocketFactory();
    	//
    	    System.out.println("Opening connection to " + host + ":" + port + "...");
    	    SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
    	    socket.setSoTimeout(10000);
    	    try {
    	        System.out.println("Starting SSL handshake...");
    	        socket.startHandshake();
    	        socket.close();
    	        System.out.println();
    	        System.out.println("No errors, certificate is already trusted");
    	    } catch (SSLException e) {
    	        System.out.println();
    	        e.printStackTrace(System.out);
    	    }
    	//
    	    X509Certificate[] chain = tm.chain;
    	    if (chain == null) {
    	        System.out.println("Could not obtain server certificate chain");
    	        return;
    	    }
    	//
    	    BufferedReader reader =
    	        new BufferedReader(new InputStreamReader(System.in));
    	//
    	    System.out.println();
    	    System.out.println("Server sent " + chain.length + " certificate(s):");
    	    System.out.println();
    	    MessageDigest sha1 = MessageDigest.getInstance("SHA1");
    	    MessageDigest md5 = MessageDigest.getInstance("MD5");
    	    for (int i = 0; i < chain.length; i++) {
    	        X509Certificate cert = chain[i];
    	        System.out.println
    	            (" " + (i + 1) + " Subject " + cert.getSubjectDN());
    	        System.out.println("   Issuer  " + cert.getIssuerDN());
    	        sha1.update(cert.getEncoded());
    	        System.out.println("   sha1    " + toHexString(sha1.digest()));
    	        md5.update(cert.getEncoded());
    	        System.out.println("   md5     " + toHexString(md5.digest()));
    	        System.out.println();
    	    }
    	//
    	    System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
    	    String line = reader.readLine().trim();
    	    int k;
    	    try {
    	        k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
    	    } catch (NumberFormatException e) {
    	        System.out.println("KeyStore not changed");
    	        return;
    	    }
    	//
    	    X509Certificate cert = chain[k];
    	    String alias = host + "-" + (k + 1);
    	    ks.setCertificateEntry(alias, cert);
    	//
    	    OutputStream out = new FileOutputStream("jssecacerts");
    	    ks.store(out, passphrase);
    	    out.close();
    	//
    	    System.out.println();
    	    System.out.println(cert);
    	    System.out.println();
    	    System.out.println
    	        ("Added certificate to keystore 'jssecacerts' using alias '"
    	        + alias + "'");
    	    }
    	//
    	    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
    	//
    	    private static String toHexString(byte[] bytes) {
    	    StringBuilder sb = new StringBuilder(bytes.length * 3);
    	    for (int b : bytes) {
    	        b &= 0xff;
    	        sb.append(HEXDIGITS[b >> 4]);
    	        sb.append(HEXDIGITS[b & 15]);
    	        sb.append(' ');
    	    }
    	    return sb.toString();
    	    }
    	//
    	    private static class SavingTrustManager implements X509TrustManager {
    	//
    	    private final X509TrustManager tm;
    	    private X509Certificate[] chain;
    	//
    	    SavingTrustManager(X509TrustManager tm) {
    	        this.tm = tm;
    	    }
    	//
    	    public X509Certificate[] getAcceptedIssuers() {
    	        //throw new UnsupportedOperationException();
    	        return new X509Certificate[0];
    	    }
    	//
    	    public void checkClientTrusted(X509Certificate[] chain, String authType)
    	        throws CertificateException {
    	        throw new UnsupportedOperationException();
    	    }
    	//
    	    public void checkServerTrusted(X509Certificate[] chain, String authType)
    	        throws CertificateException {
    	        this.chain = chain;
    	        tm.checkServerTrusted(chain, authType);
    	    }
    	    }
    	//
    	}
    
    • 编译InstallCert.java:javac InstallCert.java

    • 生成客户端证书:java InstallCert cas.example.org:8443。填写您的域名和端口,运行InstallCert。运行过程中,出现了错误提示后,根据提示输入1,命令就自动生成了证书

    • 安装证书到客户端JVM,将生成的文件jssecacerts复制到%java_home%\jre\lib\security目录下。

  • 重启CAS服务端和客户端。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值