CAS 实现单点登录(SSO)数据库查询认证机制-自定义编码方式(四)


    通过xml配置方式实现数据库查询认证,的确简单但是不够灵活。但是如果登录验证逻辑稍微复杂些,可能通过这种配置方式就不能满足需求了,比如:当用户登录时,需要判断该用户是否绑定了邮箱,如果未绑定,拒绝登录并给出提示信息。 

    遇到类似的情况,就需要使用自定义登录来完成,并且给出的提示信息也需要是自定义的。 

自定义登录验证(默认实现QueryDatabaseAuthenticationHandler

    CAS内置了一些AuthenticationHandler实现类,如下图所示,在cas-server-support-jdbc包中提供了基于jdbc的用户认证类。


CAS 实现单点登录(SSO)数据库查询认证机制-自定义编码方式(四)_第1张图片


   如果需要实现自定义登录,只需要实现org.jasig.cas.authentication.handler.AuthenticationHandler接口即可,当然也可以利用已有的实现,比如创建一个继承自org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler的类,实现方法可以参考org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler类:

   

CAS 实现单点登录(SSO)数据库查询认证机制-自定义编码方式(四)_第2张图片   


修改authenticateUsernamePasswordInternal方法中的代码为自己的认证逻辑即可。

 

操作步骤:

 

1Eclipse中引入cas-server-webapp项目,并在lib下添加两个jar



2,自定义一个类,这个类的内容可以是复制QueryDatabaseAuthenticationHandler

CAS 实现单点登录(SSO)数据库查询认证机制-自定义编码方式(四)_第3张图片


类中的核心方法:

@Override
    protected final boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredentials credentials) throws AuthenticationException {
        //获取前台传递过来的值,用户名和密码
    	final String username = getPrincipalNameTransformer().transform(credentials.getUsername());
        final String password = credentials.getPassword();
        final String encryptedPassword = this.getPasswordEncoder().encode(
            password);
        
        try {
        	/**
        	 * 以下的代码为CAS的数据库认证默认实现,如果想编写自己的实现方式,可以删除一下代码实现自己的登录认证
        	 */        	
        	//sql为配置文件中配置的sql语句   	
        	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;
        }
    }

3 ,根据业务需求编写自己的自定义登录方法,修改如下代码即可

final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
return dbPassword.equals(encryptedPassword);

当然也可以访问进行

http://localhost:8080/cas-server-webapp/login 调试。

4,配置使自定义登录认证生效


				
				
					
					
					
				

CAS 实现单点登录(SSO)数据库查询认证机制-自定义编码方式(四)_第4张图片

完成以上步骤,自定义登录即可实现!


自定义错误提示消息(默认实现IncorrectResultSizeDataAccessException继承自RuntimeException)


CAS AuthenticationException结构如下图,CAS已经内置了一些异常,比如用户名密码错误、未知的用户名错误等。


CAS 实现单点登录(SSO)数据库查询认证机制-自定义编码方式(四)_第5张图片


当用户名输入正确,而密码错误时提示“密码错误”

只需要在自定义的AuthenticationHandler类的验证方法中,验证失败的地方抛出异常即可。


密码错误的异常类:

CAS 实现单点登录(SSO)数据库查询认证机制-自定义编码方式(四)_第6张图片


请注意代码中的CODE私有属性,该属性定义了一个本地化资源文件中的键,通过该键获取本地化资源中对应语言的文字,这里只实现中文错误消息提示,修改WEB-INF/classes/messages_zh_CN.properties文件,添加CODE定义的键值对,如下示例:

error.authentication.credentials.bad.usernameorpassword.password=\u5bc6\u7801\u9519\u8bef


CAS 实现单点登录(SSO)数据库查询认证机制-自定义编码方式(四)_第7张图片


后面的文字是使用jdk自带的native2ascii编码工具:native2ascii转换成utf-8格式。


CAS 实现单点登录(SSO)数据库查询认证机制-自定义编码方式(四)_第8张图片


接下来只需要在自定义的AuthenticationHandler类的验证方法中,验证失败的地方抛出异常即可。

 

自定义AuthenticationHandler示例代码如下:

@Override
    protected final boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredentials credentials) throws AuthenticationException {
        //获取前台传递过来的值,用户名和密码
    	final String username = getPrincipalNameTransformer().transform(credentials.getUsername());
        final String password = credentials.getPassword();
        final String encryptedPassword = this.getPasswordEncoder().encode(
            password);
        
        try {
        	  final String dbPassword = null;
            if (dbPassword == null || dbPassword == "") {
				throw new BadPasswordAuthenticationException();
			}
            return dbPassword.equals(encryptedPassword);
        } catch (final IncorrectResultSizeDataAccessException e) {
            // this means the username was not found.
            return false;
        }

CAS 实现单点登录(SSO)数据库查询认证机制-自定义编码方式(四)_第9张图片 


配置使自定义错误提示生效 同上(配置自定义登录认证)!


效果:

CAS 实现单点登录(SSO)数据库查询认证机制-自定义编码方式(四)_第10张图片


总结:

 

通过以上的学习,我们知道CAS为我们提供了很多便利的扩展功能,它的这种方式也是我们在设计软件时必须要考虑和不断要加强的内容。




你可能感兴趣的:(JAVA,权限框架)