cas在windows下集成AD域

许久没写blog了,本人作为“猿”唯独缺一个“恒”字,前不久公司新项目需求实现cas单点登陆集成AD域,虽然实现过程曲折,但感觉很有意思,情不自禁记录之。主要功能实现以下2点:
1.加入域的计算机登陆实现免登陆进入系统
2.未加入域的计算机可以在登陆界面输入域用户登陆系统

准备

1.cas服务端使用的是cas-server-3.5.2,下载地址:http://developer.jasig.org/cas/
2.cas客户端使用的是cas-client-3.2.1
3.cas集成AD域所需jar包:jcifs-1.3.18.jar,jcifs-ext-0.9.4.jar;下载地址:http://developer.jasig.org/repo/content/groups/m2-legacy/org/samba/
4.集成环境为windows;本文的重点是cas集成ad,cas部署环境在此不再赘叙,此次集成主要参考官方标准文档:https://wiki.jasig.org/display/CASUM/SPNEGO


集成部署

  • cas服务端修改
    1.修改login-webflow.xml,在CAS目录下的WEB-INF文件夹下,在此配置文件中加入以下两个标签。
 <action-state id="startAuthenticate">
      <evaluate expression="negociateSpnego" />
      <transition on="success" to="spnego" />
    </action-state>

    <action-state id="spnego">
      <evaluate expression="spnego" />
      <transition on="success" to="sendTicketGrantingTicket" />
      <transition on="error" to="viewLoginForm" />
    </action-state>
2,修改login-webflow.xml,将以下3个标签属性中的“viewLoginForm”修改为“startAuthenticate”。
<action-state id="passwordPolicyCheck">
        <evaluate expression="passwordPolicyAction" />
        <transition on="showWarning" to="passwordServiceCheck" />
        <transition on="success" to="sendTicketGrantingTicket" />
        <!-- <transition on="error" to="viewLoginForm" /> -->
        <transition on="error" to="startAuthenticate" />
    </action-state>
    <action-state id="generateLoginTicket">
        <evaluate expression="generateLoginTicketAction.generate(flowRequestContext)" />
        <!-- <transition on="generated" to="viewLoginForm" /> -->
        <transition on="generated" to="startAuthenticate" />
    </action-state>
<global-transitions>
        <!-- CAS-1023 This one is simple - redirects to a login page (same as renew) when 'ssoEnabled' flag is unchecked
             instead of showing an intermediate unauthorized view with a link to login page -->
        <!-- <transition to="viewLoginForm" on-exception="org.jasig.cas.services.UnauthorizedSsoServiceException"/> -->
        <transition to="startAuthenticate" on-exception="org.jasig.cas.services.UnauthorizedSsoServiceException"/>
        <transition to="viewServiceErrorView" on-exception="org.springframework.webflow.execution.repository.NoSuchFlowExecutionException" />
        <transition to="viewServiceErrorView" on-exception="org.jasig.cas.services.UnauthorizedServiceException" />
    </global-transitions>
3.修改CAS的cas-servlet.xml配置文件
cas-servlet.xml在CAS目录下的WEB-INF文件夹下,在cas-servlet.xml文件加入如下图所示的两个标签
<bean id="negociateSpnego" class="org.jasig.cas.support.spnego.web.flow.SpnegoNegociateCredentialsAction" /> 
<bean id="spnego" class="org.jasig.cas.support.spnego.web.flow.SpnegoCredentialsAction">
    <property name="centralAuthenticationService" ref="centralAuthenticationService"/>
</bean>
4.修改CAS的deployConfigContextxml配置文件
deployerConfigContext.xml在CAS目录下的WEB-INF文件夹下,修改该文件bean标签“authenticationManager”的两个属性“credentialsToPrincipalResolvers”“authenticationHandlers”。
首先在“credentialsToPrincipalResolvers”属性的list标签中加入一个bean标签:
<bean class="org.jasig.cas.support.spnego.authentication.principal.SpnegoCredentialsToPrincipalResolver" />

然后在“authenticationHandlers”属性list标签中也加入一个bean标签:

<!--自定义的验证bean实现功能点2.未加入域的计算机可以在登陆界面输入域用户登陆系统-->
<bean class="org.jasig.cas.util.PwdAndUserTest"/>
<!--jcifs验证-->
<bean class="org.jasig.cas.support.spnego.authentication.handler.support.JCIFSSpnegoAuthenticationHandler">
    <property name="authentication">
         <bean class="jcifs.spnego.Authentication" />
    </property>
    <property name="principalWithDomainName" value="false" />
    <property name="NTLMallowed" value="true"/>
