spring security 登录、权限管理配置

news/2024/7/3 2:14:25

登录流程

1)容器启动(MySecurityMetadataSource:loadResourceDefine加载系统资源与权限列表)
 2)用户发出请求
 3)过滤器拦截(MySecurityFilter:doFilter)
 4)取得请求资源所需权限(MySecurityMetadataSource:getAttributes)
 5)匹配用户拥有权限和请求权限(MyAccessDecisionManager:decide),如果用户没有相应的权限,

     执行第6步,否则执行第7步。
 6)登录
 7)验证并授权(MyUserDetailServiceImpl:loadUserByUsername)


1、web.xml中加入过滤器

[html] view plain copy
print ?
  1. <!-- SpringSecurity 核心过滤器配置 -->  
  2. <filter>  
  3.     <filter-name>springSecurityFilterChain</filter-name>  
  4.     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  5. </filter>  
  6. <filter-mapping>  
  7.     <filter-name>springSecurityFilterChain</filter-name>  
  8.     <url-pattern>/*</url-pattern>  
  9. </filter-mapping>  
<!-- SpringSecurity 核心过滤器配置 -->
<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>


2、新建spring-security.xml文件

[html] view plain copy
print ?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans:beans xmlns="http://www.springframework.org/schema/security"  
  3.     xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.     http://www.springframework.org/schema/beans/spring-beans.xsd  
  6.     http://www.springframework.org/schema/security  
  7.     http://www.springframework.org/schema/security/spring-security.xsd">  
  8.   
  9.     <!-- entry-point-ref 配置自定义登录 -->  
  10.     <http use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint">  
  11.           
  12.         <!-- 登出配置 -->  
  13.         <logout logout-url="/j_spring_security_logout" logout-success-url="/login" />  
  14.   
  15.         <access-denied-handler error-page="/noPower" />  
  16.           
  17.         <!-- 过滤不被拦截的请求 -->  
  18.         <intercept-url pattern="/login*" access="permitAll" />  
  19.         <intercept-url pattern="/resources/**" access="permitAll" />  
  20.           
  21.         <!-- 只有权限才能访问的请求 -->  
  22.         <intercept-url pattern="/admin/**" access="isAuthenticated()" />  
  23.   
  24.         <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" />  
  25.         <custom-filter ref="securityFilter" before="FILTER_SECURITY_INTERCEPTOR" />  
  26.   
  27.     </http>  
  28.   
  29.     <beans:bean id="loginFilter"  
  30.         class="cn.com.abel.test.service.security.MyUsernamePasswordAuthenticationFilter">  
  31.           
  32.         <!-- 登录提交处理 -->  
  33.         <beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property>  
  34.           
  35.         <!-- 登录成功跳转 -->  
  36.         <beans:property name="authenticationSuccessHandler"  
  37.             ref="loginLogAuthenticationSuccessHandler"></beans:property>  
  38.           
  39.         <!-- 设置登录失败的网址 -->  
  40.         <beans:property name="authenticationFailureHandler"  
  41.             ref="simpleUrlAuthenticationFailureHandler"></beans:property>  
  42.           
  43.         <!-- 用户拥有权限 -->     
  44.         <beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property>  
  45.     </beans:bean>  
  46.   
  47.     <beans:bean id="loginLogAuthenticationSuccessHandler"  
  48.         class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">  
  49.         <beans:property name="defaultTargetUrl" value="/admin/index"></beans:property>  
  50.     </beans:bean>  
  51.     <beans:bean id="simpleUrlAuthenticationFailureHandler"  
  52.         class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">  
  53.         <beans:property name="defaultFailureUrl" value="/login"></beans:property>  
  54.     </beans:bean>  
  55.   
  56.     <authentication-manager alias="myAuthenticationManager">  
  57.         <authentication-provider user-service-ref="myUserDetailServiceImpl">  
  58.             <password-encoder ref="encoder" />  
  59.         </authentication-provider>  
  60.     </authentication-manager>  
  61.   
  62.     <beans:bean id="myUserDetailServiceImpl"  
  63.         class="cn.com.abel.test.service.security.AdminUserDetailServiceImpl">  
  64.     </beans:bean>  
  65.   
  66.     <beans:bean id="authenticationProcessingFilterEntryPoint"  
  67.         class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">  
  68.         <beans:property name="loginFormUrl" value="/login"></beans:property>  
  69.     </beans:bean>  
  70.   
  71.     <!-- 认证过滤器 -->  
  72.     <beans:bean id="securityFilter"  
  73.         class="cn.com.abel.test.service.security.MySecurityFilter">  
  74.         <!-- 用户拥有的角色 -->  
  75.         <beans:property name="authenticationManager" ref="myAuthenticationManager" />  
  76.         <!-- 用户是否拥有所请求资源的权限 -->  
  77.         <beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />  
  78.         <!-- 资源与角色的对应关系 -->  
  79.         <beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />  
  80.         <!-- <beans:property name="rejectPublicInvocations" value="true"/> -->  
  81.   
  82.     </beans:bean>  
  83.       
  84.     <beans:bean id="myAccessDecisionManager" class="myAccessDecisionManager"></beans:bean>  
  85.       
  86.     <beans:bean id="mySecurityMetadataSource"  
  87.         class="cn.com.abel.test.service.security.MySecurityMetadataSource">  
  88.         <beans:constructor-arg>  
  89.             <beans:ref bean="resourceService" />  
  90.         </beans:constructor-arg>  
  91.     </beans:bean>  
  92.   
  93.     <beans:bean id="encoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"></beans:bean>  
  94.     
  95. </beans:beans>  
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security.xsd">

    <!-- entry-point-ref 配置自定义登录 -->
    <http use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint">
        
        <!-- 登出配置 -->
        <logout logout-url="/j_spring_security_logout" logout-success-url="/login" />

        <access-denied-handler error-page="/noPower" />
        
        <!-- 过滤不被拦截的请求 -->
        <intercept-url pattern="/login*" access="permitAll" />
        <intercept-url pattern="/resources/**" access="permitAll" />
        
        <!-- 只有权限才能访问的请求 -->
        <intercept-url pattern="/admin/**" access="isAuthenticated()" />

        <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" />
        <custom-filter ref="securityFilter" before="FILTER_SECURITY_INTERCEPTOR" />

    </http>

    <beans:bean id="loginFilter"
        class="cn.com.abel.test.service.security.MyUsernamePasswordAuthenticationFilter">
        
        <!-- 登录提交处理 -->
        <beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property>
        
        <!-- 登录成功跳转 -->
        <beans:property name="authenticationSuccessHandler"
            ref="loginLogAuthenticationSuccessHandler"></beans:property>
        
        <!-- 设置登录失败的网址 -->
        <beans:property name="authenticationFailureHandler"
            ref="simpleUrlAuthenticationFailureHandler"></beans:property>
        
        <!-- 用户拥有权限 -->   
        <beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property>
    </beans:bean>

    <beans:bean id="loginLogAuthenticationSuccessHandler"
        class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
        <beans:property name="defaultTargetUrl" value="/admin/index"></beans:property>
    </beans:bean>
    <beans:bean id="simpleUrlAuthenticationFailureHandler"
        class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
        <beans:property name="defaultFailureUrl" value="/login"></beans:property>
    </beans:bean>

    <authentication-manager alias="myAuthenticationManager">
        <authentication-provider user-service-ref="myUserDetailServiceImpl">
            <password-encoder ref="encoder" />
        </authentication-provider>
    </authentication-manager>

    <beans:bean id="myUserDetailServiceImpl"
        class="cn.com.abel.test.service.security.AdminUserDetailServiceImpl">
    </beans:bean>

    <beans:bean id="authenticationProcessingFilterEntryPoint"
        class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
        <beans:property name="loginFormUrl" value="/login"></beans:property>
    </beans:bean>

    <!-- 认证过滤器 -->
    <beans:bean id="securityFilter"
        class="cn.com.abel.test.service.security.MySecurityFilter">
        <!-- 用户拥有的角色 -->
        <beans:property name="authenticationManager" ref="myAuthenticationManager" />
        <!-- 用户是否拥有所请求资源的权限 -->
        <beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
        <!-- 资源与角色的对应关系 -->
        <beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
        <!-- <beans:property name="rejectPublicInvocations" value="true"/> -->

    </beans:bean>
    
    <beans:bean id="myAccessDecisionManager" class="myAccessDecisionManager"></beans:bean>
    
    <beans:bean id="mySecurityMetadataSource"
        class="cn.com.abel.test.service.security.MySecurityMetadataSource">
        <beans:constructor-arg>
            <beans:ref bean="resourceService" />
        </beans:constructor-arg>
    </beans:bean>

    <beans:bean id="encoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"></beans:bean>
  
</beans:beans>


3、MyUsernamePasswordAuthenticationFilter.java

[java] view plain copy
print ?
  1. package cn.com.abel.test.service.security;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.http.HttpServletResponse;  
  5.   
  6. import org.springframework.security.authentication.AuthenticationServiceException;  
  7. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;  
  8. import org.springframework.security.core.Authentication;  
  9. import org.springframework.security.core.AuthenticationException;  
  10. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;  
  11.   
  12. public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{  
  13.   
  14.     @Override  
  15.     public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {  
  16.   
  17.         if (!request.getMethod().equals("POST")) {  
  18.             throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());  
  19.         }  
  20.   
  21.         String username = obtainUsername(request);  
  22.         String password = obtainPassword(request);  
  23.   
  24.         if (username == null) {  
  25.             username = "";  
  26.         }  
  27.   
  28.         if (password == null) {  
  29.             password = "";  
  30.         }  
  31.   
  32.         username = username.trim();  
  33.   
  34.         UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);  
  35.   
  36.         // Allow subclasses to set the "details" property  
  37.         setDetails(request, authRequest);  
  38.   
  39. //      //登录验证码,如需要开启把下面注释去掉则可  
  40. //      String authCode = StringUtils.defaultString(request.getParameter("authCode"));  
  41. //      if(!AdwImageCaptchaServlet.validateResponse(request, authCode)){  
  42. //          throw new AuthenticationServiceException("validCode.auth.fail");  
  43. //      }  
  44.   
  45.         return this.getAuthenticationManager().authenticate(authRequest);  
  46.     }  
  47. }  
package cn.com.abel.test.service.security;

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

import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }

        String username = obtainUsername(request);
        String password = obtainPassword(request);

        if (username == null) {
            username = "";
        }

        if (password == null) {
            password = "";
        }

        username = username.trim();

        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);

        // Allow subclasses to set the "details" property
        setDetails(request, authRequest);

//      //登录验证码,如需要开启把下面注释去掉则可
//      String authCode = StringUtils.defaultString(request.getParameter("authCode"));
//      if(!AdwImageCaptchaServlet.validateResponse(request, authCode)){
//          throw new AuthenticationServiceException("validCode.auth.fail");
//      }

        return this.getAuthenticationManager().authenticate(authRequest);
    }
}

4、MySecurityFilter.java

[java] view plain copy
print ?
  1. package cn.com.abel.test.service.security;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.Filter;  
  6. import javax.servlet.FilterChain;  
  7. import javax.servlet.FilterConfig;  
  8. import javax.servlet.ServletException;  
  9. import javax.servlet.ServletRequest;  
  10. import javax.servlet.ServletResponse;  
  11.   
  12. import org.springframework.security.access.SecurityMetadataSource;  
  13. import org.springframework.security.access.intercept.AbstractSecurityInterceptor;  
  14. import org.springframework.security.access.intercept.InterceptorStatusToken;  
  15. import org.springframework.security.web.FilterInvocation;  
  16. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;  
  17.   
  18. public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter {  
  19.     //与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应,  
  20.     //其他的两个组件,已经在AbstractSecurityInterceptor定义  
  21.     private FilterInvocationSecurityMetadataSource securityMetadataSource;  
  22.   
  23.     @Override  
  24.     public SecurityMetadataSource obtainSecurityMetadataSource() {  
  25.         return this.securityMetadataSource;  
  26.     }  
  27.   
  28.     public void doFilter(ServletRequest request, ServletResponse response,  
  29.             FilterChain chain) throws IOException, ServletException {  
  30.         FilterInvocation fi = new FilterInvocation(request, response, chain);  
  31.         invoke(fi);  
  32.     }  
  33.       
  34.     private void invoke(FilterInvocation fi) throws IOException, ServletException {  
  35.         // object为FilterInvocation对象  
  36.         //1.获取请求资源的权限  
  37.         //执行Collection<ConfigAttribute> attributes = SecurityMetadataSource.getAttributes(object);  
  38.         //2.是否拥有权限  
  39.         //获取安全主体,可以强制转换为UserDetails的实例  
  40.         //1) UserDetails  
  41.         // Authentication authenticated = authenticateIfRequired();  
  42.         //this.accessDecisionManager.decide(authenticated, object, attributes);  
  43.         //用户拥有的权限  
  44.         //2) GrantedAuthority  
  45.         //Collection<GrantedAuthority> authenticated.getAuthorities()  
  46.         //System.out.println("用户发送请求! ");  
  47.         InterceptorStatusToken token = null;  
  48.           
  49.         token = super.beforeInvocation(fi);  
  50.           
  51.         try {  
  52.             fi.getChain().doFilter(fi.getRequest(), fi.getResponse());  
  53.         } finally {  
  54.             super.afterInvocation(token, null);  
  55.         }  
  56.     }  
  57.   
  58.     public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {  
  59.         return securityMetadataSource;  
  60.     }  
  61.   
  62.     public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {  
  63.         this.securityMetadataSource = securityMetadataSource;  
  64.     }  
  65.       
  66.     public void init(FilterConfig arg0) throws ServletException {  
  67.         // TODO Auto-generated method stub  
  68.     }  
  69.       
  70.     public void destroy() {  
  71.         // TODO Auto-generated method stub  
  72.           
  73.     }  
  74.   
  75.     @Override  
  76.     public Class<? extends Object> getSecureObjectClass() {  
  77.         //下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误  
  78.         return FilterInvocation.class;  
  79.     }  
  80. }  
package cn.com.abel.test.service.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;

public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter {
    //与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应,
    //其他的两个组件,已经在AbstractSecurityInterceptor定义
    private FilterInvocationSecurityMetadataSource securityMetadataSource;

    @Override
    public SecurityMetadataSource obtainSecurityMetadataSource() {
        return this.securityMetadataSource;
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        FilterInvocation fi = new FilterInvocation(request, response, chain);
        invoke(fi);
    }
    
    private void invoke(FilterInvocation fi) throws IOException, ServletException {
        // object为FilterInvocation对象
        //1.获取请求资源的权限
        //执行Collection<ConfigAttribute> attributes = SecurityMetadataSource.getAttributes(object);
        //2.是否拥有权限
        //获取安全主体,可以强制转换为UserDetails的实例
        //1) UserDetails
        // Authentication authenticated = authenticateIfRequired();
        //this.accessDecisionManager.decide(authenticated, object, attributes);
        //用户拥有的权限
        //2) GrantedAuthority
        //Collection<GrantedAuthority> authenticated.getAuthorities()
        //System.out.println("用户发送请求! ");
        InterceptorStatusToken token = null;
        
        token = super.beforeInvocation(fi);
        
        try {
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        } finally {
            super.afterInvocation(token, null);
        }
    }

    public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
        return securityMetadataSource;
    }

    public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
        this.securityMetadataSource = securityMetadataSource;
    }
    
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
    }
    
    public void destroy() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public Class<? extends Object> getSecureObjectClass() {
        //下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误
        return FilterInvocation.class;
    }
}

5、AdminUserDetailServiceImpl.java

[java] view plain copy
print ?
  1. package cn.com.abel.test.service.security;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.List;  
  5. import java.util.Set;  
  6.   
  7. import org.springframework.beans.factory.annotation.Autowired;  
  8. import org.springframework.security.core.GrantedAuthority;  
  9. import org.springframework.security.core.authority.SimpleGrantedAuthority;  
  10. import org.springframework.security.core.userdetails.UserDetails;  
  11. import org.springframework.security.core.userdetails.UserDetailsService;  
  12. import org.springframework.security.core.userdetails.UsernameNotFoundException;  
  13.   
  14. import cn.com.abel.test.model.RoleModel;  
  15. import cn.com.abel.test.model.MemberModel;  
  16. import cn.com.abel.test.service.RoleService;  
  17. import cn.com.abel.test.service.MemberService;  
  18.   
  19. public class AdminUserDetailServiceImpl implements UserDetailsService {  
  20.     @Autowired  
  21.     private MemberService memberService;  
  22.     @Autowired  
  23.     RoleService roleService;  
  24.    
  25.     //登录验证  
  26.     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {  
  27.           
  28.        
  29.         MemberModel member = memberService.getUserDetailsByUserName(username);  
  30.           
  31.         if(member==null){  
  32.             throw new UsernameNotFoundException("member "+username +" not found.");  
  33.         }  
  34.         Set<GrantedAuthority> grantedAuths = obtionGrantedAuthorities(member);  
  35.   
  36.                 //封装成spring security的user  
  37.                 User userdetail = new User(user.getUserName(), user.getPassword(),  
  38.                 true// 账号状态 0 表示停用 1表示启用  
  39.                 truetruetrue, grantedAuths // 用户的权限  
  40.                 );  
  41.                 return userdetail;  
  42.     }  
  43.       
  44.     //取得用户的权限  
  45.     private Set<GrantedAuthority> obtionGrantedAuthorities(MemberModel member) {  
  46.           
  47.         Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();  
  48.           
  49.         List<RoleModel> roles = roleService.getRoleByUser(member)<span style="font-family:Arial, Helvetica, sans-serif;">;</span>  
  50.         if(roles!=null){  
  51.             for(RoleModel role : roles) {  
  52.                 authSet.add(new SimpleGrantedAuthority(role.getRoleCode().trim()));  
  53.             }  
  54.         }  
  55.    
  56.         return authSet;  
  57.     }  
  58.       
  59. }  
package cn.com.abel.test.service.security;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import cn.com.abel.test.model.RoleModel;
import cn.com.abel.test.model.MemberModel;
import cn.com.abel.test.service.RoleService;
import cn.com.abel.test.service.MemberService;

public class AdminUserDetailServiceImpl implements UserDetailsService {
    @Autowired
    private MemberService memberService;
    @Autowired
    RoleService roleService;
 
    //登录验证
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        
     
        MemberModel member = memberService.getUserDetailsByUserName(username);
        
        if(member==null){
            throw new UsernameNotFoundException("member "+username +" not found.");
        }
        Set<GrantedAuthority> grantedAuths = obtionGrantedAuthorities(member);

                //封装成spring security的user
                User userdetail = new User(user.getUserName(), user.getPassword(),
                true, // 账号状态 0 表示停用 1表示启用
                true, true, true, grantedAuths // 用户的权限
                );
                return userdetail;
    }
    
    //取得用户的权限
    private Set<GrantedAuthority> obtionGrantedAuthorities(MemberModel member) {
        
        Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();
        
        List<RoleModel> roles = roleService.getRoleByUser(member)<span style="font-family:Arial, Helvetica, sans-serif;">;</span>
        if(roles!=null){
            for(RoleModel role : roles) {
                authSet.add(new SimpleGrantedAuthority(role.getRoleCode().trim()));
            }
        }
 
        return authSet;
    }
    
}

6、MyAccessDecisionManager.java

[java] view plain copy
print ?
  1. package cn.com.abel.test.service.security;  
  2.   
  3. import java.util.Collection;  
  4. import java.util.Iterator;  
  5.   
  6. import org.springframework.security.access.AccessDecisionManager;  
  7. import org.springframework.security.access.AccessDeniedException;  
  8. import org.springframework.security.access.ConfigAttribute;  
  9. import org.springframework.security.authentication.InsufficientAuthenticationException;  
  10. import org.springframework.security.core.Authentication;  
  11. import org.springframework.security.core.GrantedAuthority;  
  12.   
  13. public class MyAccessDecisionManager implements AccessDecisionManager {  
  14.       
  15.     public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {  
  16.         if(configAttributes == null) {  
  17.             return;  
  18.         }  
  19.         //所请求的资源拥有的权限(一个资源对多个权限)  
  20.         Iterator<ConfigAttribute> iterator = configAttributes.iterator();  
  21.         while(iterator.hasNext()) {  
  22.             ConfigAttribute configAttribute = iterator.next();  
  23.             //访问所请求资源所需要的权限  
  24.             String needPermission = configAttribute.getAttribute();  
  25.             System.out.println("needPermission is " + needPermission);  
  26.             //用户所拥有的权限authentication  
  27.             for(GrantedAuthority ga : authentication.getAuthorities()) {  
  28.                 if(needPermission.equals(ga.getAuthority())) {  
  29.                     return;  
  30.                 }  
  31.             }  
  32.         }  
  33.         //没有权限让我们去捕捉  
  34.         throw new AccessDeniedException(" 没有权限访问!");  
  35.     }  
  36.   
  37.     public boolean supports(ConfigAttribute attribute) {  
  38.         // TODO Auto-generated method stub  
  39.         return true;  
  40.     }  
  41.   
  42.     public boolean supports(Class<?> clazz) {  
  43.         // TODO Auto-generated method stub  
  44.         return true;  
  45.     }  
  46.       
  47. }  
package cn.com.abel.test.service.security;

import java.util.Collection;
import java.util.Iterator;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

public class MyAccessDecisionManager implements AccessDecisionManager {
    
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
        if(configAttributes == null) {
            return;
        }
        //所请求的资源拥有的权限(一个资源对多个权限)
        Iterator<ConfigAttribute> iterator = configAttributes.iterator();
        while(iterator.hasNext()) {
            ConfigAttribute configAttribute = iterator.next();
            //访问所请求资源所需要的权限
            String needPermission = configAttribute.getAttribute();
            System.out.println("needPermission is " + needPermission);
            //用户所拥有的权限authentication
            for(GrantedAuthority ga : authentication.getAuthorities()) {
                if(needPermission.equals(ga.getAuthority())) {
                    return;
                }
            }
        }
        //没有权限让我们去捕捉
        throw new AccessDeniedException(" 没有权限访问!");
    }

    public boolean supports(ConfigAttribute attribute) {
        // TODO Auto-generated method stub
        return true;
    }

    public boolean supports(Class<?> clazz) {
        // TODO Auto-generated method stub
        return true;
    }
    
}


7、MySecurityMetadataSource.java

[html] view plain copy
print ?
  1. package cn.com.abel.test.service.security;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Collection;  
  5. import java.util.HashSet;  
  6. import java.util.Iterator;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9. import java.util.Map.Entry;  
  10. import java.util.TreeMap;  
  11. import java.util.concurrent.ConcurrentHashMap;  
  12.   
  13. import javax.servlet.http.HttpServletRequest;  
  14.   
  15. import org.apache.commons.lang.StringUtils;  
  16. import org.springframework.beans.factory.InitializingBean;  
  17. import org.springframework.security.access.ConfigAttribute;  
  18. import org.springframework.security.access.SecurityConfig;  
  19. import org.springframework.security.web.FilterInvocation;  
  20. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;  
  21. import org.springframework.security.web.util.matcher.AntPathRequestMatcher;  
  22. import org.springframework.security.web.util.matcher.RequestMatcher;  
  23.   
  24. import cn.com.abel.test.model.RoleModel;  
  25. import cn.com.abel.test.service.ResourceService;  
  26.   
  27. public class MySecurityMetadataSource  implements FilterInvocationSecurityMetadataSource,InitializingBean {  
  28.   
  29.       
  30.     private static final String AUTH_NO_ROLE =" __AUTH_NO_ROLE__";  
  31.       
  32.     private ResourceService resourceService;  
  33.       
  34.     public MySecurityMetadataSource(ResourceService resourceService) {  
  35.         this.resourceService = resourceService;  
  36.     }  
  37.   
  38.     private static Map<String, Collection<ConfigAttribute>> resourceMap = null;  
  39.   
  40.     public Collection<ConfigAttribute> getAllConfigAttributes() {  
  41.         return null;  
  42.     }  
  43.   
  44.     public boolean supports(Class<?> clazz) {  
  45.         return true;  
  46.     }  
  47.     private void loadResourceDefine() {  
  48.         if(resourceMap == null) {  
  49.             resourceMap = new ConcurrentHashMap<String, Collection<ConfigAttribute>>();  
  50.         }else{  
  51.             resourceMap.clear();  
  52.         }  
  53.           
  54.         Map<String,List<RoleModel>> resourceRoleMap = resourceService.getAllResourceRole();  
  55.           
  56.         for (Entry<String,List<RoleModel>> entry : resourceRoleMap.entrySet()) {  
  57.             String url = entry.getKey();  
  58.             List<RoleModel> values = entry.getValue();  
  59.               
  60.             Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();  
  61.             for(RoleModel secRoleModel : values){  
  62.                 ConfigAttribute configAttribute = new SecurityConfig(StringUtils.defaultString(secRoleModel.getRoleCode(),AUTH_NO_ROLE));  
  63.                 configAttributes.add(configAttribute);  
  64.             }  
  65.             resourceMap.put(url, configAttributes);  
  66.         }  
  67.     }  
  68.     public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {  
  69.           
  70.         HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();    
  71.    
  72.         TreeMap<String, Collection<ConfigAttribute>> attrMap = new TreeMap<String, Collection<ConfigAttribute>>(resourceMap);  
  73.           
  74.         Iterator<String> ite = attrMap.keySet().iterator();    
  75.           
  76.         RequestMatcher urlMatcher = null;    
  77.   
  78.         Collection<ConfigAttribute> attrSet = new HashSet<ConfigAttribute>();  
  79.         //match all of /admin/**  a/b/**  
  80.         while (ite.hasNext()) {    
  81.               
  82.             String resURL = ite.next();    
  83.             urlMatcher = new AntPathRequestMatcher(resURL);  
  84.   
  85.             if (urlMatcher.matches(request)||StringUtils.equals(request.getRequestURI(),resURL)) {    
  86.                 attrSet.addAll(attrMap.get(resURL));    
  87.             }    
  88.         }    
  89.   
  90.         if(!attrSet.isEmpty()){  
  91.             return attrSet;  
  92.         }  
  93.         return null;  
  94.     }  
  95.    
  96.     @Override  
  97.     public void afterPropertiesSet() throws Exception {  
  98.         loadResourceDefine() ;  
  99.     }  
  100.       
  101. }  
package cn.com.abel.test.service.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;
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.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

import cn.com.abel.test.model.RoleModel;
import cn.com.abel.test.service.ResourceService;

public class MySecurityMetadataSource  implements FilterInvocationSecurityMetadataSource,InitializingBean {

    
    private static final String AUTH_NO_ROLE =" __AUTH_NO_ROLE__";
    
    private ResourceService resourceService;
    
    public MySecurityMetadataSource(ResourceService resourceService) {
        this.resourceService = resourceService;
    }

    private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    public boolean supports(Class<?> clazz) {
        return true;
    }
    private void loadResourceDefine() {
        if(resourceMap == null) {
            resourceMap = new ConcurrentHashMap<String, Collection<ConfigAttribute>>();
        }else{
            resourceMap.clear();
        }
        
        Map<String,List<RoleModel>> resourceRoleMap = resourceService.getAllResourceRole();
        
        for (Entry<String,List<RoleModel>> entry : resourceRoleMap.entrySet()) {
            String url = entry.getKey();
            List<RoleModel> values = entry.getValue();
            
            Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
            for(RoleModel secRoleModel : values){
                ConfigAttribute configAttribute = new SecurityConfig(StringUtils.defaultString(secRoleModel.getRoleCode(),AUTH_NO_ROLE));
                configAttributes.add(configAttribute);
            }
            resourceMap.put(url, configAttributes);
        }
    }
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        
        HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();  
 
        TreeMap<String, Collection<ConfigAttribute>> attrMap = new TreeMap<String, Collection<ConfigAttribute>>(resourceMap);
        
        Iterator<String> ite = attrMap.keySet().iterator();  
        
        RequestMatcher urlMatcher = null;  

        Collection<ConfigAttribute> attrSet = new HashSet<ConfigAttribute>();
        //match all of /admin/**  a/b/**
        while (ite.hasNext()) {  
            
            String resURL = ite.next();  
            urlMatcher = new AntPathRequestMatcher(resURL);

            if (urlMatcher.matches(request)||StringUtils.equals(request.getRequestURI(),resURL)) {  
                attrSet.addAll(attrMap.get(resURL));  
            }  
        }  

        if(!attrSet.isEmpty()){
            return attrSet;
        }
        return null;
    }
 
    @Override
    public void afterPropertiesSet() throws Exception {
        loadResourceDefine() ;
    }
    
}

8、ResourceService.java

此类是为从数据库获取系统中的资源所属的角色,根据自己的数据表自行编写。

[java] view plain copy
print ?
  1. package cn.com.abel.test.service;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.HashSet;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8.   
  9. import org.apache.commons.collections.CollectionUtils;  
  10. import org.springframework.beans.factory.annotation.Autowired;  
  11. import org.springframework.stereotype.Service;  
  12.   
  13. import cn.com.abel.test.mapper.ResourceModelMapper;  
  14. import cn.com.abel.test.mapper.RoleModelMapper;  
  15. import cn.com.abel.test.mapper.RoleResourcetModelMapper;  
  16. import cn.com.abel.test.model.ResourceModel;  
  17. import cn.com.abel.test.model.ResourceModelCriteria;  
  18. import cn.com.abel.test.model.RoleModel;  
  19. import cn.com.abel.test.model.RoleModelCriteria;  
  20. import cn.com.abel.test.model.RoleResourcetModel;  
  21. import cn.com.abel.test.model.RoleResourcetModelCriteria;  
  22.   
  23. @Service  
  24. public class ResourceService {  
  25.       
  26.     @Autowired  
  27.     ResourceModelMapper resourceModelMapper;  
  28.       
  29.     @Autowired  
  30.     RoleModelMapper roleMapper;  
  31.       
  32.     @Autowired  
  33.     RoleResourcetModelMapper  roleResMapper;  
  34.       
  35.     /** 
  36.      * 获取各个资源(url)对应的角色 
  37.      * @return 
  38.      */  
  39.     public Map<String,List<RoleModel>> getAllResourceRole(){  
  40.           
  41.          Map<String,List<RoleModel>> resultMap = new HashMap<String,List<RoleModel>>();  
  42.            
  43.         ResourceModelCriteria secResourceModelExample = new ResourceModelCriteria();  
  44.         List<ResourceModel> resourceList = resourceModelMapper.selectByExample(secResourceModelExample);  
  45.           
  46.         if(CollectionUtils.isNotEmpty(resourceList)){  
  47.             for(ResourceModel secResourceModel : resourceList){  
  48.                 RoleModelCriteria roleCriteria = new RoleModelCriteria();  
  49.                 roleCriteria.createCriteria().andIdIn(getRoleIdsByResourceId(secResourceModel.getId()));  
  50.                 List<RoleModel> roleList = roleMapper.selectByExample(roleCriteria);  
  51.                 resultMap.put(secResourceModel.getValue(), roleList);  
  52.                   
  53.             }  
  54.         }  
  55.        
  56.         return resultMap;  
  57.     }  
  58.       
  59.     public List<Integer> getRoleIdsByResourceId(Integer resourceId){  
  60.         List<Integer> roleIds = new ArrayList<Integer>();  
  61.           
  62.         RoleResourcetModelCriteria criteria = new RoleResourcetModelCriteria();  
  63.         criteria.createCriteria().andResourceIdEqualTo(resourceId);  
  64.         List<RoleResourcetModel> list = roleResMapper.selectByExample(criteria);  
  65.         if(CollectionUtils.isNotEmpty(list)){  
  66.             for(RoleResourcetModel model : list){  
  67.                 roleIds.add(model.getRoleId());  
  68.             }  
  69.         }  
  70.           
  71.         HashSet<Integer> h  =   new  HashSet<Integer>(roleIds);       
  72.         roleIds.clear();       
  73.         roleIds.addAll(h);     
  74.         return roleIds;  
  75.     }  
  76. }  
