spring security 3 实践

来源:互联网 发布:备案域名30出售 编辑:程序博客网 时间:2024/05/04 22:47
project环境struts2+spring 3.0.5+morphia1.0+spring security 3.0.5+mongodb

官网上spring-securityjar包和spring包不在一起。而且现在和以前下载jar包的方式也不一样了,spring还是很超前的,不过没有以前下载方式更傻瓜,简单直接。所以跟着spring走,不怕不在技术发展的前列。

尽管现阶段spring最新版本已到4.0.3,稳定版本也在3.2.8,但是由于原工程框架用的是3.0.5,主要是为了框架的稳定兼容性,所以本人还是选择了security的3.0.5。

spring-security用到的基础jar包包括:

Ø spring-security-acl-3.0.5.RELEASE.jar

Ø spring-security-config-3.0.5.RELEASE.jar

Ø spring-security-core-3.0.5.RELEASE.jar

Ø spring-security-taglibs-3.0.5.RELEASE.jar

Ø spring-security-web-3.0.5.RELEASE.jar

当然还有其他的 security包,就不要加入了,太重。

工程目录结构如下:



        基于mongo 的spring security实现和mysql 基本一致,大家不要被名字吓坏了。Spring 其实已经提供了对mongodb 的MongoTemplate,但是基于研发过程中可能存在的问题我们采用了最早的mongo框架morphia。其实个人我更愿意用mongo 原生API,项目完成后也会跟进Spring Data Mongo。

        我将spring的配置文件分为了三个,springsecurity核心配置application-security.xml,spirng核心配置application-public.xml,spring bean管理配置application-service.xml。application-public.xml配置了spring 对mongodb配置文件的读取,morphiafactory,Mongoliafactory的配置。

       本项目用Mongodb 作为数据库,就不展示数据库脚本了,把mongo当做关系型数据库使用了。

  •  user(用户表):

      

  • user_roles(用户-角色对应表):

      

  • roles(角色表):

        

  • roles_authorities(角色-权限对应表):

      

  • authorities(权限表):

      

  • authorities_resources(权限-资源对应表):

       

  • page_resources(页面资源表):

      



     

        在这里只讲解spring Security的核心配置文件applicationContext-security.xml。该配置文件主要配置了springsecurity相关配置,包括登录验证,URL过滤,过滤器设置,SESSION控制等。

(由于CSDN无法提交URL 这把XML中URL都删除了)

