SSM整合SpringSecurity實現權限管理實例 javaconfig配置方式

1.前言

本文講述使用javaconfig的方式整合SpringMVC+Mybatis+SpringSecurity實現基於數據庫的權限系統,包括對按鈕的權限控制。 
使用技術: springMVC、springsecurity4、mybatis、ehcache、前端使用dataTables表格、ztree。

2.表結構介紹

image

標準的五張表結構。其中t_resources包含了後臺系統的菜單 
image 
五張表分別爲用戶表,角色表,資源表,用戶角色表,角色資源表。 
給用戶分配角色,給角色配置權限。形成動態的權限控制。一個用戶可以擁有多個角色,一個角色也可以擁有多個資源(即權限)。

3.mavne配置

<properties>  
        <!-- spring版本號 -->  
        <spring.version>4.3.5.RELEASE</spring.version>  
        <springsecurity.version>4.2.1.RELEASE</springsecurity.version>
  </properties> 

  <dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
     <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-context-support</artifactId>
           <version>${spring.version}</version>
       </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>${springsecurity.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${springsecurity.version}</version>
    </dependency>
    <dependency>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-taglibs</artifactId>
         <version>${springsecurity.version}</version>
     </dependency>

      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.27</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
         <scope>provided</scope>
    </dependency>
    <!-- tomcat jstl -->
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
     <!-- mybatis核心包 -->  
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.3.0</version>
        </dependency> 
        <!-- mybatis/spring包 -->  
        <dependency>  
            <groupId>org.mybatis</groupId>  
            <artifactId>mybatis-spring</artifactId>  
            <version>1.2.2</version>  
        </dependency>  

          <!--單元測試依賴 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!--spring單元測試依賴 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>fastjson</artifactId>
           <version>1.2.15</version>
       </dependency>

        <dependency>  
            <groupId>com.github.pagehelper</groupId>  
            <artifactId>pagehelper</artifactId>  
            <version>4.1.4</version>  
        </dependency>  
      <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.4</version>
    </dependency>

    <!-- ehcache 相關依賴  -->
     <dependency>
         <groupId>net.sf.ehcache</groupId>
         <artifactId>ehcache</artifactId>
         <version>2.7.5</version>
     </dependency>

      <!-- 日誌文件管理包 -->  
         <!--ehcache依賴slf4j-->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.18</version>
            </dependency>
            <!--ehcache依賴slf4j-->

            <!--slf4j需要log4j-->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.18</version>
            </dependency>
            <!--slf4j需要log4j-->

            <!--log4j-->
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
                <version>2.5</version>
            </dependency>
            <!--log4j-->

  </dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143

4.搭建SpringMVC

首先配置DispatcherServlet:
package com.study.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;


public class WebProjectConfigInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    /** 
     *  加載驅動應用後端的中間層和數據層組件
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{RootConfig.class};
    }
    /** 指定配置類
     *  加載包含web組件的bean,如控制機器、視圖解析器以及映射處理器
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    //將DispatcherServlet 映射到“/”
    @Override
    protected String[] getServletMappings() {
         return new String[] { "/" }; 
    }


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
WebConfig:

主要加載包含WEB的組件bean。如控制器、視圖解析器以及處理映射處理器

package com.study.config;

import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

@Configuration
@EnableWebMvc
@ComponentScan("com.study.controller")
public class WebConfig extends WebMvcConfigurerAdapter {

    @Bean 
    public ViewResolver viewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/jsp/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);
        resolver.setViewClass(JstlView.class);
        return resolver;
    }

    //配置靜態資源的處理  使DispatcherServlet對靜態資源的請求轉發到Servlet容器默認的Servlet上,而不是使用DispatcherServlet本身來處理此類請求
     @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
         configurer.enable();
    }

  /*  @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("classpath:/css");
        registry.addResourceHandler("/js/**").addResourceLocations("classpath:/js");
        registry.addResourceHandler("/img/**").addResourceLocations("classpath:/img");
    }*/


     @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);

        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();

        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.PrettyFormat
        );
        fastConverter.setFastJsonConfig(fastJsonConfig);

        converters.add(fastConverter);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
RootConfig:

主要加載應用中其他bean。這些bean通常是驅動應用後端的中間層和數據層組件。