package cn.com.abel.test.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.abel.test.mapper.ResourceModelMapper;
import cn.com.abel.test.mapper.RoleModelMapper;
import cn.com.abel.test.mapper.RoleResourcetModelMapper;
import cn.com.abel.test.model.ResourceModel;
import cn.com.abel.test.model.ResourceModelCriteria;
import cn.com.abel.test.model.RoleModel;
import cn.com.abel.test.model.RoleModelCriteria;
import cn.com.abel.test.model.RoleResourcetModel;
import cn.com.abel.test.model.RoleResourcetModelCriteria;

@Service
public class ResourceService {
    
    @Autowired
    ResourceModelMapper resourceModelMapper;
    
    @Autowired
    RoleModelMapper roleMapper;
    
    @Autowired
    RoleResourcetModelMapper  roleResMapper;
    
    /**
     * 获取各个资源(url)对应的角色
     * @return
     */
    public Map<String,List<RoleModel>> getAllResourceRole(){
        
         Map<String,List<RoleModel>> resultMap = new HashMap<String,List<RoleModel>>();
         
        ResourceModelCriteria secResourceModelExample = new ResourceModelCriteria();
        List<ResourceModel> resourceList = resourceModelMapper.selectByExample(secResourceModelExample);
        
        if(CollectionUtils.isNotEmpty(resourceList)){
            for(ResourceModel secResourceModel : resourceList){
                RoleModelCriteria roleCriteria = new RoleModelCriteria();
                roleCriteria.createCriteria().andIdIn(getRoleIdsByResourceId(secResourceModel.getId()));
                List<RoleModel> roleList = roleMapper.selectByExample(roleCriteria);
                resultMap.put(secResourceModel.getValue(), roleList);
                
            }
        }
     
        return resultMap;
    }
    
