SpringSecurity学习

  •   SpringSecurity介绍

           Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

    SpringSecurity官网:  https://spring.io/projects/spring-security 
      
    SpringSecurity的种认证模式:  
         1)   HttpBasic模式   
         2)   FormLogin模式
     

  •   HttpBasic模式
     
     
  1.   创建boot项目 
      结构如下: 
      在pom.xml添加依赖
     <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
  2.   创建订单Controller
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class OrderController {
    	// 首页
    	@RequestMapping("/")
    	public String index() {
    		return "index";
    	}
    
    	// 查询订单
    	@RequestMapping("/showOrder")
    	public String showOrder() {
    		return "showOrder";
    	}
    
    	// 添加订单
    	@RequestMapping("/addOrder")
    	public String addOrder() {
    		return "addOrder";
    	}
    
    	// 修改订单
    	@RequestMapping("/updateOrder")
    	public String updateOrder() {
    		return "updateOrder";
    	}
    
    	// 删除订单
    	@RequestMapping("/deleteOrder")
    	public String deleteOrder() {
    		return "deleteOrder";
    	}
    
    	// 自定义登陆页面
    	@GetMapping("/login")
    	public String login() {
    		return "login";
    	}
    
    }
    配置对应查询、修改等按钮和页面,这里主要是用于演示效果。
     
  3.  添加security配置类
    import org.springframework.context.annotation.Bean;
    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.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.password.NoOpPasswordEncoder;
    import org.springframework.stereotype.Component;
    
    /**
     * SpringSecurity配置
     * @author xiaobo
     * @Description SecurityConfig
     * @createTime 2020-06-10 7:14
     */
    @Component
    @EnableWebSecurity   // 开启security
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    
        // 用户认证信息
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            // 设置用户账号信息和权限
            auth.inMemoryAuthentication().withUser("admin").password("123456").authorities("addOrder");
        }
    
        // 配置HttpSecurity拦截URL
        protected void configure(HttpSecurity http) throws Exception {
            // 拦截所有请求并选择httpBasic模式
            http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();
        }
    
        @Bean
        public static NoOpPasswordEncoder passwordEncoder() {
            return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
        }
    
    
    }

     
  4.  启动
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * Hello world!
     *
     */
    @SpringBootApplication
    public class AppSpringSecurity {
    
    
        public static void main( String[] args ) {
            SpringApplication.run(AppSpringSecurity.class);
        }
    }

     
  5.  测试
     
      访问: http://127.0.0.1:8080/
     
     
     账号/密码: admin/123456
     
     
  •  FormLogin模式
     
  1.  修改SecurityConfig类
     
    // 配置HttpSecurity拦截URL
        protected void configure(HttpSecurity http) throws Exception {
            // 拦截所有请求并选择formLogin模式
            http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().formLogin();
        }

     
  2.  测试......
     
     
     
  •  用户自定义页面和权限
     
     

  1.  实现不同用户的权限控制
    在在SecurityConfig.java配置
    import org.springframework.context.annotation.Bean;
    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.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.password.NoOpPasswordEncoder;
    import org.springframework.stereotype.Component;
    
    /**
     * SpringSecurity配置
     * @author xiaobo
     * @Description SecurityConfig
     * @createTime 2020-06-10 7:14
     */
    @Component
    @EnableWebSecurity   // 开启security
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    
        // 用户认证信息
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            // 设置用户账号信息和权限
            // 配置admin用户拥有查看、添加、更新、删除订单权限
            auth.inMemoryAuthentication().withUser("admin").password("123456").authorities("showFlag", "addFlag", "updateFlag","deleteFlag");
            // 配置ben用户拥有查看、添加订单权限
            auth.inMemoryAuthentication().withUser("ben").password("123456").authorities("showFlag", "addFlag");
        }
    
        // 配置HttpSecurity拦截URL
        protected void configure(HttpSecurity http) throws Exception {
            // 拦截所有请求并选择httpBasic模式     /showOrder:url地址   showFlag:每个url对应的标识,用户绑定标识
            http.authorizeRequests().
                    antMatchers("/showOrder").hasAnyAuthority("showFlag").
                    antMatchers("/addOrder").hasAnyAuthority("addFlag").
                    antMatchers("/updateOrder").hasAnyAuthority("updateFlag").
                    antMatchers("/deleteOrder").hasAnyAuthority("deleteFlag").
                    antMatchers("/**").fullyAuthenticated().and().formLogin();
        }
    
        @Bean
        public static NoOpPasswordEncoder passwordEncoder() {
            return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
        }
    
    
    }

     
  2.  实现自定义权限不足页面
     // 配置类
    import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
    import org.springframework.boot.web.server.ErrorPage;
    import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.HttpStatus;
    
    @Configuration
    public class WebServerAutoConfiguration {
    
    	@Bean
    	public ConfigurableServletWebServerFactory webServerFactory() {
    		TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
    		ErrorPage errorPage400 = new ErrorPage(HttpStatus.BAD_REQUEST, "/error/400");
    		ErrorPage errorPage401 = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error/401");
    		ErrorPage errorPage403 = new ErrorPage(HttpStatus.FORBIDDEN, "/error/403");
    		ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");
    		ErrorPage errorPage415 = new ErrorPage(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "/error/415");
    		ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");
    		factory.addErrorPages(errorPage400, errorPage401, errorPage403, errorPage404, errorPage415, errorPage500);
    		return factory;
    	}
    }
    // 自定义403的controller
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class ErrorController {
    
    	@RequestMapping("/error/403")
    	public String error() {
    		return "/error/403";
    	}
    
    }
    // 效果
  3.   实现自定义登录页面
    // 自定义登录的url和页面
    // 页面
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>登录页面</title>
    </head>
    <body>
    
    	<h1>自定义登录页面</h1>
    	<form action="/login" method="post">
    		<span>用户名称</span><input type="text" name="username" /> <br>
    		<span>用户密码</span><input type="password" name="password" /> <br>
    		<input type="submit" value="登陆"> 
    
    	</form>
    	
    	<#if RequestParameters['error']??>
    	用户名称或者密码错误
    	</#if>
    
    </body>
    </html>
     
    	// controller
    	@GetMapping("/login")
    	public String login() {
    		return "login";
    	}
    
    // 在SecurityConfig.java配置登录页面
    // 配置HttpSecurity拦截URL
        protected void configure(HttpSecurity http) throws Exception {
            // 拦截所有请求并选择httpBasic模式     /showOrder:url地址   showFlag:url地址的标识,可自定义须臾上面authorities一致
            http.authorizeRequests().
                    antMatchers("/showOrder").hasAnyAuthority("showFlag").
                    antMatchers("/addOrder").hasAnyAuthority("addFlag").
                    antMatchers("/updateOrder").hasAnyAuthority("updateFlag").
                    antMatchers("/deleteOrder").hasAnyAuthority("deleteFlag").
                    antMatchers("/login").permitAll().
                    antMatchers("/**").fullyAuthenticated().and().formLogin().loginPage("/login").and().csrf().disable();
        }
    antMatchers("/login").permitAll()表示不拦截login的地址
    .loginPage("/login").and().csrf().disable();  表示自定义登录页面,并禁止csrf
    //  测试: 
     
     
  4.  获取登录成功和失败的信息
     创建登录成功和失败的handler
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
    import org.springframework.stereotype.Component;
    
    // 认证成功
    @Component
    public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    
    	public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse res, Authentication arg2)
    			throws IOException, ServletException {
    		System.out.println("用户认证成功");
    		res.sendRedirect("/");
    	}
    
    }
    
    
    
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.authentication.AuthenticationFailureHandler;
    import org.springframework.stereotype.Component;
    
    //认证失败
    @Component
    public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
    
    	public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse res, AuthenticationException auth)
    			throws IOException, ServletException {
    		System.out.println("登陆失败!");
    		res.sendRedirect("http://baidu.com");
    
    	}
    
    }

     在SecurityConfig.java配置成功和失败的handler
       引入
    
        @Autowired
        private MyAuthenticationSuccessHandler successHandler;
        @Autowired
        private MyAuthenticationFailureHandler failHandler;
    
    
        // 配置HttpSecurity拦截URL
        protected void configure(HttpSecurity http) throws Exception {
            // 拦截所有请求并选择httpBasic模式     /showOrder:url地址   showFlag:url地址的标识,可自定义须臾上面authorities一致
            http.authorizeRequests().
                    antMatchers("/showOrder").hasAnyAuthority("showFlag").
                    antMatchers("/addOrder").hasAnyAuthority("addFlag").
                    antMatchers("/updateOrder").hasAnyAuthority("updateFlag").
                    antMatchers("/deleteOrder").hasAnyAuthority("deleteFlag").
                    antMatchers("/login").permitAll().
                    antMatchers("/**").fullyAuthenticated().and().formLogin().loginPage("/login")
                    .successHandler(successHandler).failureHandler(failHandler).and().csrf().disable();
        }
     
     
     
     

     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值