Spring Security之Java Configuration方式

java configuration方式

  • 上面是以xml文件的方式配置,接下来介绍以自定义java类的方式来配置spring security
  • 可先在719行:自定义过滤器一节了解认证流程。
1. 注册DelegatingFilterProxy
    package com.study.config;
    import org.springframework.security.web.context.*;

    public class SecurityWebApplicationInitializer
        extends AbstractSecurityWebApplicationInitializer {
        
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class[] { WebSecurityConfig.class };
        }
        
    }
  • 继承该类相当于在web.xml中:

      <filter>
          <filter-name>springSecurityFilterChain</filter-name>
          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
      </filter>
    
  • 重写getRootConfigClasses()相当于把下一步Spring Security的配置加载到程序中。

2. 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 //启用web安全功能
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    //  @Resource
    //  private DataSource dataSource;
    
        //配置自定义的用户服务(即选择用户信息的查询方式是从用户库或数据库,怎么查询)
        @Resource(name="myUserDetailService")
        private UserDetailsService myUserDetailService;
        
        //第3点:自定义用户验证
        @Resource
        private AuthenticationProvider myAuthenticationProvider;
        
        //自定义认证成功处理器
        @Resource
        private AuthenticationSuccessHandler myAuthenticationSuccessHandler;
    
        //第4点:自定义拦截器(自定义权限验证,而不是拦截规则)
        @Resource
        private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
        
        /**
         * 密码加密
         */
        @Bean
        public BCryptPasswordEncoder passwordEncoder(){
            return new BCryptPasswordEncoder();
        }
        
        /**
        * 自定义认证过程
        */
        @Override
        protected void configure(AuthenticationManagerBuilder auth)
                throws Exception {
    
            /* 不重写的话默认为
            auth
                .inMemoryAuthentication()
                    .withUser("user").password("password").roles("USER"); //默认准备了一个用户
            */
            
            //方式一:内存用户存储
            /*
            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()); 
                //加后MyAuthenticationProvider里比对密码时能把表单的明文和数据库的密文对应
            
            //自定义用户验证
            auth.authenticationProvider(myAuthenticationProvider);
        }
    
    //  暴露默认的authenticationManager
    //  @Override
    //    public AuthenticationManager authenticationManagerBean() throws Exception {  
    //      return super.authenticationManagerBean();  
    //    }  
    
        /**
        * 配置Spring Security的Filter链
        */
        @Override
        public void configure(WebSecurity web)throws Exception {
            // 设置不拦截规则
             web.ignoring().antMatchers("/css/**","/js/**","/img/**","/font-awesome/**");  
        }
    
        /**
        * 配置如何通过拦截器保护请求:配置了自定义的过滤器、自定义登录登出页面
        * 前端请求的时候先经过这里检测请求是否需要验证或权限,不需要的话直接把请求分发给controller去处理,需要就认证过了再分发
        */
        @Override
        protected void configure(HttpSecurity http) throws Exception {
              http
                .addFilterBefore(myFilterSecurityInterceptor,    
                    FilterSecurityInterceptor.class)//在正确的位置添加我们自定义的过滤器  
                .authorizeRequests() //需要权限,权限符合与否由上面过滤器检查
                .antMatchers("/admin/**").hasRole("ADMIN") //以admin开头的url需要admin权限
                .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
                .anyRequest().authenticated() //不与以上匹配的所有请求只需要登录验证
    //         .and().formLogin().and() //and相当于节点结束
    //          .httpBasic();
            // 自定义登录页面:permitAll,允许all用户访问login页面
            //未登录前访问受保护资源被转回login
                .and()
                /*直接/jsp/login的话会分配给controller去处理,则需要写controller映射到登录页;请求login.jsp报404
                有后缀则直接请求资源,那么url=/login还是由controller处理;
                那么最好是加后缀,才不用再走controller*/
                .formLogin().loginPage("/jsp/login.jsp") 
                .failureUrl("/jsp/login.jsp?error=1")
                //表单提交地址,4.x默认为/login;无需认证,但是请求方式必须post
                .loginProcessingUrl("/spring_security_check") 
                .usernameParameter("username")
                .passwordParameter("password")
                .successHandler(myAuthenticationSuccessHandler) //自定义认证成功处理器
                //.failureHandler(myAuthenticationFailureHandler)
                .permitAll()
                //这里也是,要么配资源路径,要么配有controller处理的url
                .defaultSuccessU
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值