    public List<Integer> getRoleIdsByResourceId(Integer resourceId){
        List<Integer> roleIds = new ArrayList<Integer>();
        
        RoleResourcetModelCriteria criteria = new RoleResourcetModelCriteria();
        criteria.createCriteria().andResourceIdEqualTo(resourceId);
        List<RoleResourcetModel> list = roleResMapper.selectByExample(criteria);
        if(CollectionUtils.isNotEmpty(list)){
            for(RoleResourcetModel model : list){
                roleIds.add(model.getRoleId());
            }
        }
        
        HashSet<Integer> h  =   new  HashSet<Integer>(roleIds);     
        roleIds.clear();     
        roleIds.addAll(h);   
        return roleIds;
    }
}


最后附上数据表的SQL:

[sql] view plain copy
print ?
  1. CREATE TABLE `auth_resource` (  
  2.     `id` INT(11) NOT NULL AUTO_INCREMENT,  
  3.     `nameVARCHAR(100) NULL DEFAULT NULL COMMENT '资源名称',  
  4.     `value` VARCHAR(100) NULL DEFAULT NULL COMMENT '资源值',  
  5.     `summary` VARCHAR(1000) NULL DEFAULT NULL COMMENT '资源描述',  
  6.     `updated_time` DATETIME NULL DEFAULT NULL,  
  7.     `updated_user` VARCHAR(100) NULL DEFAULT NULL,  
  8.     PRIMARY KEY (`id`)  
  9. )  
  10. COMMENT='资源访问表'  
  11. COLLATE='utf8_general_ci'  
  12. ENGINE=InnoDB;  
  13.   
  14. CREATE TABLE `auth_role` (  
  15.     `id` INT(11) NOT NULL AUTO_INCREMENT,  
  16.     `role_name` VARCHAR(100) NULL DEFAULT NULL COMMENT '角色名称',  
  17.     `role_code` VARCHAR(100) NULL DEFAULT NULL COMMENT '角色代码',  
  18.     `updated_time` DATETIME NULL DEFAULT NULL,  
  19.     `updated_user` VARCHAR(100) NULL DEFAULT NULL,  
  20.     PRIMARY KEY (`id`)  
  21. )  
  22. COMMENT='角色表'  
  23. COLLATE='utf8_general_ci'  
  24. ENGINE=InnoDB;  
  25.   
  26. CREATE TABLE `role_resource` (  
  27.     `id` INT(11) NOT NULL AUTO_INCREMENT,  
  28.     `role_id` INT(11) NOT NULL,  
  29.     `resource_id` INT(11) NOT NULL,  
  30.     PRIMARY KEY (`id`),  
  31.     UNIQUE INDEX `role_id_resource_id` (`role_id`, `resource_id`)  
  32. )  
  33. COMMENT='资源角色关联表'  
  34. COLLATE='utf8_general_ci'  
  35. ENGINE=InnoDB;  
  36.   
  37. CREATE TABLE `member` (  
  38.     `id` INT(11) NOT NULL AUTO_INCREMENT,  
  39.     `user_name` VARCHAR(100) NULL DEFAULT NULL,  
  40.     `nick` VARCHAR(100) NULL DEFAULT NULL,  
  41.     `passwordVARCHAR(100) NULL DEFAULT NULL,  
  42.     `sex` INT(11) NULL DEFAULT NULL,  
  43.     `birthday` DATE NULL DEFAULT NULL,  
  44.     `mobile` VARCHAR(50) NULL DEFAULT NULL,  
  45.     `email` VARCHAR(50) NULL DEFAULT NULL,  
  46.     `address` VARCHAR(512) NULL DEFAULT NULL,  
  47.     `regip` VARCHAR(100) NULL DEFAULT NULL,  
  48.     `created_time` DATETIME NULL DEFAULT NULL,  
  49.     PRIMARY KEY (`id`)  
  50. )  
  51. COMMENT='用户表'  
  52. COLLATE='utf8_general_ci'  
  53. ENGINE=InnoDB  
  54. AUTO_INCREMENT=2;  
  55.   
  56. CREATE TABLE `member_role` (  
  57.     `id` INT(11) NOT NULL AUTO_INCREMENT,  
  58.     `member_id` INT(11) NOT NULL,  
  59.     `role_id` INT(11) NOT NULL,  
  60.     PRIMARY KEY (`id`),  
  61.     UNIQUE INDEX `member_id_role_id` (`member_id`, `role_id`)  
  62. )  
  63. COMMENT='用户角色关联表'  
  64. COLLATE='utf8_general_ci'  
  65. ENGINE=InnoDB;  
