解决多登陆的问题

解决多登陆的问题 下面给出解决方案 (只有spring security的 ssh的太多)

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
 xmlns="http://java.sun.com/xml/ns/javaee" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name> 
   <!-- spring的日志监听。。 -->
 <context-param>
  <param-name>contextConfigLocation</param-name> 
  <param-value>classpath:applicationContext.xml</param-value> 
 </context-param>
 
    <!-- spring的监听 -->
  <listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
  </listener> 
  
   <filter>  
        <filter-name>springSecurityFilterChain</filter-name>  
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>springSecurityFilterChain</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    
    <listener>
     <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> 
  </listener>
    
  <welcome-file-list>
    <welcome-file>login.jsp</welcome-file>
  </welcome-file-list>
</web-app>



//所有的参考实现

<?xml version="1.0" encoding="UTF-8"?>
<beans
 xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:security="http://www.springframework.org/schema/security"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-3.1.xsd
 ">
 
   <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 
   <property name="driverClass" value="com.microsoft.sqlserver.jdbc.SQLServerDriver">
   </property>
   <property name="jdbcUrl" value="jdbc:sqlserver://localhost:1433;databaseName=mydb">
   </property>
   <property name="user" value="sa"></property>
   <property name="password" value="123456"></property> 
    </bean>
  
  <security:http pattern="/**/*.css" security="none"/> 
  <security:http pattern="/login.jsp*" security="none"/>
  <security:http pattern="/admin/login.jsp*" security="none"/>
   
  
  <security:http entry-point-ref="loginUrlEntryPoint" access-decision-manager-ref="myaccessDecisionManager" auto-config="true">  
       
       <!-- 没用但是重要 否者不会执行我们自定义的myaccessDecisionManager-->
       <security:intercept-url pattern="/**" access="ROLE_XXX" /> 
       <security:logout  delete-cookies="true"/>  
       
       <security:remember-me/>
       <!-- 不复制session -->
       <security:session-management session-fixation-protection="none"/>
       
        <security:custom-filter ref="concurrencyFilter" position="CONCURRENT_SESSION_FILTER" />  
        <security:custom-filter ref="loginFilter" before="FORM_LOGIN_FILTER"/> 
        <security:custom-filter ref="adminLoginFilter" after="FORM_LOGIN_FILTER"/>  
        <security:custom-filter ref="logoutFilter" before="LOGOUT_FILTER"/> 
        <security:custom-filter ref="adminLogoutFilter" after="LOGOUT_FILTER"/>  
       
       <!-- 如果第二次登录,阻止,并显示错误信息 -->
        <security:session-management session-authentication-strategy-ref="sas"></security:session-management>
        
 </security:http>
  
  <bean id="loginUrlEntryPoint" class="com.spring.MyLoginUrlEntryPoint"></bean>
   

   
 <!-- 前台用户登录的  begin-->
 <bean id="loginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="sessionAuthenticationStrategy" ref="sas"></property> 
        <property name="authenticationFailureHandler" ref="failureHandler"></property>  
        <property name="authenticationSuccessHandler" ref="successHandler"></property>
        <property name="filterProcessesUrl" value="/j_spring_security_check"></property>
</bean>

 <bean id="failureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
      <property name="defaultFailureUrl" value="/login.jsp"></property>
 </bean>  
 <bean id="successHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
      <property name="alwaysUseDefaultTargetUrl"  value="true"></property>
      <property name="defaultTargetUrl" value="/index.jsp"></property>
 </bean> 

  <!-- end -->
 
 <!-- 后台用户登录的 begin -->
 <bean id="adminLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager"/> 
          <property name="sessionAuthenticationStrategy" ref="sas"></property> 
        <property name="authenticationFailureHandler" ref="adminFailureHandler"></property>  
        <property name="authenticationSuccessHandler" ref="adminSuccessHandler"></property>
        <property name="filterProcessesUrl" value="/admin/j_spring_security_check"></property> 
</bean>

 <bean id="adminFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
      <property name="defaultFailureUrl" value="/admin/login.jsp"></property>
 </bean>  
 <bean id="adminSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
      <property name="alwaysUseDefaultTargetUrl"  value="true"></property>
      <property name="defaultTargetUrl" value="/admin/index.jsp"></property>
 </bean> 
 <!-- end -->
  
 <!-- session管理 begin -->