</bean>
  • 源码修改
    下载JCIFS源码,CAS的分支SPNEGO的源码;JCIFS版本使用的jcifs-1.3.18.jar;CAS使用的cas-server-3.5.2-release;
    按照以下步骤修改完源码后,替换原jar中对应的class文件。
    1.修改JCIFS框架的Config类
    jcifs.Config.java
    原代码:filename = System.getProperty(“jcifs.properties”);
    修改后:filename = “jcifs.properties”所在的路径地址。可以通过Java方法获取工程路径实现。
    jcifs.properties文件是不存在的,需要自己创建。
    文件内容:
jcifs.http.domainController=AD域IP地址
jcifs.smb.client.username=AD域管理员用户名
jcifs.smb.client.password=AD域管理员密码
jcifs.util.loglevel=2
jcifs.http.domainname=AD域名
jcifs.http.port=AD域默认端口号
2.修改CAS-spnego框架的SpnegoNegociateCredentialsAction类

org.jasig.cas.support.spnego.web.flow.SpnegoNegociateCredentialsAction.java
原代码:private boolean ntlm = false;
修改后:private boolean ntlm = true;

3.修改CAS-spnego框架的SpnegoCredentialsAction类

org.jasig.cas.support.spnego.web.flow.SpnegoCredentialsAction
原代码:private boolean ntlm = false;
修改后:private boolean ntlm = true;

最后将修改后的源码打成jar包。

  • 部署jar包
    把以下jar包复制到\WEB-INF\lib目录下,
    cas-server-support-spnego-3.4.2.jar
    jcifs-1.3.18.jar
    jcifs-ext-0.9.4.jar
    附:PwdAndUserTest.java单独验证实现功能点2
/*
 * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
 * distributed with this file and available online at
 * http://www.ja-sig.org/products/cas/overview/license/
 */
package org.jasig.cas.util;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.springframework.util.StringUtils;

/**
 * Simple test implementation of a AuthenticationHandler that returns true if the username and password match. This
 * class should never be enabled in a production environment and is only designed to facilitate unit testing and load
 * testing.
 * 
 * @author Scott Battaglia
 * @version $Revision: 19492 $ $Date: 2009-12-09 08:16:08 -0500 (Wed, 09 Dec 2009) $
 * @since 3.0
 */
public final class PwdAndUserTest extends AbstractUsernamePasswordAuthenticationHandler
{

    public PwdAndUserTest()
    {
        log.warn(this.getClass().getName()
            + " is only to be used in a testing environment.  NEVER enable this in a production environment.");
    }

    public boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredentials credentials)
    {
        final String username = credentials.getUsername();
        final String password = credentials.getPassword();
        System.out.println(username + "<==========>" + password);
        if (StringUtils.hasText(username) && StringUtils.hasText(password))
        {
            if (CheckADUser(username, password))
            {
                log.debug("User [" + username + "] was successfully authenticated.");
                return true;
            }
        }

        log.debug("User [" + username + "] failed authentication");

        return false;
    }

    private boolean CheckADUser(String username, String password)
    {
        String host = getProperties("jcifs.properties", "jcifs.http.domainController"); // AD服务器IP
        String port = getProperties("jcifs.properties", "jcifs.http.port");// 端口
        String user = getProperties("jcifs.properties", "jcifs.http.domainname") + "\\" + username;// 这里有两种格式,domain\User或邮箱的后缀名,建议用domain\User这种格式
        String url = new String("ldap://" + host + ":" + port);
        Hashtable env = new Hashtable();
        DirContext ctx;
        env.put(Context.SECURITY_AUTHENTICATION, "simple");// 一种模式,不用管,就这么写就可以了
        env.put(Context.SECURITY_PRINCIPAL, user);
        env.put(Context.SECURITY_CREDENTIALS, password);
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, url);
        try
        {
            ctx = new InitialDirContext(env);
            ctx.close();
            return true; // 验证成功返回true
        }
        catch (NamingException err)
        {
            return false;// 验证失败返回false
        }
    }

    // 读取配置文件
    public String getProperties(String name, String key)
    {
        PropertiesUtil p = new PropertiesUtil(name);
        return p.readValue(key);
    }
}

注意:
1.ie设置,工具-》Internet选项-》安全-》Internet-》自定义级别-》用户验证-》选为自动使用“当前用户名和密码登陆”。
加入域的计算机也可以通过AD域的组策略统一设置此设置。
2.win7免登陆后台报错:修改win7客户机HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\LMCompatibilityLevel 为1,此方法太low,可以通过修改AD域服务器的组策略-》网络安全:LAN管理器身份验证级别。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值