CREATE TABLE `auth_resource` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(100) NULL DEFAULT NULL COMMENT '资源名称',
    `value` VARCHAR(100) NULL DEFAULT NULL COMMENT '资源值',
    `summary` VARCHAR(1000) NULL DEFAULT NULL COMMENT '资源描述',
    `updated_time` DATETIME NULL DEFAULT NULL,
    `updated_user` VARCHAR(100) NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)
COMMENT='资源访问表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

CREATE TABLE `auth_role` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `role_name` VARCHAR(100) NULL DEFAULT NULL COMMENT '角色名称',
    `role_code` VARCHAR(100) NULL DEFAULT NULL COMMENT '角色代码',
    `updated_time` DATETIME NULL DEFAULT NULL,
    `updated_user` VARCHAR(100) NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)
COMMENT='角色表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

CREATE TABLE `role_resource` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `role_id` INT(11) NOT NULL,
    `resource_id` INT(11) NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE INDEX `role_id_resource_id` (`role_id`, `resource_id`)
)
COMMENT='资源角色关联表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

CREATE TABLE `member` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `user_name` VARCHAR(100) NULL DEFAULT NULL,
    `nick` VARCHAR(100) NULL DEFAULT NULL,
    `password` VARCHAR(100) NULL DEFAULT NULL,
    `sex` INT(11) NULL DEFAULT NULL,
    `birthday` DATE NULL DEFAULT NULL,
    `mobile` VARCHAR(50) NULL DEFAULT NULL,
    `email` VARCHAR(50) NULL DEFAULT NULL,
    `address` VARCHAR(512) NULL DEFAULT NULL,
    `regip` VARCHAR(100) NULL DEFAULT NULL,
    `created_time` DATETIME NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)
