posts - 14, comments - 22, trackbacks - 0, articles - 4
            BlogJava :: 首頁 ::  :: 聯(lián)系 :: 聚合  :: 管理

          到現(xiàn)在我也沒有弄明白Acegi里面很多的功能,剛剛開始學(xué)的時(shí)候我就已經(jīng)被它那繁瑣的配置震懾住了,不過當(dāng)我動(dòng)起手來一步步實(shí)現(xiàn)的時(shí)候,才發(fā)現(xiàn)其實(shí)它遠(yuǎn)沒有那么難,當(dāng)然隨著學(xué)習(xí)的深入,會(huì)漸漸再發(fā)現(xiàn)這一點(diǎn)吧,現(xiàn)在就讓我們初學(xué)者一切體驗(yàn)Acegi的功能吧!

          還以我傳統(tǒng)的例子為例:
          畢業(yè)設(shè)計(jì)選題系統(tǒng),三種角色:教師,學(xué)生,管理員,我想讓他們的登陸都在一個(gè)界面下自動(dòng)識(shí)別,而無需進(jìn)行身份選擇,登陸后,他們將分別到各自的admin.jsp,stu.jsp,teacher.jsp
          在數(shù)據(jù)庫中的表結(jié)構(gòu)如下(很多屬性略):
          id--- user---password--type---about

          type是用來存儲(chǔ)用戶的類別,分別有a,t,s分別對(duì)應(yīng)三種角色
          about對(duì)應(yīng)的是acegi里所需要的enable,用戶是否可用

          在model里,我們采用了繼承關(guān)系:

          父類user:
          package subject.model;

          public abstract class User extends BaseObject
          {
          ?private Integer id;
          ?private String user;
          ?private String password;
          ?private String name;
          ?private String telphone;

          //set and get method?
          ?
          ?public abstract String getType(); //這個(gè)是用來反映用戶角色的關(guān)鍵函數(shù),在子類實(shí)現(xiàn),從而實(shí)現(xiàn)多態(tài)
          }

          子類的實(shí)現(xiàn):
          ======================
          package subject.model;

          import subject.Constants;

          public class Teacher extends User
          {
          ?private String level;???????? //教師的職稱

          //set and get method

          ?public String getType()
          ?{
          ??return Constants.TEACHER;
          ?}
          }
          ================
          package subject.model;

          import subject.Constants;

          public class Student extends User
          {
          ?private static final long serialVersionUID = 1L;

          ?private SchoolClass schoolClass;???????? //學(xué)生的班級(jí)
          ?private String sn;???????????? //學(xué)生的學(xué)號(hào)

          //set and get method
          ?
          ?public String getType()
          ?{
          ??return Constants.STUDENT;
          ?}
          }
          =================
          package subject.model;

          import subject.Constants;

          public class Admin extends User
          {
          ?private String grade;?????????? //管理員的級(jí)別
          //set and get method

          ?public String getType()
          ?{
          ??return Constants.ADMIN;
          ?}
          }

          對(duì)于三者所共有的屬性在數(shù)據(jù)庫里,都存在一個(gè)字段,而依據(jù)不同的角色擁有不同的含義,學(xué)生的班級(jí)則存放在了about里,只要學(xué)生有班級(jí),他就able,否則就enable了!而管理員和教師則默認(rèn)為1!

          這種是屬于一個(gè)繼承樹存放在一個(gè)表的情況,Hibernate的配置如下:
          <hibernate-mapping>

          ?<class name="subject.model.User" discriminator-value="not null">

          ??<id name="id">
          ???<generator class="increment" />
          ??</id>
          ??
          ??<discriminator column="type" type="character" />
          ??
          ??<property name="user" />
          ??<property name="password" />
          ??<property name="name" />
          ??<property name="telphone" />

          ??<subclass name="subject.model.Admin" discriminator-value="a">
          ???<property name="grade" column="sn" />
          ??</subclass>
          ??
          ??<subclass name="subject.model.Teacher" discriminator-value="t">
          ???<property name="level" column="sn" />
          ??</subclass>
          ??
          ??<subclass name="subject.model.Student" discriminator-value="s">
          ???
          ???<property name="sn" />
          ???
          ???<many-to-one name="schoolClass" class="subject.model.SchoolClass"
          ????column="about" update="false" insert="false" />
          ????
          ??</subclass>

          ?</class>

          </hibernate-mapping>

          =============================================
          上面的這些都是模型的基礎(chǔ),下面再講怎么樣配合Spring和Acegi實(shí)現(xiàn)系統(tǒng)的安全與登陸
          在Spring中Hibernate的配置只介紹不說明:
          <!-- 定義DBCP數(shù)據(jù)源 -->
          ?<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
          ??<property name="driverClassName" value="com.mysql.jdbc.Driver" />
          ??<property name="url" value="jdbc:mysql://localhost/subject?useUnicode=true&amp;characterEncoding=gbk" />
          ??<property name="username" value="root" />
          ??<property name="password" value="" />
          ??<property name="maxActive" value="100" />
          ??<property name="maxIdle" value="30" />
          ??<property name="maxWait" value="1000" />
          ??<property name="defaultAutoCommit" value="true" />
          ??<property name="removeAbandoned" value="true" />
          ??<property name="removeAbandonedTimeout" value="60" />
          ?</bean>

          ?<!-- Hibernate -->
          ?<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
          ??<property name="dataSource" ref="dataSource" />
          ??<property name="mappingResources">
          ???<list>
          ????<value>subject/model/User.hbm.xml</value>
          ???</list>
          ??</property>
          ??<property name="hibernateProperties">
          ???<props>
          ????<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
          ???</props>
          ??</property>
          ?</bean>

          ?<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
          ??<property name="sessionFactory" ref="sessionFactory" />
          ?</bean>

          <!-- Dao對(duì)象 -->
          <bean id="userDao" class="subject.dao.hibernate.UserDaoImpl">
          ??<property name="sessionFactory" ref="sessionFactory" />
          ?</bean>

          <!-- 業(yè)務(wù)邏輯 -->
          ?<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          ??<property name="transactionManager" ref="transactionManager" />
          ??<property name="transactionAttributes">
          ???<props>
          ????<prop key="save*">PROPAGATION_REQUIRED</prop>
          ????<prop key="remove*">PROPAGATION_REQUIRED</prop>
          ????<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
          ???</props>
          ??</property>
          ?</bean>

          <bean id="userManager" parent="txProxyTemplate">
          ??<property name="target">
          ???<bean class="subject.service.impl.UserManagerImpl">
          ????<property name="userDao" ref="userDao" />
          ???</bean>
          ??</property>
          ?</bean>

          <!-- Struts -->
          ?<bean name="/user" class="subject.web.action.UserAction" singleton="false">
          ??<property name="userManager">
          ???<ref bean="userManager" />
          ??</property>
          ?</bean>
          ==================
          上面具體的不用了解,無非就是調(diào)用和數(shù)據(jù)庫的操作,
          下面就要對(duì)Acegi進(jìn)行聲明了:
          我不用Ctrl+c和Ctrl+V的方式對(duì)Acegi進(jìn)行介紹,沒有意義,隨便google就一大堆
          我們想主要在這樣的系統(tǒng)中需要的安全策略都有哪些?
          1.用戶的登陸
          2.防止多個(gè)用戶登陸一個(gè)帳號(hào)
          3.用戶的注銷
          4.防止非法用戶的訪問

          我這個(gè)程序所涉及到的只有這些,下面就進(jìn)行說明:

          在web.xml的聲明:
          <!-- Acegi安全控制 Filter 配置 -->
          ??? <filter>
          ??????? <filter-name>securityFilter</filter-name>
          ??????? <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
          ??????? <init-param>
          ??????????? <param-name>targetClass</param-name>
          ??????????? <param-value>org.acegisecurity.util.FilterChainProxy</param-value>
          ??????? </init-param>
          ??? </filter>
          ???
          ??? <filter-mapping>
          ??????? <filter-name>securityFilter</filter-name>
          ??????? <url-pattern>/*</url-pattern>
          ??? </filter-mapping>

          Acegi通過實(shí)現(xiàn)了Filter接口的FilterToBeanProxy提供一種特殊的使用Servlet Filter的方式,它委托Spring中的Bean -- FilterChainProxy來完成過濾功能,這樣就簡(jiǎn)化了web.xml的配置,并且利用Spring IOC的優(yōu)勢(shì)。FilterChainProxy包含了處理認(rèn)證過程的filter列表,每個(gè)filter都有各自的功能。

          <!-- ======================== FILTER CHAIN ======================= -->
          ?<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,exceptionTranslationFilter,filterInvocationInterceptor
          ???</value>
          ??</property>
          ?</bean>

          大體上先介紹一下:
          httpSessionContextIntegrationFilter:每次request前 HttpSessionContextIntegrationFilter從Session中獲取Authentication對(duì)象,在request完后, 又把Authentication對(duì)象保存到Session中供下次request使用,此filter必須其他Acegi filter前使用,使之能跨越多個(gè)請(qǐng)求。
          logoutFilter:用戶的注銷
          authenticationProcessingFilter:處理登陸請(qǐng)求
          exceptionTranslationFilter:異常轉(zhuǎn)換過濾器
          filterInvocationInterceptor:在訪問前進(jìn)行權(quán)限檢查

          這些就猶如在web.xml聲明一系列的過濾器,不過當(dāng)把他們都聲明在spring中就可以享受Spring給我們帶來的方便了。

          下面就是對(duì)這些過濾器的具體聲明:
          只對(duì)有用的地方進(jìn)行聲明,別的地方幾乎都是默許的
          <!-- ======================== FILTER ======================= -->
          ?<bean id="httpSessionContextIntegrationFilter"
          ??class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />

          ?<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
          ??<constructor-arg value="/index.htm" />???????????? 離開后所轉(zhuǎn)向的位置
          ??<constructor-arg>
          ??????????? <list>
          ??????????????? <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
          ??????????? </list>
          ??????? </constructor-arg>
          ??<property name="filterProcessesUrl" value="/logout.htm" />??????? 定義用戶注銷的地址,
          ?</bean>

          下面的這個(gè)過濾器,我們根據(jù)自己的需求有了自己的實(shí)現(xiàn):

          ?<bean id="authenticationProcessingFilter" class="subject.web.filter.UserAuthenticationProcessingFilter">
          ??<property name="authenticationManager" ref="authenticationManager"/>??下面會(huì)介紹的用來起到認(rèn)證管理的作用
          ??<property name="authenticationFailureUrl" value="/login.htm?error=wrong"/>? 登陸失敗的地址
          ??<property name="defaultTargetUrl" value="/login.htm"/>?????? 登陸成功的地址
          ??<property name="filterProcessesUrl" value="/j_security_check"/>????? 登陸請(qǐng)求的地址
          ??<property name="userManager" ref="userManager"/>??????? 自己添加的屬性,這樣就可以訪問到我們的業(yè)務(wù)邏輯
          ??<property name="exceptionMappings">?? 出現(xiàn)異常所對(duì)應(yīng)的地址
          ??????????? <value>
          ??????????????? org.acegisecurity.AuthenticationException=/login.htm?error=fail???? 登陸失敗??????????????? org.acegisecurity.concurrent.ConcurrentLoginException=/login.htm?error=too??????? 已登陸了
          ??????????? </value>
          ??????? </property>
          ?</bean>
          ?
          ?<bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>

          ?<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
          ??<property name="authenticationEntryPoint">
          ???<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
          ????<property name="loginFormUrl" value="/login.htm?error=please"/>//如果用戶沒登陸就想訪問,先到這里登陸吧
          ????<property name="forceHttps" value="false"/>
          ???</bean>
          ??</property>
          ?</bean>
          ?
          ?<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
          ??<property name="authenticationManager" ref="authenticationManager"/>???????認(rèn)證服務(wù)
          ??<property name="accessDecisionManager">
          ???<bean class="org.acegisecurity.vote.AffirmativeBased">
          ????<property name="allowIfAllAbstainDecisions" value="false"/>
          ????<property name="decisionVoters">
          ?????<list>
          ??????<bean class="org.acegisecurity.vote.RoleVoter">
          ??????????????????? <property name="rolePrefix" value=""/>???????? //這里定義數(shù)據(jù)庫中存放的角色和我們?cè)谶@里聲明的角色間是否需要加個(gè)前綴?我沒加
          ??????????????? </bean>
          ?????</list>
          ????</property>
          ???</bean>
          ??</property>
          ??<property name="objectDefinitionSource">
          ??????????? <value>
          ??????????????? PATTERN_TYPE_APACHE_ANT
          ???????????????
          ??????????????? /admin.htm*=a???????? 這里就是數(shù)據(jù)庫中對(duì)應(yīng)的tyep a
          ??????????????? /student*=s?????????? 由于沒有前綴和數(shù)據(jù)庫里一樣
          ??????????????? /teacher*=t
          ??????????? </value>
          ??????? </property>
          ?</bean>
          ?
          ?<bean id="loggerListener"
          ????????? class="org.acegisecurity.event.authentication.LoggerListener"/>?????? 記錄事件

          下面就要說明我們的認(rèn)證服務(wù)了,其起到的關(guān)鍵作用就是用來保證用戶登陸身份的驗(yàn)證:

          它將驗(yàn)證的功能委托給多個(gè)Provider,并通過遍歷Providers, 以保證獲取不同來源的身份認(rèn)證,若某個(gè)Provider能成功確認(rèn)當(dāng)前用戶的身份,authenticate()方法會(huì)返回一個(gè)完整的包含用戶授權(quán)信息的Authentication對(duì)象,否則會(huì)拋出一個(gè)AuthenticationException。

          先聲明一個(gè)管理器吧,在上面的過濾器中都已經(jīng)用到過了
          <!-- ======================== AUTHENTICATION ======================= -->
          ?<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
          ??<property name="providers">
          ???<list>
          ????<ref local="daoAuthenticationProvider" />???我僅僅用到 從數(shù)據(jù)庫中讀取用戶信息驗(yàn)證身份
          ???</list>
          ??</property>
          ??<property name="sessionController">
          ???<bean id="concurrentSessionController"
          ????class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl">
          ????<property name="maximumSessions">
          ?????<value>1</value>每個(gè)用戶同時(shí)登陸一位
          ????</property>
          ????<property name="sessionRegistry">
          ?????<bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistryImpl" />
          ????</property>
          ????<property name="exceptionIfMaximumExceeded" value="true" />
          ???</bean>
          ??</property>
          ?</bean>
          ?來實(shí)現(xiàn)唯一的一個(gè)Provider,從數(shù)據(jù)庫驗(yàn)證身份
          ?<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
          ??<property name="userDetailsService">
          ???<bean id="jdbcDaoImpl"
          ??????????? class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
          ????????? <property name="dataSource" ref="dataSource"/>
          ????????? <property name="usersByUsernameQuery">
          ????????????? <value>
          ????????????????? select user,password,about from user where user = ???????? 查找用戶的查詢語句,只需要把你數(shù)據(jù)庫中的用戶和密碼以及enable相對(duì)應(yīng)上就行
          ????????????? </value>
          ????????? </property>
          ????????? <property name="authoritiesByUsernameQuery">
          ????????????? <value>
          ????????????????? select user,type from user where user = ??????????? 這里就是把用戶和權(quán)限對(duì)應(yīng)上,在appfuse中用的兩個(gè)表,我都放一個(gè)表里了,所以就用這一個(gè)就行問題的關(guān)鍵是要讓它能找到兩個(gè)字段,構(gòu)成一個(gè)對(duì)象
          ????????????? </value>
          ????????? </property>
          ????? </bean>
          ??</property>
          ??<property name="userCache"> 緩存都這么寫:
          ???<bean class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
          ????<property name="cache">
          ?????<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
          ??????<property name="cacheManager">
          ???????<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
          ??????</property>
          ??????<property name="cacheName" value="userCache"/>
          ?????</bean>
          ????</property>
          ???</bean>
          ??</property>
          ?</bean>

          ==============
          對(duì)于上面登陸請(qǐng)求的處理器我借鑒了springSide,實(shí)現(xiàn)的方法如下:
          package subject.web.filter;

          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import javax.servlet.http.HttpSession;

          import org.acegisecurity.Authentication;
          import org.acegisecurity.context.SecurityContext;
          import org.acegisecurity.context.SecurityContextHolder;
          import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
          import org.acegisecurity.userdetails.UserDetails;

          import subject.Constants;
          import subject.model.User;
          import subject.service.UserManager;

          public class UserAuthenticationProcessingFilter extends
          ??AuthenticationProcessingFilter
          {
          ?private UserManager userManager;

          ?public void setUserManager( UserManager userManager )
          ?{
          ??this.userManager = userManager;
          ?}

          ?protected boolean requiresAuthentication( HttpServletRequest request ,
          ???HttpServletResponse response )
          ?{
          ??boolean requiresAuth = super.requiresAuthentication( request, response );
          ??HttpSession httpSession = null;
          ??try
          ??{
          ???httpSession = request.getSession( false );
          ??}
          ??catch ( IllegalStateException ignored )
          ??{
          ??}
          ??if ( httpSession != null )
          ??{
          ???if ( httpSession.getAttribute( Constants.USER ) == null )
          ???{
          ????if ( !requiresAuth )
          ????{
          ?????SecurityContext sc = SecurityContextHolder.getContext();
          ?????Authentication auth = sc.getAuthentication();
          ?????if ( auth != null
          ???????&& auth.getPrincipal() instanceof UserDetails )
          ?????{
          ??????UserDetails ud = (UserDetails) auth.getPrincipal();//上面聲明的sql無非就是要包裝成這個(gè)對(duì)象
          ??????User user = userManager.getUser( ud.getUsername() );從業(yè)務(wù)邏輯里找到用戶,放到session里
          ??????httpSession.setAttribute( Constants.USER, user );
          ?????}
          ????}
          ???}
          ??}
          ??return requiresAuth;
          ?}
          }

          在看看我的login.htm在登陸成功時(shí)是怎么工作的吧?
          public class UserAction extends BaseAction
          {
          ?private UserManager mgr;

          ?public void setUserManager( UserManager mgr )
          ?{
          ??this.mgr = mgr;
          ?}

          ?public ActionForward login( ActionMapping mapping , ActionForm form ,
          ???HttpServletRequest request , HttpServletResponse response )
          ???throws Exception
          ?{
          ??User user = (User) getSessionObject( request, Constants.USER );
          ??ActionMessages msg = new ActionMessages();
          ??if ( user != null )
          ??{
          ???return new ActionForward(? user.getType() + ".htm", true );成功就去type.htm
          ??}
          ??else
          ??{
          ???String error = getParameter( request, Constants.ERROR );
          ???if ( error != null )對(duì)于不同的錯(cuò)誤,都加以提示
          ???{
          ????if ( error.equalsIgnoreCase( "wrong" ) )
          ?????msg.add( "msg", new ActionMessage( "fail.login.wrong" ) );
          ????else if ( error.equalsIgnoreCase( "too" ) )
          ?????msg.add( "msg", new ActionMessage( "fail.login.too" ) );
          ????else if ( error.equalsIgnoreCase( "fail" ) )
          ?????msg.add( "msg", new ActionMessage( "fail.login.fail" ) );
          ????else
          ?????msg.add( "msg", new ActionMessage( "fail.login.please" ) );
          ???}
          ???else
          ????msg.add( "msg", new ActionMessage( "fail.login.please" ) );
          ??}
          ??saveErrors( request, msg );
          ??return mapping.findForward( "fail" );
          ?}

          }

          當(dāng)然,Acegi需要介紹的東西太多了,我只把我這次認(rèn)為有必要解釋的東西寫在了上面讓大家來參考,作為能google到的東西,比如對(duì)于認(rèn)證的方式還有很多,我就沒有詳細(xì)的介紹,在學(xué)習(xí)Acegi過程中,把它自帶的例子弄清楚很關(guān)鍵,希望大家一起學(xué)習(xí)一起共勉!


          評(píng)論

          # re: Spring+Hibernate+Acegi 的初次體驗(yàn)  回復(fù)  更多評(píng)論   

          2006-08-24 16:29 by 跳跳堂
          如果能擴(kuò)充objectDefinitionSource 介紹就最好了

          # re: Spring+Hibernate+Acegi 的初次體驗(yàn)  回復(fù)  更多評(píng)論   

          2006-08-31 16:51 by wangx
          <property name="usersByUsernameQuery">
          <value>SELECT user_no,user_password FROM SYS_USERS WHERE user_no=?</value>
          </property>

          請(qǐng)問上面acegi配置文件中的SQL語句的查詢條件系統(tǒng)是怎么取得的?

          另外,你的例子的登錄頁面的URL是多少?
          URL中是不是要帶個(gè)/j_acegi_security_check?

          # re: Spring+Hibernate+Acegi 的初次體驗(yàn)  回復(fù)  更多評(píng)論   

          2007-01-01 12:45 by itspy
          大體上先介紹一下:
          httpSessionContextIntegrationFilter:每次request前 HttpSessionContextIntegrationFilter從Session中獲取Authentication對(duì)象,在request完后, 又把Authentication對(duì)象保存到Session中供下次request使用。


          有個(gè)問題我不太明白,如何從Authentication中取出當(dāng)前登錄的用戶名呢,比如要做一個(gè)審計(jì),記錄當(dāng)前用戶的操作,就一定要得到當(dāng)前登錄用戶的名字。

          # re: Spring+Hibernate+Acegi 的初次體驗(yàn)  回復(fù)  更多評(píng)論   

          2007-01-12 11:44 by 刺猬[匿名]
          To itspy:

          Acuthentication中就包含有當(dāng)前登陸用戶的信息,除了用戶信息,還包括當(dāng)前登陸用戶已定義的權(quán)限信息。

          # re: Spring+Hibernate+Acegi 的初次體驗(yàn)  回復(fù)  更多評(píng)論   

          2007-03-16 15:46 by 路過
          靠色,樓主怎能這樣寫?
          User user = (User) getSessionObject( request, Constants.USER );
          ActionMessages msg = new ActionMessages();
          那與其不要Acegi 算了.

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          有事在這里給我留言噢!
          主站蜘蛛池模板: 永济市| 资中县| 神木县| 疏勒县| 卢龙县| 德州市| 琼海市| 绥滨县| 南宁市| 黔东| 海淀区| 嘉荫县| 上虞市| 砀山县| 永泰县| 法库县| 密山市| 特克斯县| 伊金霍洛旗| 盘山县| 汝州市| 鹿泉市| 芜湖市| 铜川市| 揭西县| 容城县| 陕西省| 蒙山县| 桦甸市| 保康县| 高尔夫| 上饶县| 和田市| 苏尼特左旗| 山阳县| 互助| 汽车| 宁河县| 常熟市| 太和县| 新乡市|