SpringSecurity(二)------数据库简单认证------简单授权

一. 准备数据库

二. 我的login.html登录页面 

三. 配置自定义表单 

        设置登录成功与失败的页面

        在上一个文章的基础至上进行添加内容完成根据数据库认证操作

        *.自定义表单

                  分别是 认证页面 认证成功页面 认证失败页面 

                  写完这个地方可以访问 http://localhost:8080/login.html 自己的登录页面这个路径来查看是否配置成功

http.formLogin()
                .loginPage("/login.html").permitAll()// 登录的页面是login.html
                .defaultSuccessUrl("/home.html") // 访问输入login.html 成功之后默认跳转的页面
                .failureUrl("/fail.html") // 访问失败的跳转页面
                .usernameParameter("uname") // 默认的name值为username 改为自己想改的 在login.html页面
                .passwordParameter("pwd")   //默认的password值为password 改为自己想改的 在login.html页面
                .loginProcessingUrl("/mylogin").permitAll()

        ;

四. 配置自定义用户

        因为需要基于数据库用户进行登录所以需要进行配置用户信息---数据库在最上方

    1. 设置加密密码

                添加一个测试类

                       首先 加jar包

<!--   加test测试依赖   -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>2.7.17</version>
</dependency>

                       创建测试类 

 

   2. 设置配置类加密密码

          在配置类里面添加一个@Bean

         @Bean 与 @Compponent 有什么不同

         @Compponent 放在类上使用

         @Bean 可以放在方法上使用 

在 configure(AuthenticationManagerBuilder auth) 部分进行对密码加密

/**
     * 配置用户的信息
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 不能使用明文密码
        // 配置使用的密码是什么
        PasswordEncoder passwordEncoder = getPasswordEncoder();



        // 不用固定密码了 下面开始从数据库查数据
        String pwd = passwordEncoder.encode("dys");// 加密之后的密码
        // 解析密码吗的时候 需要看你使用的加密规则  是什么   加密和解密务必使用同一套规则
        System.out.println("pwd = " + pwd);
        // 在内存中配置认证的信息
        auth.inMemoryAuthentication()
                .passwordEncoder(passwordEncoder)// 加密解密的规则
                .withUser("dys").password(pwd).roles("admin");

    }

在刚创建的测试类里进行使用 

// 测试工具类
@SpringBootTest(classes = MySpringsecuity.class)
public class MyTest {
    // 调用在 MySecurityConfig 里写好的密码加密 对下方密码进行加密操作
    @Resource
    PasswordEncoder passwordEncoder;
    @Test
    public void test(){
        // 对下方密码进行加密操作
        String pwd = "123456";
        String encode = passwordEncoder.encode(pwd);
        System.out.println(encode);
        //加密之后: $2a$10$4nzPl.SorSWhJDm.r2WiEuGQaPlQVOOsuTE86gUKGe7P0ksQraXoy
    }
}

五. 设置权限 service业务层

 创建 UserServiceImpl 需要实现一个接口 名字为UserDetailService  是框架自带的一个接口

需要进行配置 配置完之后即可使用

编写配置文件

        加密密码部分进行修改   加密的时候从service走一遍 到这里 service已经可以收到username名

 /**
     *     从数据库查询需要注入的类  当前项目只有UserServiceImpl实现了userDetailsService
     *     所以理所当然注入的是当前项目只有UserServiceImpl实现了userDetailsService
      */
    @Resource
    private UserDetailsService userDetailsService;
    /**
     * 配置用户的信息
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 不能使用明文密码
        // 配置使用的密码是什么
        PasswordEncoder passwordEncoder = getPasswordEncoder();



        // 不用固定密码了 下面开始从数据库查数据
        /*String pwd = passwordEncoder.encode("dys");// 加密之后的密码
        // 解析密码吗的时候 需要看你使用的加密规则  是什么   加密和解密务必使用同一套规则
        System.out.println("pwd = " + pwd);
        // 在内存中配置认证的信息
        auth.inMemoryAuthentication()
                .passwordEncoder(passwordEncoder)// 加密解密的规则
                .withUser("dys").password(pwd).roles("admin");*/

        // 通过userDetailsService从数据库查询用户信息  .passwordEncoder(passwordEncoder)配置密码不能是明文的解析器
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);

    }

六. 根据数据库进行查询 

        写完之后访问的路径:标题icon-default.png?t=N7T8http://localhost:8080/home.html

        1.加jar包

<!--  mybatis包   连接数据库-->
<dependency>
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>1.3.3</version>
</dependency>

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.44</version>
</dependency>

         2.加application配置文件

spring:  
  datasource: # 连接数据库  四大金刚 驱动 url 用户名 密码
    url: jdbc:mysql://localhost:3306/springboottest?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    password: 123456
    username: root
    driver-class-name: com.mysql.jdbc.Driver

 

        3.添加实体类

        4.添加Mapper层(dao层)

                !  !  ! 写mapper层之前不要忘了在启动类加上

        @MapperScan("com.aaa.mapper")

         