COMMENT='用户表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=2;

CREATE TABLE `member_role` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `member_id` INT(11) NOT NULL,
    `role_id` INT(11) NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE INDEX `member_id_role_id` (`member_id`, `role_id`)
)
COMMENT='用户角色关联表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

完整代码下载(包含数据库): http://download.csdn.net/download/rongku/9931455




http://www.niftyadmin.cn/n/2607916.html

相关文章

thinkphp mysql 调试_Thinkphp 5 调试执行的SQL语句

在模型操作中 &#xff0c;为了更好的查明错误&#xff0c;经常需要查看下最近使用的SQL语句&#xff0c;我们可以用getLastsql方法来输出上次执行的sql语句。例如&#xff1a;User::get(1);echo User::getLastSql();输出结果是 SELECT * FROM think_user WHERE id 1也可以使用…

37 分发系统

expect分发yum install -y expect1.自动远程登录 #! /usr/bin/expect set host "192.168.133.132" //定义变量host set passwd "123456" spawn ssh root$host //spawn后面跟系统shell命令&#xff0c;远程登录 expect { "yes/no" { send "…

c++ string替换指定字符串

string fnd "dataset"; string rep "labels"; string buf "d:/data/dataset/ii.jpg"; buf buf.replace(buf.find(fnd), fnd.length(), rep); 去掉由于window下引入的 /r 字符 fstream fp("val.txt"); vector<string> fn_vec…