配置文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<beans <!— 此处URL删除了,spring security schema声明--><!—spring security 命名空间引入-->>

     <description>SpringSecurity安全配置</description>
     <!—auto-config=true时,spring会自动为用户注册login form, BASIC authentication, anonymous authentication, logout services,remember-me and servlet-   api-integration.  如果不配置默认为 false,这时需要你自己定义验证登录点,即AuthenticationEntryPoint,添加标签entry-point-ref=’’;       use-expressions="true" 启用表达式  匹配路径默认为ant 表达式匹配-->
      <security:http auto-config="true" use-expressions="true" >
         
        <!-- 不要过滤图片等静态资源,其中**代表可以跨越(1或多个)目录,*任意字符,不可以跨越目录。  webcontent下CSS,JS,JPG,PGN等资源不准过滤  -->
        <security:intercept-url pattern="/**/*.css" filters="none" />
        <security:intercept-url pattern="/**/*.png" filters="none" />
        <security:intercept-url pattern="/**/*.jpg" filters="none" />
        <security:intercept-url pattern="/**/*.gif" filters="none" />
        <security:intercept-url pattern="/**/*.ico" filters="none" />
        <security:intercept-url pattern="/**/*.js" filters="none" />
        
        <!-- 登录界面不要过滤 -->
        <security:intercept-url pattern="/securityuse/login.jsp" filters="none" />
        <security:intercept-url pattern="/securityuse/sessionTimeout.jsp" filters="none"/>
        
        <!-- 登录 成功/失败 页面设置-->
        <security:form-login login-page="/securityuse/login.jsp" default-target-url="/index.jsp"
             authentication-failure-url="/securityuse/login.jsp?error=1" />
            
        <!-- 尝试访问没有权限的页面时跳转的页面 -->   
        <security:access-denied-handler error-page="/securityuse/common/403.html"/>
        
        <!-- 检测失效的sessionId,超时时定位到另外一个URL   expired-url="/securityuse/common/403.html"-->
          <security:session-management invalid-session-url="/securityuse/sessionTimeout.jsp" >
          <!-- 防止多人同时登录一个号,error-if-maximum-exceeded =true,不允许后来登录的用户登录,如果为false第二个登录的同一用户会把第一位用户踢掉-->
              <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="false" />
          </security:session-management>
        
        
        <!-- 安全退出 -->
        <security:logout logout-success-url="/securityuse/login.jsp" />
        
        <!-- 自定义过滤器 spring security 过滤器讲解 -->
        <security:custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
     </security:http>
    
          <!--  一个自定义的filter,必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性。  -->
     <bean id="myFilter" class="com.xxxxxx.ct.its.soc.security.MyFilterSecurityInterceptor">
         <!-- 项目实现的用户查询服务,将用户信息查询出来 -->
         <property name="authenticationManager" ref="myAuthenticationManager" />
        <!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 -->
         <property name="accessDecisionManager" ref="myAccessDecisionManagerBean" />
         <!-- 将所有的资源和权限对应关系建立起来 -->
         <property name="securityMetadataSource" ref="mySecurityMetadataSource" />
     </bean>
   
    <!-- 验证配置 , 认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 -->
     <security:authentication-manager alias="myAuthenticationManager" >
        <security:authentication-provider user-service-ref="userDetailsService">
            <!-- 先MD加密,然后用用户名作为盐值加密-->
            <!-- spirng security密码加密: MD5(password{username}) -->
            <security:password-encoder ref="passwordEncoder">
                <security:salt-source user-property="username"/>
            </security:password-encoder>
        </security:authentication-provider>
    </security:authentication-manager>
    
    <!-- 项目实现的用户查询服务,将用户信息查询出来  -->
    <bean id="userDetailsService" class="com.xxxxxx.ct.its.soc.security.MyUserDetailService">
        <property name="userCache" ref="userCache" />
        <!-- <property name="dataSource" ref="dataStore" /> -->
    </bean>
    
    <!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源     -->
    <bean id="myAccessDecisionManagerBean" class="com.xxxxxx.ct.its.soc.security.MyAccessDecisionManager"></bean>
    
    <!-- 很重要,此类在初始化时,应该取到所有资源及其对应角色的定义。 -->
     <!-- 资源源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色访问 -->
    <bean id="mySecurityMetadataSource"
        class="com.xxxxxx.ct.its.soc.security.MyInvocationSecurityMetadataSourceService">
    </bean>
    
    <!-- 定义国际化 -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
          <property name="basename"
              value="classpath:org/springframework/security/messages_zh_CN"/>
     </bean>
 </beans>


Spring security在web.xml 中的配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app >
<display-name>cnmsoc</display-name>

<!-- 配置Spring配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<!—此处引入sprig public,security,service配置文件--> <param-value>/WEB-INF/classes/applicationContext-public.xml,/WEB-INF/classes/applicationContext-service.xml,/WEB-INF/classes/applicationContext-security.xml</param-value>
</context-param>

<!-- 引入LOG4J配置-->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>

<!-- 使用ContextLoaderListener初始化Spring容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

<!-- 定义Struts 2的核心Filter -->
<filter>
<filter-name>struts2</filter-name>
<!-- <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> -->
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<!-- 默认后缀为 action的请求经过STRUTS处理 -->
<init-param>
<param-name>struts.action.extension</param-name>
<param-value>action</param-value>
</init-param>
</filter>

<!-- 让Struts 2的核心Filter拦截所有请求,所有的请求多要经过STRUTS 过滤-->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- spring securit 配置 start-->

