CAS自定义加密方式和自定义登录验证

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fancheng614/article/details/84038266

先搭建一个CAS服务:搭建教程

本项目中的自定义加和登录验证中的加密方法使用了shiro,记得加shiro-all-XXX.jar。

源码下载

一、自定义加密

实现PasswordEncoder接口,public String encode(String password)返回加密后的密码。

1、实现PasswordEncoder接口

package org.jasig.cas.web.pass;

import javax.validation.constraints.NotNull;

import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.jasig.cas.authentication.handler.PasswordEncoder;

/**
 * @author 74790
 * 2018年11月13日20:16:47
 * 自定义加密方式
 */
public class MyPassWord implements PasswordEncoder{
	
	@NotNull
	private Integer iterationCount;  //加密次数

	@Override
	public String encode(String password) {
		System.out.println("加密之前的密码:"+password);
		String newpass = getNewPass(password, "salt", "MD5", 1024).toString();
		System.out.println("加密之后的密码:"+newpass);
		return newpass;
	}
	
	//自定义加密方式,返回加密后的密码字符串
	private Object getNewPass(String password,String userName, String encryMode, Integer encryNum){
		Object salt = ByteSource.Util.bytes(userName);
		Object result = new SimpleHash(encryMode, password, salt, encryNum);
		return result;
	}

	public Integer getIterationCount() {
		return iterationCount;
	}

	public void setIterationCount(Integer iterationCount) {
		this.iterationCount = iterationCount;
	}
	
	
}

2、在deployerConfigContext.xml中配置自定义加密方式

    <!-- 自定义加密方式 -->
    <bean id="myPassWord" class="org.jasig.cas.web.pass.MyPassWord">  
	    <property name="iterationCount">
	        <value>1024</value>
	    </property>
	</bean>

3、将默认的认证方式按照下面要求修改,配置数据源可以看本文章头部的CAS服务搭建教程

将<property name="authenticationHandlers">标签下面的

<beanclass="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />

换成:

<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
	<property name="dataSource" ref="dataSource"></property>
	<property name="sql" value="select userpassword from tuser where username=?"></property>
	<property name="passwordEncoder" ref="myPassWord"></property>
</bean> 

这里已经实现了自定义的加密方式,但是这个PasswordEncoder接口里面的public String encode(String password)方法不能传入盐值,如果没有盐值,两个用户一样的密码时,加密后的密码就会一样。所以此处需要盐值加密。可以看下面的自定义登录验证。

二、自定义登录验证

1、继承AbstractJdbcUsernamePasswordAuthenticationHandler类,重写authenticateUsernamePasswordInternal方法。

package com.mfc.handler;

import javax.validation.constraints.NotNull;

import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.handler.AuthenticationException;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.springframework.dao.IncorrectResultSizeDataAccessException;

/**
 * @author 74790
 * 自定义登录方式
 */
public class MyQueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {

	@NotNull
	private String sql;     //查询sql
	@NotNull
	private String encryMode; //加密方式
	@NotNull 
	private Integer encryNum; //加密次数
	
	@Override
	protected boolean authenticateUsernamePasswordInternal(UsernamePasswordCredentials credentials)
			throws AuthenticationException {
		final String username = getPrincipalNameTransformer().transform(credentials.getUsername());
        final String password = credentials.getPassword();
        final String encryptedPassword = getPasswordEncoder1(password, username, this.encryMode, this.encryNum);
        
        try {
        	System.out.println("===页面输入密码加密后:"+encryptedPassword);
            final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
            return dbPassword.equals(encryptedPassword);
        } catch (final IncorrectResultSizeDataAccessException e) {
            // this means the username was not found.
            return false;
        }
	}
	
	
	//自定义加密方式,返回加密后的密码字符串
	private String getPasswordEncoder1(String password,String userName, String encryMode, Integer encryNum){
		Object salt = ByteSource.Util.bytes(userName);
		Object result = new SimpleHash(encryMode, password, salt, encryNum);
		return result.toString();
	}
	
	/**
     * @param sql The sql to set.
     */
    public void setSql(final String sql) {
        this.sql = sql;
    }
    
    public void setEncryMode(final String encryMode) {
    	this.encryMode = encryMode;
    }
    
    public void setEncryNum(final Integer encryNum){
    	this.encryNum = encryNum;
    }
}

2、在deployerConfigContext.xml修改配置

将<property name="authenticationHandlers">标签下面的登录验证方式修改一下,刚导入CAS项目时的验证方式是输入用户名和密码同样的字符串就可以登录成功,即:

<beanclass="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />

修改成自定义的登录验证方式:

<bean class="com.mfc.handler.MyQueryDatabaseAuthenticationHandler">
	<property name="dataSource" ref="dataSource"></property>
	<property name="sql" value="select userpassword from tuser where username=?"></property>
	<property name="encryMode" value="MD5"></property>
    <property name="encryNum" value="1024"></property>
</bean>

到此可以实现自定义登录验证。

猜你喜欢

转载自blog.csdn.net/fancheng614/article/details/84038266