setting.xml

<?xml version"1.0" encoding"UTF-8"?><settings xmlns"http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"http://maven.apache.org/SETTINGS/1.0…

LINUX——CA证书的自签署以及如何吊销

吊销证书1.客户端获取要吊销的证书的serial openssl x509 -in /path/from/cert_file -noout -serial -subject CA端先客户端提交的serial与subject信息&#xff0c;对比检验是否与index.txt文件中的信息一致 吊销证书&#xff1a; openssl ca -revoke /etc/pki/CA/newcerts/SER…

深入浅出JS - 变量提升(函数声明提升)

前言在我们的日常工作中&#xff0c;变量无处不在。更加深入的去了解它&#xff0c;能够使得自己的JS水平更上一层楼&#xff0c; 从变量提升这个小知识点着手&#xff0c;让我们一起来深入了解JS吧&#xff01;变量提升的小栗子console.log(a) // undefined var a hello JS /…

图像增强序列——基于Lab色彩空间和色调映射的彩色图像增强算法

1. 参考文献2. 模型实现 % 论文: 基于Lab色彩空间和色调映射的彩色图像增强算法 % 作者: % 链接&#xff1a; http://www.jsjkx.com/jsjkxen/ch/reader/create_pdf.aspx?file_no20180251&year_id2018&quarter_id2&falg1 % Author: HSW % Date: 2018-04-26clc; clo…

移除input在type=number时的上下箭头

网页在有些情况下&#xff0c;会需要input的输入的为单纯数字的文本框&#xff0c;此时typenumber&#xff0c;但使用typenumber时&#xff0c;输入框后面会有一个上下箭头&#xff0c;那么如何去掉上下箭头呢&#xff1f; 1、chrome浏览器移除 input::-webkit-outer-spin-butt…