<!-- 使用Spring中的过滤器解决在请求和应答中的乱码问题通用utf-8,如果是中文乱码可改为gbk start -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 使用Spring中的过滤器解决在请求和应答中的乱码问题通用utf-8,如果是中文乱码可改为gbk end -->

<!-- Spring Secutiry3.0.5的过滤器链配置 start -->

<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>

<!-- Spring Secutiry3.0.5的过滤器链配置 end -->

<session-config>
<session-timeout>20</session-timeout>
</session-config>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>

<!-- Spring刷新Interceptor防止内存泄漏 -->
<listener>
<listener-class>
org.springframework.web.util.IntrospectorCleanupListener
</listener-class>
</listener>

</web-app>

        我们自定的这个SercurityFilter类要继承AbstractSecurityInterceptor 接口和Filter类(负责传递一系列的Filter),因为我们是从数据库中获取权限验证的数据,所以还要重写FilterInvocationSecurityMetadataSource 接口,AccessDecisionManager 接口,UserDetailsService 接口,只要重写了这3个接口,然后再spring配置文件中做相应的配置,项目启动启动后,我们进行资源请求,就自动会去执行我们重定义的类进行权限判断。

MyFilterSecurityInterceptor 代码:

package com.xxxxxx.ct.its.soc.security;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import org.springframework.security.access.SecurityMetadataSource;import org.springframework.security.access.intercept.AbstractSecurityInterceptor;import org.springframework.security.access.intercept.InterceptorStatusToken;import org.springframework.security.web.FilterInvocation;import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;/** * 该过滤器的主要作用就是通过spring著名的IoC生成securityMetadataSource。 * securityMetadataSource相当于本包中自定义的MyInvocationSecurityMetadataSourceService。 * 该MyInvocationSecurityMetadataSourceService的作用提从数据库提取权限和资源,装配到HashMap中, * 供Spring Security使用,用于权限校验。 * @author ss  * */public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptorimplements Filter {private FilterInvocationSecurityMetadataSource securityMetadataSource;@Overridepublic Class<? extends Object> getSecureObjectClass() {// TODO Auto-generated method stubreturn FilterInvocation.class;}public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {return this.securityMetadataSource;}public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {this.securityMetadataSource = securityMetadataSource;}@Overridepublic SecurityMetadataSource obtainSecurityMetadataSource() {// TODO Auto-generated method stubreturn this.securityMetadataSource;}public void destroy() {// TODO Auto-generated method stub}public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {// TODO Auto-generated method stubFilterInvocation fi = new FilterInvocation(request, response, chain);invoke(fi);}private void invoke(FilterInvocation fi) throws IOException,ServletException {// TODO Auto-generated method stubInterceptorStatusToken token = super.beforeInvocation(fi);try {fi.getChain().doFilter(fi.getRequest(), fi.getResponse());} finally {super.afterInvocation(token, null);}}public void init(FilterConfig arg0) throws ServletException {// TODO Auto-generated method stub}}

MyAccessDecisionManager代码:

package com.xxxxxx.ct.its.soc.security;import java.util.Collection;import java.util.Iterator;import org.apache.log4j.Logger;import org.springframework.security.access.AccessDecisionManager;import org.springframework.security.access.AccessDeniedException;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;/** * 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 * @author ss * */public class MyAccessDecisionManager implements AccessDecisionManager{Logger logger = Logger.getLogger(MyAccessDecisionManager.class);//authentication 用户登录传递的参数,  configAttributes已做好的权限配置数据 数据库或者配置文件public void decide(Authentication authentication, Object object,Collection<ConfigAttribute> configAttributes) throws AccessDeniedException,InsufficientAuthenticationException {// TODO Auto-generated method stubif(configAttributes == null){            return ;        }Iterator<ConfigAttribute> ite=configAttributes.iterator();while(ite.hasNext()){            ConfigAttribute ca=ite.next();            String needRole=((SecurityConfig)ca).getAttribute();            for(GrantedAuthority ga:authentication.getAuthorities()){            //ga 为用户所被赋予的权限。 needRole 为访问相应的资源应该具有的权限。            logger.debug("访问当前资源应该具有的权限="+needRole.trim()+"用户的访问的权限="+ga.getAuthority().trim());                if(needRole.trim().equals(ga.getAuthority().trim())){  //ga is user's role.                    return ;                }            }}throw new AccessDeniedException("no right");}public boolean supports(ConfigAttribute attribute) {// TODO Auto-generated method stubreturn true;}public boolean supports(Class<?> clazz) {// TODO Auto-generated method stubreturn true;}}

MyInvocationSecurityMetadataSourceService代码:

package com.xxxxxx.ct.its.soc.security;import java.net.UnknownHostException;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import org.apache.log4j.Logger;import org.springframework.security.access.ConfigAttribute;import org.springframework.security.access.SecurityConfig;import org.springframework.security.web.FilterInvocation;import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;import org.springframework.security.web.util.AntUrlPathMatcher;import org.springframework.security.web.util.UrlMatcher;import com.google.code.morphia.Datastore;import com.google.code.morphia.Morphia;import com.mongodb.Mongo;import com.xxxxxx.ct.its.soc.morphia.model.Authorities;import com.xxxxxx.ct.its.soc.morphia.model.AuthoritiesResources;import com.xxxxxx.ct.its.soc.morphia.model.PageResources;import com.xxxxxx.ct.its.soc.util.ParseProperties;/** * 最核心的地方,就是提供某个资源对应的权限定义,即getAttributes方法返回的结果。 此类在初始化时,应该取到所有资源及其对应角色的定义。 *  * @author ss */public class MyInvocationSecurityMetadataSourceService implementsFilterInvocationSecurityMetadataSource{Logger logger = Logger.getLogger(MyInvocationSecurityMetadataSourceService.class);private UrlMatcher urlMatcher = new AntUrlPathMatcher();private static Map<String, Collection<ConfigAttribute>> resourceMap = null;public MyInvocationSecurityMetadataSourceService() throws UnknownHostException {loadResourceDefine();}//着重说明:由于spring security 的机制是在项目启动时会把所有角色-权限加载到内存中,但是此时morphia  还没有生成实例,造成无法通过service调用DAO,所以此处是用morphiaAPI直接查询的private void loadResourceDefine() throws UnknownHostException {// TODO Auto-generated method stub//原始morpiha查询数据String mongip = ParseProperties.getRelativePropertyValues("database.properties", "mongo.db.host");String mymongip = mongip.split(":")[0];int port =Integer.parseInt(mongip.split(":")[1]);String dbname = ParseProperties.getRelativePropertyValues("database.properties", "mongo.db.databaseName");Mongo mongo = new Mongo(mymongip, port);String userName = ParseProperties.getRelativePropertyValues("database.properties", "mongo.db.databaseUserName");char[] password = ParseProperties.getRelativePropertyValues("database.properties", "mongo.db.databasePassword").toCharArray();Morphia morphia = new Morphia();Datastore ds = morphia.createDatastore(mongo, dbname,userName,password);//Datastore ds = morphia.createDatastore(mongo, dbname);List<String> query = new ArrayList<String>();//morphia查询List<Authorities> authoritiesList= ds.find(Authorities.class).asList();for (Authorities authorities : authoritiesList) {logger.info("权限名字 有  Authority_name:"+authorities.getAuthority_name());query.add(authorities.getAuthority_name());}resourceMap = new LinkedHashMap<String, Collection<ConfigAttribute>>();for (String auth : query) {ConfigAttribute ca = new SecurityConfig(auth);//获取该权限对应的资源的所有链接//get authority_id from authorities by authority_nameList<String> queryResources = new ArrayList<String>();String authority_id=ds.find(Authorities.class, "authority_name =", auth).get().getAuthority_id();//get resource_id from authorities_resources by authority_id resource_idList<AuthoritiesResources> authoritiesResourcesList=ds.find(AuthoritiesResources.class, "authority_id =", authority_id).asList();for (AuthoritiesResources authoritiesResources : authoritiesResourcesList) {//get resouce_string from resources by resouce_idString resource_string=ds.find(PageResources.class, "resource_id =", authoritiesResources.getResource_id()).get().getResource_string();logger.info("权限ID 有  Authority_ID:"+authority_id+"///对应全新资源名字:"+resource_string);queryResources.add(resource_string);}for (String res : queryResources) {String url = res;if (resourceMap.containsKey(url)) {Collection<ConfigAttribute> value = resourceMap.get(url);value.add(ca);resourceMap.put(url, value);}else { Collection<ConfigAttribute> atts  = new ArrayList<ConfigAttribute>(); atts.add(ca); resourceMap.put(url, atts);}}}}public Collection<ConfigAttribute> getAllConfigAttributes() {// TODO Auto-generated method stubreturn null;}public Collection<ConfigAttribute> getAttributes(Object object)throws IllegalArgumentException {//object 是一个URL,被用户请求的url。String url = ((FilterInvocation) object).getRequestUrl();//请求的链接如果带问号 就分割开int firstQuestionMarkIndex = url.indexOf("?");        if (firstQuestionMarkIndex != -1) {            url = url.substring(0, firstQuestionMarkIndex);        }Iterator<String> ite = resourceMap.keySet().iterator();while (ite.hasNext()) {String resURL = ite.next();//着重说明:本人在这里栽了大跟头,pathMatchesUrl方法中两个参数,第一个是用户已有权限的URL,另一个是用户访问URL,千万不要颠倒,我当时就是颠倒了位置,这么了两天,差点重写匹配URL代码。boolean matcheOk = urlMatcher.pathMatchesUrl(resURL, url);logger.info("请求URL:"+url+"//匹配URL"+resURL+"///匹配成功与否:"+matcheOk);if (matcheOk) {return resourceMap.get(resURL);}}//着重说明:spring security 对于未在资源表中的资源以及资源表中存在但是没有权限占用的资源,默认任何用户都可以访问.//此处给予这些资源设置默认权限占用,防止登录用户访问. Collection<ConfigAttribute> returnCollection = new ArrayList<ConfigAttribute>();returnCollection.add(new SecurityConfig("ROLE_NO_USER")); return returnCollection;//return null;}public boolean supports(Class<?> clazz) {// TODO Auto-generated method stubreturn true;}}

MyUserDetailService代码:

package com.xxxxxx.ct.its.soc.security;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.HashSet;import java.util.LinkedHashSet;import java.util.List;import java.util.Map;import java.util.Set;import javax.annotation.Resource;import javax.sql.DataSource;import org.apache.commons.lang.StringUtils;import org.apache.log4j.Logger;import org.springframework.dao.DataAccessException;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.GrantedAuthorityImpl;import org.springframework.security.core.userdetails.User;import org.springframework.security.core.userdetails.UserCache;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import org.springframework.stereotype.Service;import com.opensymphony.xwork2.ActionContext;import com.xxxxxx.ct.its.soc.morphia.model.Roles;import com.xxxxxx.ct.its.soc.morphia.model.UserSoc;import com.xxxxxx.ct.its.soc.security.service.IPubUsersService;/** * 用户登录初始化校验 * @author ss * */@Servicepublic class MyUserDetailService  implements UserDetailsService{Logger logger = Logger.getLogger(MyUserDetailService.class);@Resource private IPubUsersService pubUsersService;private UserCache userCache;private DataSource dataSource;public UserDetails loadUserByUsername(String username)throws UsernameNotFoundException,DataAccessException{// TODO Auto-generated method stubCollection<GrantedAuthority> auths=new ArrayList<GrantedAuthority>();Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();//authSet.add(new GrantedAuthorityImpl(res.getName()));//取得用户的权限 List<String> auth=pubUsersService.findAuthByUserName(username); //获取用户权限描述 String authority_desc = pubUsersService.findAuthDescByUserName(username); for(int i =0;i<auth.size();i++) { logger.debug("登录用户: "+username+" 用户权限包括 "+auth.get(i)); authSet.add(new GrantedAuthorityImpl(auth.get(i))); }  auths = authSet;String password=null;String userid = null;//取得用户的密码UserSoc usesoc = new UserSoc();usesoc=pubUsersService.findUserSocByname(username);userid=usesoc.getUser_id();password=usesoc.getUser_password();String user_location = pubUsersService.findUserRolesByUserId(userid);Roles roles = new Roles();roles = pubUsersService.findRolesByUserId(userid);//String rolesId = roles.getRole_id();//可以返回province device 的ID 也可以返回中文String provinceIdRole=roles.getProvinceid();String devicetypeIdRole=roles.getDevicetype();//查询省中文名,role  中省可能有是","分割的String[] provinceIdArray = StringUtils.split(provinceIdRole, ",");Collection<String> piaCol = new LinkedHashSet<String>();for (String provinceId : provinceIdArray) {piaCol.add(pubUsersService.findResourceById(provinceId,"province"));}String provincename=StringUtils.join(piaCol, ",");//设备中文名查询String[] devicetypeIdArray = StringUtils.split(devicetypeIdRole, ",");Collection<String> diaCol = new LinkedHashSet<String>();for (String devicetypeId : devicetypeIdArray) {diaCol.add(pubUsersService.findResourceById(devicetypeId,"device_type"));}String devicetypeName=StringUtils.join(diaCol, ",");//查询资源列表String resourceIdArray= pubUsersService.findResourcesIdByUserName(roles.getRole_id());//此处可以把用户登录后相关数据写到SESSION中,用于其他功能使用Map<String, Object> sessionmap = new HashMap<String, Object>();sessionmap.put("usernamesession", username);sessionmap.put("userid", userid);sessionmap.put("provinceid", provinceIdRole);sessionmap.put("devicetypeid", devicetypeIdRole);//资源列表sessionmap.put("resourceArray",resourceIdArray );//操作日志会用到sessionmap.put("provincename", provincename);sessionmap.put("devicetypeName", devicetypeName);sessionmap.put("authority_desc", authority_desc);sessionmap.put("user_location", user_location);sessionmap.put("role_id", roles.getRole_id());logger.debug("登录用户名为:"+username+"//登录用户ID:"+userid+"//登录省份ID:"+provinceIdRole+"//登录设备ID:"+devicetypeIdRole+"//登录省份名称:"+provincename+"//登录设备名称:"+devicetypeName+"//权限:"+authority_desc);boolean enables = true;boolean accountNonExpired = true;boolean credentialsNonExpired = true;boolean accountNonLocked = true;//封装成spring security User类User userdetails = new User(username,password,enables,accountNonExpired,credentialsNonExpired,accountNonLocked,auths);logger.debug("当前登录用户名:密码="+username+":"+password);//用户登录时操作一次即可,登出后销毁ActionContext ctx = ActionContext.getContext();ctx.getSession().putAll(sessionmap);return userdetails;}public UserCache getUserCache() {return this.userCache;}public void setUserCache(UserCache userCache) {this.userCache = userCache;}public DataSource getDataSource() {return dataSource;}public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}}

登录页面login.jsp代码:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP 'login.jsp' starting page</title>    <meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page">  </head>  <body onload='document.f.j_username.focus();'><p><font color='red'>Your login attempt was not successful, try again.<br/><br/>Reason: Bad credentials</font></p><h3>Login with Username and Password</h3><form name='f' action='/XXXX/j_spring_security_check' method='POST'>  <table>     <tr><td>User:</td><td><input type='text' name='j_username' value="admin" ></td></tr>     <tr><td>Password:</td><td><input type='password' name='j_password' value="admin"/></td></tr>     <tr><td colspan='2'><input name="submit" type="submit"/></td></tr>     <tr><td colspan='2'><input name="reset" type="reset"/></td></tr>   </table> </form></body></html>

0 0