java

SpringBoot集成SpringSecurity入门到精通

2020-11-11  本文已影响0人  任笙_8b8c

Springboot环境搭建


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>SpringBootText</artifactId>
    <version>1.0-SNAPSHOT</version>

        <!--springboot版本-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>


    <dependencies>
        <!--springboot项目添加web包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <!--springboot集成测试包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--springboot集成前端thymeleaf框架  有了这个框架就能设置前后缀直接跳转到指定页面-->  
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!--权限控制  spring security依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
#更改项目端口号
server.port=8081

# 定位thymeleaf模板的目录  使用@controller直接返回就会找这个模板下面的页面
spring.thymeleaf.prefix=classpath:/templates/
使用SpringSecurity
  @Override
    protected void configure(HttpSecurity http) throws Exception {
        //表单登录,permitAll()表示这个不需要验证 登录页面,登录失败页面
        /*loginPage("/login")  当目标请求过来访问我们的资源路径跳转到自己写的登录页面
       登录页面的 form的提交资源目录就是 loginProcessingUrl("/login/form")
        这个是框架校验自己用户名密码的地方如果用户输入的账号密码和框架提供的账号密码不一致就会走failureUrl("/login-error")这个资源路径
        跳转到错误页面 , 用户账户密码都输入成功 则会成功成功访问资源路径进行放行
        */
        http
                .formLogin().loginPage("/login").loginProcessingUrl("/login/form").failureUrl("/login-error").permitAll()
                .and()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .csrf().disable();
    }
图片.png

再次进行访问项目,看到的就是自己写的登录页面 但是要注意的是表单的提交路径必须和设置的loginProcessingUrl("/login/form")路径一致!!!

按理来说只需要重写configure方法即可

  @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
            //设置withUser:用户名   password:密码  roles:角色
            auth
                    .inMemoryAuthentication()
                    .withUser("admin1").password("123456").roles("USER")
                    .and()
                    .withUser("test").password("test123").roles("ADMIN");
    }

再次启动项目使用自定义的用户名和密码进行访问会发现一个报错问题:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
解决方法:
这是因为Spring boot 2.0.3引用的security 依赖是 spring security 5.X版本,spring security5.x 新增了加密方式 如果重写如重写 configure(AuthenticationManagerBuilder auth)时仍使用该处原代码,会出现如下报错: There is no PasswordEncoder mapped for the id “null” :
(第一种方法 :)
因此,需要创建PasswordEncorder的实现类。MyPasswordEncoder.class:

package com.tang.Money;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

@Component   //(记住一定要加这个注解,把这个类交给sprig管理)
public class MyPasswordEncoder implements PasswordEncoder {
    @Override
    public String encode(CharSequence charSequence) {
        return charSequence.toString();
    }
    @Override
    public boolean matches(CharSequence charSequence, String s) {
        return s.equals(charSequence.toString());
    }
}

再次启动进行访问就能看到不会爆错了,而且能登录成功!!!
但是有人表示需要加上 new MyPasswordEncoder()才算是进行明文密码校验,如下代码 ,但是反复测试只需要将MyPasswordEncoder类交给spring去管理就可以解决此问题

 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //可以设置内存指定的登录的账号密码,指定角色
        //不加.passwordEncoder(new MyPasswordEncoder())
        //就不是以明文的方式进行匹配,会报错
        auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
        //.passwordEncoder(new MyPasswordEncoder())。
        //这样,页面提交时候,密码以明文的方式进行匹配。  new MyPasswordEncoder() 这个类
        auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder()).withUser("cxh").password("cxh").roles("ADMIN");
    }

(第二种方式:)更改configure重写的源码就不需要注入MyPasswordEncoder这个类了.

  @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
           /* auth
                    .inMemoryAuthentication()
                    .withUser("admin1").password("123456").roles("USER")
                    .and()
                    .withUser("test").password("test123").roles("ADMIN");*/
        
        auth.
                inMemoryAuthentication()
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("ADMIN")
                .and()
                .withUser("test").password(new BCryptPasswordEncoder().encode("test123")).roles("USER");
    }
上一篇下一篇

猜你喜欢

热点阅读