SpringBoot+SpringSecurity集成权限管理快速打造企业级声明式安全认证授权解决方案之SpringBoot+SpringSecurity+mybatis+mysql

1 主要目的

SpringBoot+SpringSecurity集成权限管理快速打造企业级声明式安全认证授权解决方案之SpringBoot+SpringSecurity+mybatis+mysql

2 spring boot介绍

2.1 spring boot是什么?
Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化Spring应用的初始搭建以及开发过程。
Spring Boot可以轻松创建独立的,生产级的基于Spring的应用程序。
2.2 spring boot解决了哪些问题?
 spring boot 使编码变的更简单
 spring boot 使配置变的更简单
 spring boot 使部署变的更简单
 。。。。

2.2.1 使编码变的简单
在这里插入图片描述

2.2.2 使得配置变的简单
在这里插入图片描述

2.2.3 使得部署变的简单
在这里插入图片描述

3 Spring Boot入门

3.1 Spring boot环境搭建
环境说明:Idea + maven+jdk1.8+mysql

搭建步骤:
一:浏览器输入:start.spring.io
在这里插入图片描述

二:拷贝生成的项目,并使用Idea打开即可

在这里插入图片描述

3.2 Hello World
第一个:创建Controller

@Controller
public class HelloWorldController {

    @RequestMapping("/hello")
    @ResponseBody
    public String showHelloWolrd(){
        return "hello word";
    }
}

第二个:运行main方法

第三个:浏览器输入地址:http://localhost:8080/hello
在这里插入图片描述

项目结构如下:
在这里插入图片描述

总结:
1.创建一个maven工程,然后添加依赖即可(添加parent ,添加相关的启动器,例如:添加web)
2.创建一个引导类(SpringBootAplication.class)
3.创建Controller即可。

4 Spring Boot的属性配置

4.1 application.properties
默认的情况下,springboot 所有的属性配置都在application.properties中进行配置,我们可以在里面添加必要的属性及对应的值,比如:默认的情况下 启动项目,使用端口8080,可以设置端口为其他。例如:
在这里插入图片描述

访问时即可 使用8081.

其他的属性配置,参考如下文档:
https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

4.2 自定义属性值及获取
有时需要自定义配置属性文件,设置值,并在代码中使用它,可以在application.properties中设置。

例如:
 定义值:
在这里插入图片描述
 获取值:

直接通过@value注解获取即可。
在这里插入图片描述

4.3 java config获取属性值
由于如果属性值比较多,一个一个通过@value注解的方式来获取,比较繁琐,可以通过java类进行映射,将属性值映射到java类中,并交给spring管理,使用时直接注入即可,比较方便。

例如:

第一个:定义属性:
在这里插入图片描述

第二个:定义映射属性的类: 并设置getter和setter方法
在这里插入图片描述

@ConfigurationProperties(prefix = "mail")
@Component
public class MailPropertiesConfig {
    private String host;
    private String username;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

第三个:使用属性文件中的值:直接注入即可。
在这里插入图片描述

5 mybatis的集成

在正式的项目中,需要将数据从数据库中查询出来展示到前台相关的业务逻辑中。所有持久层的技术必不可少,这里我们介绍现阶段比较流行的持久层框架mybatis集成到springboot中。

5.1 mybatis集成的环境搭建
第一个:添加mybatis、mysql的依赖坐标:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.1</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

第二个:创建数据库实例,并配置连接信息
在这里插入图片描述

创建数据库实例,并导入如上图所示的sql。

spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/sbc
spring.datasource.username=root
spring.datasource.password=itcast

第三个:创建mapper(dao)接口

public interface UserMapper {

    @Select(value = "select * from user where username=#{username}")
    public User selectByUsername(String username);
}

第四个:扫描mapper接口所在的包,将由spring创建这些接口的代理对象
在这里插入图片描述

第五:测试,在test目录下实现测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootApplicationTests {

   @Autowired
   private UserMapper mapper;
   @Test
   public void contextLoads() {
      System.out.println(mapper.selectByUsername("zhangsan"));
   }

}

测试OK

集成mybatis 总结:
1.添加mybaits的启动器的依赖,
2.添加mysql的依赖
3.配置连接池的信息(application.properties配置连接数据库的用户名和密码以及数据库驱动,URL)
4.编写mapper接口(相当于是Dao)
5.测试

5.2 页面展示用户相关信息
5.2.1 编写service 接口及实现类

public interface UserService {
    public User selectUserByUsername(String username);
}
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public User selectUserByUsername(String username) {
        return userMapper.selectByUsername(username);
    }
}

结构如下图:

在这里插入图片描述

5.2.2 编写controller

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/user/info")
    @ResponseBody
    public User info(){
        return userService.selectUserByUsername("zhangsan");
    }
}

其他的CURD与此类似,此处不再讨论。

6 spring security介绍