package com.study.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@ComponentScan(basePackages={"com.study"},excludeFilters={@Filter(type=FilterType.ANNOTATION,value=EnableWebMvc.class)})
public class RootConfig {

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

5.配置Spring Security

配置Delegating-FilterProxy
package com.study.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
/**
 * 配置Delegating-FilterProxy
 * 繼承AbstractSecurityWebApplicationInitializer會自動註冊DelegatingFilterProxy
 * 等價於xml配置
 * <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
 * 
 *
 */
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer{
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
Spring Security 安全配置
package com.study.config;

import javax.annotation.Resource;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import com.study.security.MyFilterSecurityInterceptor;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

//  @Resource
//  private DataSource dataSource;

    @Resource(name="myUserDetailService")
    private UserDetailsService myUserDetailService;

    @Resource
    private MyFilterSecurityInterceptor myFilterSecurityInterceptor;


//  @Override
//    public AuthenticationManager authenticationManagerBean() throws Exception {  
//      return super.authenticationManagerBean();  
//    }  

    @Override
    public void configure(WebSecurity web)throws Exception {
        // 設置不攔截規則
         web.ignoring().antMatchers("/css/**","/js/**","/img/**","/font-awesome/**");  
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
          http
            .addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class)//在正確的位置添加我們自定義的過濾器  
            .authorizeRequests()
            .anyRequest().authenticated()
//         .and().formLogin().and()
//          .httpBasic();
        // 自定義登錄頁面
            .and()
            .formLogin().loginPage("/jsp/login.jsp")
            .failureUrl("/jsp/login.jsp?error=1")
            .loginProcessingUrl("/spring_security_check")
            .usernameParameter("username")
            .passwordParameter("password").permitAll().defaultSuccessUrl("/index.do");

          //如果開啓了CSRF 退出則需要使用POST訪問,可以使用以下方式解決,但並不推薦
          http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))  
//        登陸成功後跳轉的地址,以及刪除的cookie名稱  
          .logoutSuccessUrl("/jsp/login.jsp?error=logout")  
         .invalidateHttpSession(true);  
    }



    @Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {

        //啓用內存用戶存儲
        /*auth.inMemoryAuthentication()
        .withUser("user1").password("123456").roles("USER").and()
        .withUser("admin").password("admin").roles("USER","ADMIN");*/
        //
        //給予數據庫表認證
        /*auth.jdbcAuthentication().dataSource(dataSource)
        .usersByUsernameQuery("select username,password,enable from t_user where username=?")
        .authoritiesByUsernameQuery("select username,rolename from t_role where username=?");
        */
        //配置自定義的用戶服務
        auth.userDetailsService(myUserDetailService).passwordEncoder(new Md5PasswordEncoder());

    }



}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90

解釋:以上代碼實現了spring Security 安全配置。其中@EnableWebSecurity註解將會啓用WEB安全功能。 
configure(WebSecurity web) 通過重載,配置Spring Security 的Filter鏈。 
configure(HttpSecurity http)通過重載,配置如何通過攔截器保護請求。以上代碼配置了自定義的過濾器 、自定義登錄頁面、和退出功能。其中自定義的過濾器相當於配置了對資源的授權。 
configure(AuthenticationManagerBuilder auth)通過重載,配置user_detail服務,其中可以使用基於內存用戶存儲、基於數據庫表進行認證、基於LDAP進行認證,以及自定義的用戶服務。以上代碼沒註釋的就是本文基於數據庫的自定義權限認證。

自定義認證:

就是在登錄時的認證操作交給Spring Security.在此處需要提供給當前登錄用戶所擁有的權限。即根據用戶名查詢上面t_resources表中的resKey 拼湊成”ROLE_XXX“ 這樣形式的字符串所組成的list ,交給spirngSecurity。

package com.study.security;

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

import javax.annotation.Resource;

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 org.springframework.stereotype.Component;

import com.study.model.Resources;
import com.study.model.User;
import com.study.service.ResourcesService;
import com.study.service.UserService;

@Component("myUserDetailService")
public class MyUserDetailServiceImpl implements UserDetailsService{

    @Resource
    private UserService userService;

    @Resource
    private ResourcesService resourcesService;
    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
        User user = userService.findUserByName(username);
        if(user ==null)
            throw new UsernameNotFoundException(username+" not exist!");  
        Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();
        Resources resources = new Resources();
        resources.setUsername(username);
        List<Resources> list = resourcesService.loadMenu(resources);
        for (Resources r : list) {
            authSet.add(new SimpleGrantedAuthority("ROLE_" +r.getResKey()));
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), 
                user.getPassword(), 
                user.getEnable()==1?true:false, 
                true, 
                true,
                true,
                authSet);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
