吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6246|回复: 1
收起左侧

[会员申请] 申请会员ID:HarryWan

[复制链接]
吾爱游客  发表于 2019-6-24 17:24
1、申 请 I D:HarryWan
2、个人邮箱:
harrywan1993@163.com

3、原创技术文章:单点登陆CAS源码编译,添加自定义密码加解密校验(后端RSA解密,MD5+Salt加密)

环境准备:Cas Server=4.0.0
               java version=1.7(官方申明cas4只支持jdk7及以下版本,高于1.7源码编译不通过)
               maven=3.6

背景:企业ToB项目需要支持单点登陆,Cas自带的密码加解密校验方式不支持项目本身,需要进行源码的二次开发。
自定义加解密:前端RSA加密,到CAS Server先进行RSA解密,在对明文密码进行Md5+Salt加密,和后端DB里的密码(Md5+Salt)进行比对,从而完成SSO

文章包括:1.针对自定义加解密源码改动
               2.CasServer部分源码解读

1.改动入口:cas-server-webapp下的deployerConfigContext.xml

[Asm] 纯文本查看 复制代码
<bean id="dataSource"
                class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
                <property name="url" value="jdbc:mysql://1.1.1.1:8306/demo"></property>
                <property name="username" value="xixi"></property>
                <property name="password" value="haha"></property>
        </bean>

        <bean id="primaryAuthenticationHandler"
                class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
                <property name="dataSource" ref="dataSource" />
                <property name="sql" value="select xx from xx where xx = ?" />
                <property name="passwordEncoder" ref="Md5SaltPasswordEncoder" />
        </bean>
<!-- <bean id="primaryAuthenticationHandler"
          class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
        <property name="users">
            <map>
                <entry key="casuser" value="Mellon"/>
            </map>
        </property>
    </bean> -->

注:1.添加数据源
     2.Cas不同的身份校验方式对应不同的Handler默认的校验方式为AcceptUsersAuthenticationHandler写死的用户名密码casuser/Mellon,这边注释,使用QueryDatabaseAuthenticationHandler,配置数据源,这里的Sql语句用来查询Db里对应的用户名密码进行身份判断,具体的密码加解密流程就在自定义的Md5SaltPasswordEncoder.java中

[XML] 纯文本查看 复制代码
<bean id="Md5SaltPasswordEncoder"
                class="org.jasig.cas.authentication.handler.Md5SaltPasswordEncoder">
                <constructor-arg index="0">
                        <value>MD5</value>
                </constructor-arg>
                <constructor-arg index="1">
                        <value>此处是Md5加密的盐值</value>
                </constructor-arg>
                <constructor-arg index="2">
                        <value>此处是Rsa的私钥,用于Rsa解密</value>
                </constructor-arg>
                <constructor-arg index="3">
                        <value>UTF-8</value>
                </constructor-arg>
        </bean>

注:这里通过构造器注入的方式,处理的业务逻辑为将前端的rsa密文解密,在进行MD5+Salt加密