随着互联网的发展,当我们在淘宝或者京东上很方便的购物时,是否会想到我们的这种便利,如果不能保证我们的账号安全的话,可想而知会出现什么样的后果。所以,系统的安全性显得尤为重要。当用户购买下订单时,系统必须要验证此用户的身份和相应的权限。而如果使用springmvc的拦截器,验证过程显得非常繁琐。利用spring boot 和spring security将大大简化我们的配置项和提高网站的安全性。
Spring Security是一个基于spring专注于为Java应用程序提供身份验证(Authentication)和授权(Authorization)的框架。同时在 Web 请求级和方法调用级处理身份确认和授权。

7 spring security入门

springsecurity 使用4.2.4.RELEASE版本。

第一个:添加依赖:

org.springframework.boot
spring-boot-starter-security

第二个:测试,访问之前写好的hello world
启动项目 并在浏览器中输入:http://localhost:8081/user/info
如图:
在这里插入图片描述

默认的情况下:spring boot 和spring security已经集成 并拦截所有的请求,需要验证通过才能放行。弹出框的方式 是默认的spring security的认证方式即(http basic的方式)

默认的情况下:用户名为user 密码为每次启动项目是所生成的的随机字符串,如图:

在这里插入图片描述

8 表单登录认证

正常的情况下,目前的验证的方式不是我们想要的,更多的时候,需要有一个表单的登录界面来进行用户的身份确认(认证)。所以此时不能满足我们的需要,我们修改成表单的方式来登录。

第一个:创建配置类继承WebSecurityConfigurerAdapter,进行配置。

@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()//授权所有的请求 都需要通过认证才能访问
                .and()//并且
                .formLogin();//采用表单提交的方式进行认证登录
    }
}

第二个:启动项目,测试;输入地址:http://localhost:8081/user/info

输入用户名和密码即可。
在这里插入图片描述

9 自定义用户认证

认证包括三个方面:第一个 获取用户的信息,第二个 校验用户 第三个 密码加密

用户的信息获取主要使用mybatis获取用户信息,将获取到的用户的信息和页面传递过来的用户的信息进行匹配,如果成功,则放行,如果失败,则返回错误的信息。匹配的过程是由spring security自己本身来实现的。

用户的信息获取需要通过实现一个接口:UserDetailsService 来实现这个功能。

@Component
public class MyUserDetailsService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //从数据库中获取到用户的信息
        return new User(username,"123456", AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }
}

此时任何的用户只要输入了密码为123即可登录成功。
因此需要从数据库中查询数据,并校验数据的密码是否正确

@Component
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserService userService;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //从数据库中获取到用户的信息
        com.itheima.springboot.pojo.User user = userService.selectUserByUsername(username);
        if(user==null){
            return null;//表示不存在
        }
        
        return new User(username,user.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }
}

此时如果还有其他的需求,比如:当用户名和密码都正确但是有时这个用户已经被冻结了,此时也不能登录成功,如果要实现这个需求,那么需要对UserDetails接口说明一下。代码需要重新构造:

@Component
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserService userService;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //从数据库中获取到用户的信息
        com.itheima.springboot.pojo.User user = userService.selectUserByUsername(username);
        if(user==null){
            return null;//表示不存在
        }

        //校验用户是否已经被冻结  用户已经被冻结
        boolean flagNonlock = false;//已经被冻结

//        return new User(username,user.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
        return new User(username,user.getPassword(),true,true,true,flagNonlock, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }
}

此时,用户查询的数据的数据是明文的,在企业开发中,密码需要加密进行处理,不能以明文展示。此时需要加密。在spring security 中,处理加密的是一个passwordEncoder接口。

只需配置一个passwordEncoder接口的实现类即可。

首先配置passwordEncoder:

@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder createPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }

    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()//授权所有的请求 都需要通过认证才能访问
                .and()//并且
                .formLogin();//采用表单提交的方式进行认证登录

    }
}

修改校验逻辑:

@Component
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //从数据库中获取到用户的信息
        com.itheima.springboot.pojo.User user = userService.selectUserByUsername(username);
        if(user==null){
            return null;//表示不存在
        }
        //进行加密;注意此处不应该这么写,此处的方法应当在用户注册的时候调用此方法进行加密处理,验证身份时直接获取数据库中加过密的信息即可。
        String encode = passwordEncoder.encode(user.getPassword());
        System.out.println("密码》》》"+encode);

        //校验用户是否已经被冻结  用户已经被冻结
//        boolean flagNonlock = true;
      return new User(username,encode, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
//        return new User(username,encode,true,true,true,flagNonlock, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }
}

自定义用户认证
总结:
1.获取用户的信息的校验(UserDetailsService)
2.处理用户的校验的业务逻辑处理(UserDetails)
3.密码的加密(PasswordEncoder)—BCryptPasswordEncoder

10 源码地址

https://github.com/YouAreOnlyOne/SpringBootSecurity

发布了52 篇原创文章 · 获赞 37 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/u014374009/article/details/103791462
今日推荐