自定義過濾器

使訪問程序時,檢查當前用戶是否擁有當前url的權限

package com.study.security;

import java.io.IOException;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
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.beans.factory.annotation.Autowired;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;



@Component
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
    @Autowired
    private MySecurityMetadataSource securityMetadataSource;
    @Autowired
    private MyAccessDecisionManager accessDecisionManager;
//  @Resource(name="myAuthenticationManager")
//    private AuthenticationManager authenticationManager;  

    @Resource
    private AuthenticationConfiguration authenticationConfiguration;

//  @Autowired
//  public void setAuthenticationConfiguration(AuthenticationConfiguration authenticationConfiguration) {
//       this.authenticationConfiguration = authenticationConfiguration;
//  }

    @PostConstruct
    public void init() throws Exception{
        super.setAccessDecisionManager(accessDecisionManager);
        super.setAuthenticationManager(authenticationConfiguration.getAuthenticationManager());   
    }

    @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對象
                  //super.beforeInvocation(fi);源碼
        //1.獲取請求資源的權限
        //執行Collection<ConfigAttribute> attributes = SecurityMetadataSource.getAttributes(object);
        //2.是否擁有權限
        //this.accessDecisionManager.decide(authenticated, object, attributes);
//      System.err.println(" ---------------  MySecurityFilter invoke--------------- ");
        InterceptorStatusToken token = super.beforeInvocation(fi);
        try {
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        } finally {
            super.afterInvocation(token, null);
        }
    }

    public void init(FilterConfig arg0) throws ServletException {
    }

    public void destroy() {

    }

    @Override
    public Class<? extends Object> getSecureObjectClass() {
        //下面的MyAccessDecisionManager的supports方面必須放回true,否則會提醒類型錯誤
        return FilterInvocation.class;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86

以上代碼涉及到MySecurityMetadataSource和MyAccessDecisionManager

MyAccessDecisionManager
package com.study.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;
import org.springframework.stereotype.Component;
/**
 * <!-- 用戶是否擁有所請求資源的權限 -->
 * 
 */
@Component
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;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
MySecurityMetadataSource

需要加載所有資源與權限的關係,即查詢t_resources表中所有resKey與resUrl的對應關係。

package com.study.security;

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

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

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.stereotype.Component;

import com.study.dao.ResourcesDao;
import com.study.model.Resources;

/**
 * 加載資源與權限的對應關係
 */
@Component
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Resource
    private ResourcesDao resourcesDao;


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

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

    public boolean supports(Class<?> clazz) {
        return true;
    }
    /**
     * @PostConstruct是Java EE 5引入的註解,
     * Spring允許開發者在受管Bean中使用它。當DI容器實例化當前受管Bean時,
     * @PostConstruct註解的方法會被自動觸發,從而完成一些初始化工作,
     * 
     * //加載所有資源與權限的關係
     */
    @PostConstruct
    private void loadResourceDefine() {
        if (resourceMap == null) {
            resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
            List<Resources> list = resourcesDao.queryAll(new Resources());
            for (Resources resources : list) {
                Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
                // 通過資源名稱來表示具體的權限 注意:必須"ROLE_"開頭
                ConfigAttribute configAttribute = new SecurityConfig("ROLE_" + resources.getResKey());
                configAttributes.add(configAttribute);
                resourceMap.put(resources.getResUrl(), configAttributes);
            }
        }
    }
    //返回所請求資源所需要的權限
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        String requestUrl = ((FilterInvocation) object).getRequestUrl();
    //  System.out.println("requestUrl is " + requestUrl);
        if(resourceMap == null) {
            loadResourceDefine();
        }
        //System.err.println("resourceMap.get(requestUrl); "+resourceMap.get(requestUrl));
        if(requestUrl.indexOf("?")>-1){
            requestUrl=requestUrl.substring(0,requestUrl.indexOf("?"));
        }
        Collection<ConfigAttribute> configAttributes = resourceMap.get(requestUrl);
        return configAttributes;
    }


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77

6.配置對按鈕的前臺顯示控制

因爲基於了數據庫的權限控制,無法通過使用Spring Security的標籤來控制對按鈕的條件性渲染。不過其實可以通過,來控制顯示。但是按鈕所對應的Role_XXX就被限定死,而無法修改了。但是在開發階段,只有按鈕所對應操作的url是可以確定的。於是採用自定義標籤,使當前的按鈕根據按鈕的url來確定當前用戶是否擁有該url的權限,進而控制按鈕的顯示。自定義標籤如下所示:

