zoukankan      html  css  js  c++  java
  • SpringBoot安全篇Ⅵ --- 整合Spring Security

    知识储备:

    关于SpringSecurity的详细学习可以查看SpringSecurity的官方文档

    Spring Security概览

    应用程序的两个主要区域是"认证"和"授权"(访问控制)。这两个主要区域是Spring Security的两个目标。

    "认证"(Authentication),是建立一个他声明的主体的过程(一个"主体"一般是指用户,设备或一些可以在你的应用程序中执行动作的其他系统)。

    "授权"(Authorization)指确定一个主体是否允许在你的应用程序执行一个动作的过程。为了抵达需要授权的点, 主体的身份已经有认证过程建立。

    一.Spring Security快速入门

    1.1 导入spring-boot-starter-security

    <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    1.2 编写SpringSecurity的配置类,该类需要继承WebSecurityConfigurerAdapter

    这边需要开启基于WebSecurity的注解,由于这个注解内部以及有了@Configuration,所以不需要再加上@Configuration了。

    @EnableWebSecurity //开启基于WebSecurity的注解(已经开启了@Configuration)
    public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    
    }

    1.3 在配置类中定制授权规则

     @Override
        protected void configure(HttpSecurity http) throws Exception {
            //super.configure(http);
            //定制请求的授权规则
            http.authorizeRequests().antMatchers("/").permitAll() //让所有人可以访问首页
            .antMatchers("/level1/**").hasRole("VIP1")
            .antMatchers("/level2/**").hasRole("VIP2")
            .antMatchers("/level3/**").hasRole("VIP3");
            //访问测试
    
            //开启自动配置的登陆功能,如果没有登录,则会来到登录页面
            http.formLogin();
            //该功能开启之后的效果:SpringSecurity自动处理的请求
            //1、/login 来到登录页
            //2、重定向到 /login?error 表示登录失败
            //3、更多信息
    
        }

    1.4 定义认证规则

    这边需要注意的是如果不用PasswordEncoder去验证密码会报错误,这里是解决方案

      @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            //super.configure(auth);
            //auth.jdbcAuthentication()
            //内存用户验证
        /*    auth.inMemoryAuthentication().withUser("wang").password("123456").roles("VIP1","VIP2").and()
                    .withUser("xia").password("654321").roles("VIP2","VIP3");  //表单提交的时候密码是以密文匹配,会报错*/
            auth.inMemoryAuthentication()
                    .passwordEncoder(new MyPasswordEncoder())
                    .withUser("wang").password("123456").roles("VIP1","VIP2").and()
                    .withUser("yun").password("123456").roles("VIP3"); //表单提交的时候密码是以明文匹配
    
        }

    二.注销

    在protected void configure(HttpSecurity http) throws Exception(){}方法中开启自动配置的注销功能:

    http.logout()

    开启后默认规则:

    1.访问/logout表示用户注销,清空session

    2.注销成功会返回/login?logout页面

    配置注销以后直接来到首页;

    http.logout().logoutSuccessUrl("/"); //注销以后来到首页

    完整代码:

     @Override
        protected void configure(HttpSecurity http) throws Exception {
            //super.configure(http);
            //定制请求的授权规则
            http.authorizeRequests().antMatchers("/").permitAll() //让所有人可以访问首页
            .antMatchers("/level1/**").hasRole("VIP1")
            .antMatchers("/level2/**").hasRole("VIP2")
            .antMatchers("/level3/**").hasRole("VIP3");
            //访问测试
    
            //开启自动配置的登陆功能,如果没有登录,则会来到登录页面
            //SpringSecurity自动处理的请求
            //默认规则
            //1、/login 来到登录页
            //2、重定向到 /login?error 表示登录失败
            //3、更多信息
            http.formLogin();
    
    
    
            //开启自动配置的注销功能
            //默认规则
            //1.访问/logout表示用户注销,清空session
            //2.注销成功会返回/login?logout页面
    
            http.logout().logoutSuccessUrl("/"); //注销以后来到首页
        }

    三.权限控制

    3.1 版本依赖

    使用这项功能前需要先将SpringBoot版本切换为1.5.6.RELEASE,SpringBoot2.x的版本使用时遇到了一些问题所以我将SpringBoot版本降级了。如果有Springboot2.x整合Spring Security成功使用权限控制的可以教教我。。。

    将SpringBoot版本变为1.5.6.RELEASE后需要将thymeleaf的版本也切换一下:

    <properties>
    <java.version>1.8</java.version>
    <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>
    <thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-extras-springsecurity4.version>
    </properties>

    在html使用spring security标签还需要导入thymeleaf-extra-springsecurity4包,版本为上面的版本3.0.2.RELEASE

    <dependency>
                <groupId>org.thymeleaf.extras</groupId>
                <artifactId>thymeleaf-extras-springsecurity4</artifactId>     
     </dependency>

    3.2 权限控制

    首先引入标签库

    <html xmlns:th="http://www.thymeleaf.org"
          xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">

    如果没有认证则显示下面内容:

    <div sec:authorize="!isAuthenticated()">
        <h2 align="center">游客您好,如果想查看武林秘籍 <a th:href="@{/login}">请登录</a></h2>
    </div>

    如果角色认证了显示出角色的信息:

    <!--如果认证了-->
    <div sec:authorize="isAuthenticated()">
        <h2><span sec:authentication="name"></span>,您好,您的角色有<span sec:authentication="principal.authorities"></span></h2>
        <form th:action="@{/logout}" method="post">
            <input type="submit" value="注销"/>
        </form>
    </div>

    控制只有拥有某个权限时才能显示该内容

    <div sec:authorize="hasRole('VIP1')">
        <h3>普通武功秘籍</h3>
        <ul>
            <li><a th:href="@{/level1/1}">罗汉拳</a></li>
            <li><a th:href="@{/level1/2}">武当长拳</a></li>
            <li><a th:href="@{/level1/3}">全真剑法</a></li>
        </ul>
    </div>

    四.记住我

    在protected void configure(HttpSecurity http) throws Exception(){}方法中开启记住我功能:

    //开启记住我功能
     http.rememberMe();

    开启该功能后,登陆页面会自动多一个记住我的复选框按钮。

    勾选登陆后,会自动生成cookie,下次访问时无需登陆即可访问。

    五.自定义登陆页

    上述功能都是基于默认规则的登录功能,那么如何制定自己的登录页呢?

    5.1 定制Controller登录页

    /*
         * 登陆页
         * @return
         */
        @GetMapping("/userlogin")
        public String loginPage() {
            return PREFIX+"login";
        }
        

    5.2 在protected void configure(HttpSecurity http) throws Exception(){}中配置:

    http.formLogin().usernameParameter("user").passwordParameter("pwd").loginPage("/userlogin");

    一旦定制loginPage,那么loginPage的post请求就是登录。

    5.3 登录的表单

    <div align="center">
            <form th:action="@{/userlogin}" method="post">
                用户名:<input name="user"/><br>
                密码:<input name="pwd"><br/>
                <input type="checkbox" name="remeber"/>记住我 <br/>
                <input type="submit" value="登陆">
            </form>
    </div>

    5.4 自定义记住我功能

    //开启记住我功能
    http.rememberMe().rememberMeParameter("remeber");
  • 相关阅读:
    Response.Redirect、Server.Transfer、Server.Execute的区别
    js删除Array指定位置元素方法
    用Json.NET将json字符串反序列化为json匿名对象
    Asp.net中编程方式调用ashx(通过webRequest)
    Server.Transfer中传递ViewState方法
    Ext.Net中Ext.net.DirectMethods无法找到DirectMethod
    IFrame网页加载完成事件
    oracle中grant授权说明
    深度剖析Byteart Retail案例:前言
    深度剖析Byteart Retail案例:仓储(Repository)及其上下文(Repository Context)
  • 原文地址:https://www.cnblogs.com/wangxiayun/p/10301276.html
Copyright © 2011-2022 走看看