<bean id="concurrencyFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
      <property name="sessionRegistry" ref="sessionRegistry"></property>
      <property name="expiredUrl" value="/MyJsp.jsp"></property> 
  </bean> 
  <bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
     <constructor-arg name="sessionRegistry" ref="sessionRegistry"></constructor-arg> 
     <!-- 只要单个session -->
     <property name="maximumSessions" value="1"></property> 
 </bean> 
  <bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"></bean>
 <!-- end -->
  
 <!-- login out begin--> 
 <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
    <constructor-arg value="/login.jsp"></constructor-arg>
    <constructor-arg>
        <list>
           <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"></bean>
         </list>
    </constructor-arg>
    <property name="filterProcessesUrl" value="/logout"></property>
 </bean>
 
  <bean id="adminLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
    <constructor-arg value="/admin/login.jsp"></constructor-arg>
    <constructor-arg>
        <list>
           <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"></bean>
         </list>
    </constructor-arg>
    <property name="filterProcessesUrl" value="/admin/logout"></property>
 </bean> 
  <!-- end --> 
  
 
 <!--查询用户和用户权限 begin -->  
  <bean id="myaccessDecisionManager" class="com.spring.MyAccessDecisionManager">
     <property name="dataSource" ref="dataSource"></property>
  </bean> 
 <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider>  
        <!-- 查询用户和对应的权限。。 -->
        <security:jdbc-user-service data-source-ref="dataSource"  
        users-by-username-query="select u.username,u.password,u.status as enabled from users u where u.username=? "  
         authorities-by-username-query="select u.username, r.name as authority from dbo.user_role ur join dbo.users u 
         on u.id=ur.user_id join dbo.roles r on r.id=ur.role_id where u.username = ? "  cache-ref="userCache"/> 
      </security:authentication-provider>
 </security:authentication-manager>
 <!-- end --> 
  
  <!-- 用户缓存 begin -->
 <bean id="userCache" class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
       <property name="cache" ref="userEhCache"></property>
  </bean>    
  <bean id="userEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
      <property name="cacheManager" ref="cacheManager"></property>
      <property name="cacheName" value="userCache"></property>
  </bean> 
  <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"></bean>
  <!-- end -->   
 
  <!-- 消息提示 -->
  <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
        <property name="basename" value="classpath:org/springframework/security/messages_zh_CN" /> 
  </bean>
 

</beans>



附加的连个类

1.MyAccessDecisionManager.java

package com.spring;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.AuthorizationServiceException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.authentication.InsufficientAuthenticationException;
 
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
 

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class MyAccessDecisionManager  implements AccessDecisionManager{

 private  Logger logger = Logger.getLogger(MyAccessDecisionManager.class);
  
 private ComboPooledDataSource  dataSource;  
 public ComboPooledDataSource getDataSource() {
    
  return dataSource;
 }
 public void setDataSource(ComboPooledDataSource dataSource) {
  this.dataSource = dataSource;
 }
   
 @Override
 public void decide(Authentication authentication, Object object,
   Collection<ConfigAttribute> configAttributes) throws AccessDeniedException,
   InsufficientAuthenticationException {
   
  logger.info("当前请求:"+object.toString() );  
  System.out.println("来了。。。。。。。。。");
   Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
   UserDetails userDetails = null;
   List<String> list_role= null;
   //没有当前用户  --》越界访问
   try {
    userDetails =(UserDetails)obj;
  } catch (Exception e) {
    throw new AuthorizationServiceException("认证失败!");
  } 
   Connection con =null;
   PreparedStatement ps  = null;
   ResultSet set  = null; 
   try {
   con= dataSource.getConnection();
    String sql = "select rl.name from resc_role rr join rescs re on rr.resc_id = re.id  join roles rl on rr.role_id = rl.id where re.res_string = ? ";
   //数据库查询对应的
    ps=  con.prepareStatement(sql);  
    ps.setString(1 ,  object.toString().substring( object.toString().indexOf("/")  )  );
    set =  ps.executeQuery();  
    list_role = new ArrayList<String>(); 
    while(set.next()){    
     list_role.add(set.getString("name") );
    } 
  } catch (Exception e) {
   // TODO: handle exception
   e.printStackTrace();
  }finally{
  
    try {
     if(set!=null)set.close();
    } catch (SQLException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    } 
    try {
     if(set!=null) ps.close();
    } catch (SQLException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    } 
    try {
     if(set!=null) con.close();
    } catch (SQLException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }  
  } 
  
  for (String string : list_role) {
   //当前用户角色 
   for( GrantedAuthority g : userDetails.getAuthorities()){
     if( g.getAuthority() .equals(string) ){
      logger.info("您有权限!");
      return; 
     }
    }
  } 
     throw new AccessDeniedException("呵呵!没有权限!");   
 }

 @Override
 public boolean supports(ConfigAttribute arg0) {
  // TODO Auto-generated method stub
  return true;//fan hui true 
 }

 @Override
 public boolean supports(Class<?> arg0) {
  // TODO Auto-generated method stub
  return true;//fanhui false
 }

 
 
}

说明 :这个是传统的jdbc 没有hibernate的 那可以改下 反正要实现权限判断



2.MyLoginUrlEntryPoint.java

package com.spring;

import java.io.IOException;

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

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;

public class MyLoginUrlEntryPoint implements AuthenticationEntryPoint{

 @Override
 public void commence(HttpServletRequest request, HttpServletResponse arg1,
   AuthenticationException arg2) throws IOException, ServletException {
  // TODO Auto-generated method stub
  String targetUrl = null;
        String url = request.getRequestURI();
        if(url.indexOf("admin") != -1){ 
            //未登录而访问后台受控资源时,跳转到后台登录页面 
            request.setAttribute("msg", "你还未登录。。");
         targetUrl = "/admin/login.jsp";
        }else{
            //未登录而访问前台受控资源时,跳转到前台登录页面 
         request.setAttribute("msg", "你还未登录。。");
            targetUrl = "/login.jsp";
        } 
        request.getRequestDispatcher((request.getContextPath() + targetUrl)).forward(request, arg1);
        
 }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值