AuthorizeTag
package com.study.tag;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.study.model.Resources;
import com.study.service.ResourcesService;
import com.study.util.SpringWiredBean;
/**
 * 自定義標籤  用於前臺判斷按鈕權限 
 * @author A
 *
 */
public class AuthorizeTag extends BodyTagSupport {
    private static final long serialVersionUID = 1L;  

    private String buttonUrl;  

    public String getButtonUrl() {
        return buttonUrl;
    }


    public void setButtonUrl(String buttonUrl) {
        this.buttonUrl = buttonUrl;
    }


    @SuppressWarnings("static-access")
    @Override  
    public int doStartTag() {  
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();  
        SecurityContextImpl securityContextImpl = (SecurityContextImpl) request
                .getSession().getAttribute("SPRING_SECURITY_CONTEXT");
        //獲取當前登錄名
        String name = securityContextImpl.getAuthentication().getName();

        //如果數據庫裏有該鏈接,並且該用戶的權限擁有該鏈接,則顯示 。如果數據庫沒有該鏈接則不顯示
        ResourcesService resourcesService= (ResourcesService) SpringWiredBean.getInstance().getBeanById("resourcesService");
        List<Resources> queryAll = resourcesService.queryAll();
        boolean flag = true;
        for (Resources resources : queryAll) {
            if(resources.getResUrl().equals(buttonUrl))
                flag = false;
        }
        if(flag) //數據庫中沒有該鏈接,直接顯示
            return EVAL_BODY_INCLUDE;
        else{
            Resources resources = new Resources();
            resources.setUsername(name);
            resources.setResUrl(buttonUrl);
            List<Resources> resourcesList = resourcesService.loadMenu(resources);
            if(resourcesList.size()>0)  return EVAL_BODY_INCLUDE;//數據庫中有該鏈接,並且該用戶擁有該角色,顯示
        }
        return this.SKIP_BODY;  //不顯示
    }  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

以上帶有用到SpringWiredBean

SpringWiredBean
package com.study.util;


import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

public class SpringWiredBean extends SpringBeanAutowiringSupport {

    /**
     * 自動裝配註解會讓Spring通過類型匹配爲beanFactory注入示例
     */
    @Autowired
    private BeanFactory beanFactory;

    private SpringWiredBean() {
    }

    private static SpringWiredBean instance;

    static {
        // 靜態塊,初始化實例
        instance = new SpringWiredBean();
    }

    /**
     * 實例方法
     * 使用的時候先通過getInstance方法獲取實例
     * 
     * @param beanId
     * @return
     */
    public Object getBeanById(String beanId) {
        return beanFactory.getBean(beanId);
    }

