java隨記

          堅持就是勝利!

           

          acegi之Active Directory驗證

          客戶要求提供Active Directory登錄驗證.原因是他們公司是在美國的上市公司,要求上市公司的軟件必須提供統一登錄認證.他們想到的解決方案就是Active Directory.呵呵.而我們開發的系統使用的是acegi登錄驗證.嗯,這個,首先想到的就是ldap,沒的想,網上搜吧,資料還不算少.那就配吧,配好了需要測試吧,那就找服務器咧.這公司的域服務器不讓用,那就openldap吧.下好了又一通查資料,openldap總得配是吧.總算給配好了,不容易呀.就拿到客戶環境去試吧,嘿嘿,客戶說了不可能給我們管理員帳號密碼,只有用戶登錄帳號跟密碼,傻了.acegi的ldap驗證就要這個啊.
          回來繼續搞咧,咱也沒辦法不是?

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

          <beans>

           <bean id="filterChainProxy"
            class="org.acegisecurity.util.FilterChainProxy">
            <property name="filterInvocationDefinitionSource">
             <value>
              CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
              PATTERN_TYPE_APACHE_ANT
              /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
             </value>
            </property>
           </bean>

           <bean id="authenticationManager"
            class="org.acegisecurity.providers.ProviderManager">
            <property name="providers">
             <list>
               <!-- 自己寫一個認證提供者類 我加的-->
                 <ref local="activeDirectoryProvider" />
              <ref local="daoAuthenticationProvider" />
              <ref local="anonymousAuthenticationProvider" />
              <ref local="rememberMeAuthenticationProvider" />
             </list>
            </property>
           
           </bean>
           
           <!-- 認證提供者類的配置 我加的-->
           <bean id="activeDirectoryProvider"
            class="net.omw.utility.AcegiTestProvider">
            <property name="url" value="ldap://172.108.4.2"> </property>
            <property name="port" value="389"> </property>
          <!--domain取值域服務器的配置-->
            <property name="domain" value="SUNTECH"> </property>
            <!--    <property name="sessionController" ref="concurrentSessionController"></property> -->
           </bean>


           <bean id="jdbcDaoImpl"
            class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
            <property name="dataSource">
             <ref bean="coreDataSource" />
            </property>
            <property name="usersByUsernameQuery">
             <value>
              select C_OPER_ID,C_PASSWORD,1 from Operator where
              C_OPER_ID = ? and C_STATUS='Y'
             </value>
            </property>
            <property name="authoritiesByUsernameQuery">
             <value>
              select C_OPER_ID,C_PASSWORD,1 from Operator where
              C_OPER_ID = ? and C_STATUS='Y'
             </value>
            </property>
           </bean>

           <bean id="passwordEncoder"
            class="org.acegisecurity.providers.encoding.Md5PasswordEncoder">
            <property name="encodeHashAsBase64" value="false"></property>
           </bean>

           <bean id="daoAuthenticationProvider"
            class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
            <property name="userDetailsService">
             <ref local="jdbcDaoImpl" />
            </property>
            <!-- <property name="userCache">
             <ref local="userCache" />
            </property>-->
            <property name="passwordEncoder">
             <ref local="passwordEncoder" />
            </property>
           </bean>

           <bean id="cacheManager"
            class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />

           <bean id="userCacheBackend"
            class="org.springframework.cache.ehcache.EhCacheFactoryBean">
            <property name="cacheManager">
             <ref local="cacheManager" />
            </property>
            <property name="cacheName">
             <value>userCache</value>
            </property>
           </bean>

           <bean id="userCache"
            class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
            <property name="cache">
             <ref local="userCacheBackend" />
            </property>
           </bean>

           <bean id="loggerListener"
            class="org.acegisecurity.event.authentication.LoggerListener" />

           <bean id="anonymousProcessingFilter"
            class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
            <property name="key">
             <value>foobar</value>
            </property>
            <property name="userAttribute">
             <value>anonymousUser,ROLE_ANONYMOUS</value>
            </property>
           </bean>

           <bean id="anonymousAuthenticationProvider"
            class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
            <property name="key">
             <value>foobar</value>
            </property>
           </bean>

           <bean id="httpSessionContextIntegrationFilter"
            class="org.acegisecurity.context.HttpSessionContextIntegrationFilter">
           </bean>

           <bean id="rememberMeProcessingFilter"
            class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
            <property name="authenticationManager">
             <ref local="authenticationManager" />
            </property>
            <property name="rememberMeServices">
             <ref local="rememberMeServices" />
            </property>
           </bean>

           <bean id="rememberMeServices"
            class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
            <property name="userDetailsService">
             <ref local="jdbcDaoImpl" />
            </property>
            <property name="key">
             <value>springRocks</value>
            </property>
           </bean>

           <bean id="rememberMeAuthenticationProvider"
            class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
            <property name="key">
             <value>springRocks</value>
            </property>
           </bean>

           <bean id="logoutFilter"
            class="org.acegisecurity.ui.logout.LogoutFilter">
            <constructor-arg value="/login/loginPage.jsp" />
            <constructor-arg>
             <list>
              <ref bean="rememberMeServices" />
              <bean
               class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler" />
             </list>
            </constructor-arg>
           </bean>

           <bean id="securityContextHolderAwareRequestFilter"
            class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter" />

           <bean id="exceptionTranslationFilter"
            class="org.acegisecurity.ui.ExceptionTranslationFilter">
            <property name="authenticationEntryPoint">
             <ref local="authenticationProcessingFilterEntryPoint" />
            </property>
            <property name="accessDeniedHandler">
             <bean
              class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
              <property name="errorPage"
               value="/common/AccessDenied.jsp" />
             </bean>
            </property>
           </bean>

           <bean id="authenticationProcessingFilter"
            class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
            <property name="authenticationManager">
             <ref bean="authenticationManager" />
            </property>
            <property name="authenticationFailureUrl">
             <value>/login/Login.action?login_msg=1</value>
            </property>
            <property name="defaultTargetUrl">
             <value>/login/Login.action?login_msg=0</value>
            </property>
            <property name="filterProcessesUrl">
             <value>/j_acegi_security_check</value>
            </property>
            <property name="rememberMeServices">
             <ref local="rememberMeServices" />
            </property>
           </bean>

           <bean id="authenticationProcessingFilterEntryPoint"
            class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
            <property name="loginFormUrl">
             <value>/login/loginPage.jsp</value>
            </property>
            <property name="forceHttps">
             <value>false</value>
            </property>
            <property name="serverSideRedirect" value="false"></property>
           </bean>

           <bean id="httpRequestAccessDecisionManager"
            class="org.acegisecurity.vote.AffirmativeBased">
            <property name="allowIfAllAbstainDecisions">
             <value>false</value>
            </property>
            <property name="decisionVoters">
             <list>
              <ref bean="roleVoter" />
             </list>
            </property>
           </bean>

           <bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter" />

           <bean id="filterInvocationInterceptor"
            class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
            <property name="validateConfigAttributes" value="true" />
            <property name="authenticationManager">
             <ref bean="authenticationManager" />
            </property>
            <property name="accessDecisionManager">
             <ref local="httpRequestAccessDecisionManager" />
            </property>
            <property name="objectDefinitionSource"
             ref="rdbmsFilterInvocationDefinitionSource" />

           </bean>

           <bean id="rdbmsFilterInvocationDefinitionSource"
            class="net.omw.utility.acegi.interceptor.RdbmsFilterInvocationDefinitionSource">
            <property name="dataSource">
             <ref bean="coreDataSource" />
            </property>
            <property name="webresdbCache" ref="webresCacheBackend" />
           </bean>

           <bean id="webresCacheBackend"
            class="org.springframework.cache.ehcache.EhCacheFactoryBean">
            <property name="cacheManager">
             <ref local="cacheManager" />
            </property>
            <property name="cacheName">
             <value>webresdbCache</value>
            </property>
           </bean>

           <!-- 
            <bean id="switchUserProcessingFilter" class="org.acegisecurity.ui.switchuser.SwitchUserProcessingFilter">
            <property name="userDetailsService" ref="jdbcDaoImpl" />
            <property name="switchUserUrl"><value>/j_acegi_switch_user</value></property>
            <property name="exitUserUrl"><value>/j_acegi_exit_user</value></property>
            <property name="targetUrl"><value>/secure/index.htm</value></property>
            </bean>   
           -->

           <bean id="authenticationLoggerListener"
            class="org.acegisecurity.event.authentication.LoggerListener" />

           <bean id="authorizationLoggerListener"
            class="org.acegisecurity.event.authorization.LoggerListener" />
          </beans>

          AcegiTestProvider類從AbstractUserDetailsAuthenticationProvider繼承,有兩個方法必須實現
          additionalAuthenticationChecks()和retrieveUser()方法.retrieveUser返回UserDetails,UserDetails的實現可以包裝更多的信息.但在本例中幾乎沒什么太大的作用,僅僅是為了返回而重新定義了一個類
          真正的驗證邏輯發生在additionalAuthenticationChecks方法里拋出異常就算用戶登錄失敗

          package net.omw.utility;

          import java.util.Properties;

          import javax.naming.Context;
          import javax.naming.NamingException;
          import javax.naming.ldap.InitialLdapContext;

          import org.acegisecurity.AuthenticationException;
          import org.acegisecurity.GrantedAuthority;
          import org.acegisecurity.GrantedAuthorityImpl;
          import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
          import org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider;
          import org.acegisecurity.userdetails.UserDetails;
          import org.acegisecurity.userdetails.UsernameNotFoundException;

          public class AcegiTestProvider extends
            AbstractUserDetailsAuthenticationProvider {
             private String url;
             private String port;
             private String domain;
           
           /*
            * 驗證邏輯
            * @see org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider#additionalAuthenticationChecks(org.acegisecurity.userdetails.UserDetails, org.acegisecurity.providers.UsernamePasswordAuthenticationToken)
            *
            */
           @Override
           protected void additionalAuthenticationChecks(UserDetails arg0,
             UsernamePasswordAuthenticationToken arg1)
             throws AuthenticationException {
            // TODO Auto-generated method stub

            String URL = url+":"+port;

                  String username=domain+"\\"+arg0.getUsername();
            String password = arg0.getPassword();


            Properties env = new Properties();  
            env.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.jndi.ldap.LdapCtxFactory");
            env.put(Context.PROVIDER_URL,"ldap://172.18.0.42:389");
            env.put(Context.SECURITY_AUTHENTICATION,"simple");
            env.put(Context.SECURITY_PRINCIPAL,
            username);
            env.put(Context.SECURITY_CREDENTIALS,password);
            env.put("com.sun.jndi.ldap.connect.pool","true");
            env.put("java.naming.referral","follow"); 
            try{
              new InitialLdapContext(env,null);
            }
            catch(NamingException e){
             // Authentication failed
             throw new UsernameNotFoundException(e.toString());
             
            }


           }

           @Override
           protected UserDetails retrieveUser(String arg0,
             UsernamePasswordAuthenticationToken arg1)
             throws AuthenticationException {
            // TODO Auto-generated method stub
            GrantedAuthority[] authorities = new GrantedAuthority[1];
            authorities[0] = new GrantedAuthorityImpl("ROLE_SUPERVISOR");
            String password = (String) arg1.getCredentials();  
                  /*String username = "";
            Object obj = arg1.getPrincipal();
            if (obj instanceof UserDetails) {
             username = ((UserDetails) obj).getUsername();
            } else {
             username = obj.toString();
            }
                  */
            UserDetails userDetails = new UserDetailsImpl(authorities, password,
              arg1.getName(), true, true, true, true);
            //if(true)
              //  throw new AuthenticationCredentialsNotFoundException("t");
            
            return userDetails;
           }

           public String getUrl() {
            return url;
           }

           public void setUrl(String url) {
            this.url = url;
           }

           public String getPort() {
            return port;
           }

           public void setPort(String port) {
            this.port = port;
           }

           public String getDomain() {
            return domain;
           }

           public void setDomain(String domain) {
            this.domain = domain;
           }

           
          }

          package net.omw.utility;

          import org.acegisecurity.GrantedAuthority;
          import org.acegisecurity.userdetails.UserDetails;

          public class UserDetailsImpl implements UserDetails {
           GrantedAuthority[] authorities;

           String password;

           String username;
           boolean isAccountNonExpired;

           boolean isAccountNonLocked;

           boolean isCredentialsNonExpired;

           boolean isEnabled;

           UserDetailsImpl(GrantedAuthority[] authorities, String password,
                      String username, boolean isAccountNonExpired,
                      boolean isCredentialsNonExpired, boolean isEnabled,
                      boolean isAccountNonLocked) {
                  this.authorities = authorities;
                  this.isAccountNonExpired = isAccountNonExpired;
                  this.isAccountNonLocked = isAccountNonLocked;
                  this.isEnabled = isEnabled;
                  this.password = password;
                  this.username = username;
                  this.isCredentialsNonExpired = isCredentialsNonExpired;

              }

           
           @Override
           public GrantedAuthority[] getAuthorities() {
            // TODO Auto-generated method stub
            return authorities;
           }

           @Override
           public String getPassword() {
            // TODO Auto-generated method stub
            return password;
           }

           @Override
           public String getUsername() {
            // TODO Auto-generated method stub
            return username;
           }

           @Override
           public boolean isAccountNonExpired() {
            // TODO Auto-generated method stub
            return isAccountNonExpired;
           }

           @Override
           public boolean isAccountNonLocked() {
            // TODO Auto-generated method stub
            return isAccountNonLocked;
           }

           @Override
           public boolean isCredentialsNonExpired() {
            // TODO Auto-generated method stub
            return isCredentialsNonExpired;
           }

           @Override
           public boolean isEnabled() {
            // TODO Auto-generated method stub
            return isEnabled;
           }

          }





           

          posted on 2009-10-30 17:48 傻 瓜 閱讀(1552) 評論(0)  編輯  收藏 所屬分類: 雜項

          導航

          統計

          常用鏈接

          留言簿(7)

          我參與的團隊

          隨筆分類

          隨筆檔案

          文章分類

          友情鏈接

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 林芝县| 贵定县| 安塞县| 临漳县| 织金县| 廉江市| 榆树市| 鄂伦春自治旗| 彰化县| 探索| 西和县| 延川县| 银川市| 泸定县| 新乡市| 孝义市| 砚山县| 荣成市| 大兴区| 庆云县| 苏尼特左旗| 关岭| 十堰市| 湟中县| 奉化市| 曲靖市| 陈巴尔虎旗| 嵩明县| 延庆县| 库伦旗| 民县| 田东县| 嘉峪关市| 顺平县| 化德县| 广灵县| 合作市| 神木县| 景洪市| 麻城市| 明水县|