5.编写Service层 

        所有注释都在代码中

package com.aaa.service;

import com.aaa.mapper.UserMapper;
import com.aaa.entity.MyUser;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * implements UserDetailsService 是SpringSecurity框架自带的接口
 * 在需要认证的时候需要走这个service 需要在MyServiceConfig 里进行配置
 */
@Service
public class UserServiceImpl implements UserDetailsService {
    @Resource
    private UserMapper userDao;
    /**
     * Spring username 代表前台传过来的用户名
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 在MySecurityConfig里配置完之后这里就可以获取到用户user了
        System.out.println(username);
        MyUser myUser = userDao.selectAll(username);
        //能获取到之后 根据username(名字)去数据库中查询
        // 判断是否从数据库中查到数据 如果没有查到数据则抛出异常
        if (myUser==null) {
//            如果没有查到 没有登录
            System.out.println("没有这个用户");
            throw new UsernameNotFoundException("没有这个用户");
        }
            /**
             * public User(String username, String password, Collection<? extends GrantedAuthority> authorities) {
             *         this(username, password, true, true, true, true, authorities);
             *     }
             *   使用这个构造方法
             *   需要三个参数 String username, String password, Collection
             *   第一个传账号
             *   第二个传密码
             *   第三个传这个用户所拥有的权限
             */
            List<SimpleGrantedAuthority> list = new ArrayList<>();
            /**
             * 这里写菜单管理跟角色
             * 角色 官方推荐 角色使用 ROLE_ 开头 后面加名字
             */
            list.add(new SimpleGrantedAuthority("ROLE_ADMIN")); // 第一个角色
            list.add(new SimpleGrantedAuthority("ROLE_USER")); // 第二个角色
            list.add(new SimpleGrantedAuthority("menu")); // 菜单管理
//            // 这里的User不是自己写的类 而是 UserDetails 里的一个实现类
            return new  User(myUser.getUsername(),myUser.getPwd(),list);



    }
}

       认证到这里已经结束

6.修改配置类

        写完这里就可以运行了        

        详细注释代码中

7. 上方配置完登录成功之后查询用户全部信息

        这里与上方浏览器的开始访问路径不同http://localhost:8080/user

        查询用户全部信息一共有三种方式 编写有些许区别但是用途相同

        创建一个controller层 

         第一种

 /**
     * 第一种方式
     * principal 代表了用户的全部信息
     * @return
     */
@GetMapping
    public Principal getUser(Principal principal){
        // 主题 principal代表了用户信息 里面有所有用户的信息 ---- 浏览器直接访问http://localhost:8080/user
        return principal;
    }

 

        第二种

/**
     * 第二种方式 从框架内获取到
     * @return
     */
    @GetMapping
    public User getUser(){
        User principal = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return principal;
    }

         第三种 

/**
     * 第三种方式 跟第二种方式想比少了中间的一串
     * @param authentication
     * @return
     */
    @GetMapping
    public User getUser(Authentication authentication){
        return (User) authentication.getPrincipal();
    }

 七. 简单授权

        1.编写Controller层

        2.编写配置类

@Override
    protected void configure(HttpSecurity http) throws Exception {

        http.formLogin()
                .loginPage("/login.html").permitAll()// 登录的页面是login.html
                .defaultSuccessUrl("/home.html") // 访问输入login.html 成功之后默认跳转的页面
                .failureUrl("/fail.html") // 访问失败的跳转页面
                .usernameParameter("uname") // 默认的name值为username 改为自己想改的 在login.html页面
                .passwordParameter("pwd")   //默认的password值为password 改为自己想改的 在login.html页面
                .loginProcessingUrl("/mylogin").permitAll()

        ;
        /**
         *  设置授权 除了这里设置的用户名 其他的一律不可通过 hasRole 这里不需要写Role_框架下会自动加 hasRole只能设置一个用户名
         *  访问时输入的账号为UserServiceImpl中 if判断判断的""中的内容 如果这个账号有下方设置的权限则成功 没有则跳转403页面
         */
        //http.authorizeRequests().antMatchers("/test").hasRole("ADMIN1");
        // 与上面相同 可以设置多个用户名 主要满足其中一个即可
        http.authorizeRequests().antMatchers("/test").hasAnyRole("ADMIN1","ADMIN");
        // 根据菜单判断 逻辑跟上方用户名相同 都是如果能判断到就成功 不能就 403
        //http.authorizeRequests().antMatchers("/test").hasAuthority("menu");

        // 没有权限时登录报错403 配置403页面 设置页面 403.html
        http.exceptionHandling().accessDeniedPage("/403.html");

        // 除了放行之外的其他的路径全部需要认证
        http.authorizeRequests().anyRequest().authenticated();
        // 由于我们设置的 登录是一个html页面
        http.csrf().disable();

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值