SpringBoot—Security安全管理(一)

Spring Security 是 Spring 家族中的一个安全管理框架,Spring Boot 对于 Spring Security 提供了 自动化配置方案,可以零配置使用 Spring Security。

SpringBoot 2.x版本

1.整合Security。

2.简单示例

3.详细配置。

一、整合Security

1.加入Security依赖,为了方便演示,加入thymeleaf依赖。

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

2.创建Controller类,在里面写个方法。

@Controller
public class SecurityController {
    @RequestMapping("/hello")
    public String Hello(Model model){
        model.addAttribute("msg","Spring Security!!!");
        return "Hello";
    }
}

3.创建thymeleaf页面,Hello.html.

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Security安全管理哦</title>
</head>
<body>
<h1>Security管理中</h1>
<div>
    <h3 th:utext="${msg}"></h3>
</div>
</body>
</html>

4.在properties中设置好访问端口后,此时Security模块已经开启了。启动项目,控制台会自动给出一个密码,默认用户名为user,此时访问Controller中的方法,浏览器出现以下界面,输入用户名和密码,才能进入Hello.html页面。

在这里插入图片描述

二、简单示例

接下来我们自己写一个Security的配置类,简单了解一下Security的使用。

1.在template下创建一些用来演示的html页面。

在这里插入图片描述

2.把Hello.html略作修改。

<body>
<h1>Security管理中</h1>
<div>
    <h3 th:utext="${msg}"></h3>
</div>
<div>
   <div>
        <h1>初级技能</h1>
        <a th:href="@{level_1/1}">加减乘除</a>
    </div>

    <div>
        <h1>中级技能</h1>
        <a th:href="@{level_2/1}">函数方程</a>
    </div>
</div>
</body>

3.创建Security的配置类,该配置类需要继承 WebSecurityConfigurerAdapter ,并重写配置方法。这里重写了认定和授权方法。

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/hello").permitAll()
                .antMatchers("/level_1/1").hasRole("Lv_1")
            .antMatchers("/level_2/1").hasRole("Lv_2");
       
        http.formLogin();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //super.configure(auth);
        auth.inMemoryAuthentication().passwordEncoder(new 	                                       BCryptPasswordEncoder()).withUser("Jack")
                .password(new BCryptPasswordEncoder().encode("123456")).roles("Lv_1");
    }


}

1)、这里的代码有些复杂,加密了密码算法,如果不写登录会报错,后面我们可以单独设置方法来解决。

auth.inMemoryAuthentication().passwordEncoder(new 				                                          BCryptPasswordEncoder()).withUser("Jack")
                .password(new BCryptPasswordEncoder().encode("123456")).roles("Lv_1");

SpringBoot2.0抛弃了原来的NoOpPasswordEncoder,要求用户保存的密码必须要使用加密算法后存储,在登录验证的时候Security会将获得的密码在进行编码后再和数据库中加密后的密码进行对比

这里也可以在配置类中使用原来的这个方法,当然不推荐,因为已经被废弃了,老版本适用,新版本会报错。

@Bean
    public static NoOpPasswordEncoder passwordEncoder() {
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }

2)、或者用 BCryptPasswordEncoder加密,设置一个bean,但是此时的密码还是明文,所以密码部分还是需要设置编码。

 @Bean
    public static BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

此时1)部分的代码可以如下

auth.inMemoryAuthentication().withUser("Jack")
                .password(new BCryptPasswordEncoder().encode("123456")).roles("Lv_1")

4.在Controller中继续加入两个路由。

 @RequestMapping("/level_1/1")
    public String level_1(){

        return "level_1/1";
    }
    @RequestMapping("/level_2/1")
    public String level_2(){

        return "level_2/1";
    }

5.此时我们访问hello,进入以下界面。

在这里插入图片描述

点击加减乘除,此时需要表单验证,输入Jack和密码123456,进入level_1/1.html,返回,点击函数方程,出现以下界面。

在这里插入图片描述

因为Lv_1角色无法访问这个界面,Lv_2角色才可以进入。

三、详细配置

3.1、自定义配置类

自定义配置类需要继承WebSecurityConfigurerAdapter,开启@EnableWebSecurity注解。

重写configure(HttpSecurity http)和configure(AuthenticationManagerBuilder auth)方法可以自定义规则。

1)、http.authorizeRequests()方法开启授权路径,antMatchers("/hello").permitAll()代表/hello路径所有人都可以访问,.antMatchers("/level_1/*").hasRole("Lv_1")代表/level_1/下路径只有Lv_1角色才可以访问。

2)、auth.inMemoryAuthentication().withUser("Jack") .password(new BCryptPasswordEncoder().encode("123456")).roles("Lv_1")代表在内存中设置用户,密码及其角色。

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/hello").permitAll()
                .antMatchers("/level_1/*").hasRole("Lv_1")
                .antMatchers("/level_2/*").hasRole("Lv_2")
                .antMatchers("/level_3/*").hasRole("Lv_3")
        ;


        http.formLogin().passwordParameter("pwd").usernameParameter("username")
                .loginPage("/userLogin")
                .successForwardUrl("/hello");
        http.logout().logoutSuccessUrl("/hello");

    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //super.configure(auth);
        auth.inMemoryAuthentication().withUser("Jack")
                .password(new BCryptPasswordEncoder().encode("123456")).roles("Lv_1")
                .and().withUser("Sally").password(new BCryptPasswordEncoder().encode("999"))
                .roles("Lv_3","Lv_2","Lv_1");
    }

    @Bean
    public static BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

3.2、自定义登录页

  http.formLogin().passwordParameter("pwd").usernameParameter("username")
                .loginPage("/userLogin").loginProcessingUrl("/userLogin")
                .successForwardUrl("/hello");
        http.logout().logoutSuccessUrl("/hello");

这里设置了/userLogin路径为登录路径,SpringBoot Security中登录是需要提交一个Post表单的,这里设置了表单参数为pwd和username,表单提交路径为loginProcessingUrl("/userLogin"),登录成功后返回/hello,

3.3、开启Thymleaf对Security的支持

Thymleaf对Security提供了一些支持标签,方便操作。

如下 sec:authorize="!isAuthenticated()",如果没有登陆,标签里面的内容不会显示。除此之外,还有许多其他的标签。

<div sec:authorize="!isAuthenticated()">
    <h3>你好,请登录</h3>
    <a th:href="@{/userLogin}">登录</a>
</div>

使用支持需要引入依赖,同时在html页面引入命名空间。

<dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
            <version>3.0.4.RELEASE</version>
        </dependency>
 xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"

这里的版本冲突需要注意。

原文地址:https://www.cnblogs.com/cgl-dong/p/13820875.html