Spring Security控制权限

目录

一 、认识SpringSecurity

二、环境搭建  认证和授权

1、引入Spring Security模块

2、编写Spring Security配置类

3、定制请求的授权规则

4、在SecurityConfigure中开启自动配置的登录功能

5、自定义认证规则

三 、注销

        1、开启自动配置的注销功能

        2、增加一个注销按钮

        3、自定义注销(注销成功后跳转到指定页面)

四、权限控制 

        1、导入依赖

        2、 修改前端页面

                1、导入命名口空间

                2、修改导航栏,增加认证判断

                3、解决注销404了

        3、角色功能模块 

五、定制登录页面

1、开启记住我功能

2、自定义登录首页 


一 、认识SpringSecurity

        Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理。

        记住几个类:
                WebSecurityConfigurerAdapter: 自定义Security策略
                AuthenticationManagerBuilder:自定义认证策略
                @EnableWebSecurity:开启WebSecurity模式    @Enablexxx 开启xx模式
                Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)。
         “认证”(Authentication)
                身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。
                身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。
         “授权” (Authorization)
                授权发生在系统成功验证您的身份后,最终会授予您访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。

二、环境搭建  认证和授权

        1、引入Spring Security模块

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

        2、编写Spring Security配置类

package com.kuang.config;
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.WebSecurity
ConfigurerAdapter;
@EnableWebSecurity // 开启WebSecurity模式
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
}
}

        3、定制请求的授权规则

        //请求授权的规则    如果没有权限会报403错误(没有权限)
        http.authorizeRequests().antMatchers("/").permitAll()//所有用户都可以访问首页
                .antMatchers("/level1/**").hasRole("vip1")//vip1的用户可以访问level1下的资
                .antMatchers("/level2/**").hasRole("vip2")//vip2的用户可以访问level2下的资
                .antMatchers("/level3/**").hasRole("vip3");//vip3的用户可以访问level3下的资

        4、在SecurityConfigure中开启自动配置的登录功能

    //没有权限访问会默认到登录页面,需要开启登录的页面
        http.formLogin();

        5、自定义认证规则

        @Override//认证
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //下面这些数据可以从数据库中读取 也可以从内存中读取  {noop}是对密码进行加密 不加密会报500错误
        auth.inMemoryAuthentication()
                .withUser("rk").password("{noop}123456").roles("vip2","vip3")
                .and()
                .withUser("root").password("{noop}123456").roles("vip1","vip2","vip3")
                .and()
                .withUser("guest").password("{noop}123456").roles("vip1");
    }

               测试 :使用rk进行登录

        访问:level1的资源

        访问level2、level3 

三 、注销

        1、开启自动配置的注销功能

//定制请求的授权规则
@Override
protected void configure(HttpSecurity http) throws Exception {
    //开启自动配置的注销的功能
    // /logout 注销请求
    http.logout();
}

        2、增加一个注销按钮

                路径为:/logout

<a class="item" th:href="@{/logout}">
    <i class="address card icon"></i> 注销
</a>

        3、自定义注销(注销成功后跳转到指定页面)

// .logoutSuccessUrl("/"); 注销成功来到首页
http.logout().logoutSuccessUrl("/");

四、权限控制 

        需求:

        1、用户没有登录的时候,导航栏上只显示登录按钮,用户登录之后,导航栏可以显示登录的用户信息及注销按钮

        2、比如rk这个用户,它只有 vip2,vip3功能,那么登录则只显示这两个功能,而vip1的功能菜单不显示

        thymeleaf和springsecurity整合包

        1、导入依赖

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
    <version>3.0.4.RELEASE</version>
</dependency>

        2、 修改前端页面

                1、导入命名口空间

xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"

                2、修改导航栏,增加认证判断

 <!--登录注销-->
            <div class="right menu">
                
                <!--如果未登录   首页只显示登录-->
                <div sec:authorize="!isAuthenticated()">
                    <a class="item" th:href="@{/login}">
                        <i class="address card icon"></i> 登录
                    </a>
                </div>

                <!--isAuthenticated()表示已登录 如果已登录  显示用户名,角色  和注销-->
                <div sec:authorize="isAuthenticated()">
                    <a class="item">
                       <i class="address card icon"></i>
                        用户名:<span sec:authentication="principal.username"></span>
                        角色:<span sec:authentication="principal.authorities"></span> <!--获取角色权限-->
                    </a>
                </div>

                <div sec:authorize="isAuthenticated()">
                    <a class="item" th:href="@{/logout}">
                        <i class="address card icon"></i> 注销
                    </a>
                </div>

                3、解决注销404了

                因为它默认防止csrf跨站请求伪造,因为会产生安全问题,我们可以将请求改为post表单提交,或者在spring security中关闭csrf功能 。

http.csrf().disable();//关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求
http.logout().logoutSuccessUrl("/");

                此时已经完成需求1,接下来完成需求2 

        3、角色功能模块 

                在需要分角色显示的模块加上:sec:authorize="hasRole('角色')"

  <div class="ui three column stackable grid">
            <!--该模块设置vip1的权限-->
            <div class="column" sec:authorize="hasRole('vip1')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 1</h5>
                            <hr>
                            <div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>
                            <div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
                            <div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>
                        </div>
                    </div>
                </div>
            </div>
            <!--该模块设置vip2的权限-->
            <div class="column" sec:authorize="hasRole('vip2')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 2</h5>
                            <hr>
                            <div><a th:href="@{/level2/1}"><i class="bullhorn icon"></i> Level-2-1</a></div>
                            <div><a th:href="@{/level2/2}"><i class="bullhorn icon"></i> Level-2-2</a></div>
                            <div><a th:href="@{/level2/3}"><i class="bullhorn icon"></i> Level-2-3</a></div>
                        </div>
                    </div>
                </div>
            </div>
            <!--该模块设置vip3的权限-->
            <div class="column" sec:authorize="hasRole('vip3')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 3</h5>
                            <hr>
                            <div><a th:href="@{/level3/1}"><i class="bullhorn icon"></i> Level-3-1</a></div>
                            <div><a th:href="@{/level3/2}"><i class="bullhorn icon"></i> Level-3-2</a></div>
                            <div><a th:href="@{/level3/3}"><i class="bullhorn icon"></i> Level-3-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

        </div>

五、定制登录页面

        1、开启记住我功能

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

                此时在自带的登录页面中会增加一个登录我的按钮 

         2、自定义登录首页 

                在开启登录加入其它参数

         //没有权限会默认到登录页面,需要开启登录的页面
        http.formLogin()
                .loginPage("/toLogin")//自定义的登录页面
                .loginProcessingUrl("/login")//登录表单from的action地址
                .defaultSuccessUrl("/rk");//登录成功后跳转的路径

                修改login.html的表单提交路径

    <form th:action="@{/login}" method="post">

                此时刚刚加入的登录我按钮已经不生效了,因为我们自定义了新的登录页面

                在前端页面加上记住我的按钮

  <div class="field">
               <input type="checkbox" name="remember">记住我
  </div>

                增加开启记住我的参数,值为记住我的name属性值

 //开启记住我
http.rememberMe().rememberMeParameter("remember");

Guess you like

Origin blog.csdn.net/m0_46979453/article/details/120998642