    public static SpringWiredBean getInstance() {
        return instance;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

在WEB-INF下加入authorize.tld

authorize.tld
<?xml version="1.0" encoding="UTF-8" ?>    
<taglib 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-jsptaglibrary_2_1.xsd"    
        version="2.1">    
        <description>    
        <![CDATA[security Tags]]>    
        </description>    
        <tlib-version>1.0</tlib-version>    
        <short-name>security</short-name>    
        <uri>http://www.springsecurity.org/jsp</uri>    
        <tag>    
            <description>    
            <![CDATA[authorize Tag]]>    
            </description>    
            <name>authorize</name>    
            <tag-class>    
                com.study.tag.AuthorizeTag
            </tag-class>    
            <body-content>JSP</body-content>    
            <attribute>    
                <name>buttonUrl</name>    
                <required>false</required>    
                <rtexprvalue>true</rtexprvalue>    
                <type>java.lang.String</type>    
            </attribute>    
        </tag>    
    </taglib>    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

則在前端使用時,引入上面定義的標籤:

<%@ taglib uri="http://www.springsecurity.org/jsp" prefix="security"%>
  • 1
  • 1

然後頁面上控制:

 <security:authorize buttonUrl="/role/addRole.do">
     <button type="button" id="btn_search" onclick="$('#addRole').modal();" class="btn btn-info" style="float: right; margin-right: 1;">新增</button>
</security:authorize>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

7.配置Mybatis

package com.study.config; 

import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.Logger;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.github.pagehelper.PageHelper;

@Configuration
//加載資源文件
@PropertySource({"classpath:jdbc.properties"})
//加上這個註解,使得支持事務
@EnableTransactionManagement
@MapperScan(basePackages = {"com.study.dao"})
public class DataSourceConfig {
    private static final Logger logger = Logger.getLogger(DataSourceConfig.class);
    /*
     * 綁定資源屬性
     */
    @Value("${jdbc.driver}")
    private String driverClass;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String userName;
    @Value("${jdbc.password}")
    private String passWord;
    @Value("${maxActive}")
    private int maxActive;
    @Value("${maxIdle}")
    private int maxIdle;
    @Value("${maxWait}")
    private long maxWait;


    /** 
     * 必須加上static 
     */  
    public static PropertySourcesPlaceholderConfigurer placehodlerConfigurer() {
        logger.info("PropertySourcesPlaceholderConfigurer");
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean(destroyMethod="close")  
    public BasicDataSource dataSource() {
        logger.info("DataSource");
         BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(driverClass);
        dataSource.setUrl(url);
        dataSource.setUsername(userName);
        dataSource.setPassword(passWord);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxIdle(maxIdle);
        dataSource.setMaxWait(maxWait);
        return dataSource;
    }

    @Bean
    public PlatformTransactionManager txManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

   @Bean  
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {  
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();  
        sessionFactory.setDataSource(dataSource);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setMapperLocations(resolver.getResources("classpath:mapping/*Mapping.xml"));
        //配置pageHelper 
        sessionFactory.setPlugins(new Interceptor[]{pageHelper()});
        return sessionFactory.getObject();
    }  

    /*@Bean
    public MapperScannerConfigurer scannerConfigurer(){
        MapperScannerConfigurer configurer = new MapperScannerConfigurer();
        configurer.setBasePackage("com.study.dao");
        configurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        return configurer;
    }*/
    /**
     * mybatis 分頁插件配置
     * @return
     */
    @Bean  
    public PageHelper pageHelper() {  
        logger.info("MyBatisConfiguration.pageHelper()");
        PageHelper pageHelper = new PageHelper();  
        Properties p = new Properties();  
        p.setProperty("offsetAsPageNum", "true");  
        p.setProperty("rowBoundsWithCount", "true");  
        p.setProperty("reasonable", "true");  
        pageHelper.setProperties(p);  
        return pageHelper;  
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114

以上代碼,配置了dataSource、sqlSessionFactory、txManager。還配置了mybatis的分頁插件pageHelper。 
需要注意的是:上面代碼註釋了的部分,配置的MapperScannerConfigurer。當寫上這段代碼後,就會使因爲@PropertySource注入的jdbc配置獲取的值爲null,導致datasource無法配置成功,後來找了一些資料,改成@MapperScan(basePackages = {“com.study.dao”})就可以了。但還在沒找到原因,希望哪個大牛看到後可以給我解答,還有因爲這個只是一個練習的項目,可能存在很多不妥或者欠缺的地方,各位對這個項目有建議的地方,希望留言或者發送到郵箱 
[email protected],在此先謝謝大家。

再附上CachingConfig

CachingConfig
package com.study.config;

import org.apache.log4j.Logger;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration  
@EnableCaching//<!-- 啓用緩存註解 -->
public class CachingConfig {

     private static final Logger logger = Logger.getLogger(CachingConfig.class);  

    @Bean  
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {  
        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();  
        ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource(  
                "ehcache.xml"));  
        return ehCacheManagerFactoryBean;  
    }  

    @Bean  
    public CacheManager cacheManager() {  
        logger.info("EhCacheCacheManager"); 
        EhCacheCacheManager cacheManager = new EhCacheCacheManager();  
        cacheManager.setCacheManager(ehCacheManagerFactoryBean().getObject());  
        return cacheManager;  
    }  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

8.效果圖

image 
image 
image 
從圖中可以看到,當勾選相應的權限後,界面上的按鈕也跟着消失了。

套了模板,但是界面還是很醜,對前臺操作不太擅長,就先這樣了,還有對所有的修改操作都沒有做,就做了增加和刪除(好吧,有點懶的)。

第一次使用時導入mytest.sql 
admin 的密碼爲admin ,因爲密碼的加密是後面加入的,所以現在庫裏只有admin可以登錄。要想使用其他用戶登錄,請使用admin用戶重新創建用戶, 
並分配相應的權限。 
代碼下載: 
github 地址 :https://github.com/lovelyCoder/springsecuritydemo.git 
csdn 下載http://download.csdn.net/detail/poorcoder_/9818490

轉載請標明出處:http://blog.csdn.net/poorcoder_/article/details/70231779

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章