[Java] 纯文本查看 复制代码
/*
 * Licensed to Jasig under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Jasig licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License.  You may obtain a
 * copy of the License at the following location:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.jasig.cas.authentication.handler;

import javax.validation.constraints.NotNull;

import org.apache.commons.lang.StringUtils;
import org.jasig.cas.util.MD5Utils;
import org.jasig.cas.util.RsaUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Md5SaltPasswordEncoder implements PasswordEncoder {
        protected final Logger logger = LoggerFactory.getLogger(this.getClass());

        @NotNull
        private final String encodingAlgorithm;
        @NotNull
        private final String salt;
        @NotNull
        private final String privateKey;
        @NotNull
        private final String characterEncoding;


        @Override
        public String encode(String password) {
                if (!StringUtils.isEmpty(password)) {
                        String rsaDecryptPwd = RsaUtils.decrypt(password, privateKey);
                        logger.debug("Md5SaltPasswordEncoder#encode,rsaDecryptPwd= {}", rsaDecryptPwd);
                        String md5SaltPwd = MD5Utils.digestWithSalt(rsaDecryptPwd, salt);
                        logger.debug("Md5SaltPasswordEncoder#encode,md5SaltPwd= {}", md5SaltPwd);
                        return md5SaltPwd;
                }
                return null;
        }

        public Md5SaltPasswordEncoder(String encodingAlgorithm, String salt, String privateKey, String characterEncoding) {
                this.encodingAlgorithm = encodingAlgorithm;
                this.salt = salt;
                this.privateKey = privateKey;
                this.characterEncoding = characterEncoding;
        }


}

注:实现cas自带的PasswordEncoder,实现自定义encode方法,对前端的密码进行加解密,具体加解密代码分装在工具类中





2.部分源码解析(用户身份认证流程)
2.1 顶层接口AuthenticationHandler,通过authenticate(Credential credential)方法进行身份认证
2.2 抽象类AbstractUsernamePasswordAuthenticationHandler实现AuthenticationHandler接口,doAuthentication(final Credential credential)方法做认证前置的部分校验,
      通过模板方法模式暴露authenticateUsernamePasswordInternal钩子方法,共自定义实现,不同的Handler实现对应不同的认证方式,包括Shiro,Ldap,QueryDatabase,以及默认的AcceptUserName方式,这边具体的 Handler在上面的xml中进行指定
[Java] 纯文本查看 复制代码
@Override
    protected final HandlerResult doAuthentication(final Credential credential)
            throws GeneralSecurityException, PreventedException {
        final UsernamePasswordCredential userPass = (UsernamePasswordCredential) credential;
        if (userPass.getUsername() == null) {
            throw new AccountNotFoundException("Username is null.");
        }
        
        final String transformedUsername= this.principalNameTransformer.transform(userPass.getUsername());
        if (transformedUsername == null) {
            throw new AccountNotFoundException("Transformed username is null.");
        }
        userPass.setUsername(transformedUsername);
        //钩子方法authenticateUsernamePasswordInternal,不同Handler实现类对应不同的认证方式,在deploy.xml配置指定
        return authenticateUsernamePasswordInternal(userPass);
    }

2.3,具体的认证流程在QueryDatabaseAuthenticationHandler类中,已在代码中进行了步骤注释
[Java] 纯文本查看 复制代码
@Override
    protected final HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential)
            throws GeneralSecurityException, PreventedException {

        final String username = credential.getUsername();
        //1.获取指定的Md5SaltPasswordEncoder进行前端密码加解密
        final String encryptedPassword = this.getPasswordEncoder().encode(credential.getPassword());
        try {
                //2.通过配置的数据源查询sql获取db中的密码
            final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
            //3.这里进行密码比对,db里的密码和前端密码
            if (!dbPassword.equals(encryptedPassword)) {
                throw new FailedLoginException("Password does not match value on record.");
            }
        } catch (final IncorrectResultSizeDataAccessException e) {
            if (e.getActualSize() == 0) {
                throw new AccountNotFoundException(username + " not found with SQL query");
            } else {
                throw new FailedLoginException("Multiple records found for " + username);
            }
        } catch (final DataAccessException e) {
            throw new PreventedException("SQL exception while executing query for " + username, e);
        }
        return createHandlerResult(credential, new SimplePrincipal(username), null);
    }






除此之外,在对Cas 源码进行编译时,也遇到了不少坑,比如绕过License的认证,部分jar包不存在需要手动指定仓库地址,以及如何绕过自带的code style校验!

tips:犯了低级错误,帖子没有备份保存下,发表的时候出错,内容回滚没有回滚全,又重新写了遍,后面申请的可以注意下!!!

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2019-6-24 18:45
抱歉,未能达到申请要求,申请不通过,可以关注论坛官方微信(吾爱破解论坛),等待开放注册通知。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 07:58

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表