2021-12-10SpringSecurity安全框架(一)基于内存中的用户信息,基于JDBC用户认证

基于内存中的用户信息:

继承类,重写方法,来实现自定义认证信息

@Configuration //相当于配置类,返回值是Java对象,对象放到spring容器之中
@EnableWebSecurity//表示启用安全框架功能

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
//启用方法级别的认证 ,表示可以启用@preAuthorize 和@postAuthorize
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    //方法中配置用户和密码的信息,作为登录的信息
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        PasswordEncoder pe = passwordEncoder();
        auth.inMemoryAuthentication()
                .withUser("zhangsan")
                .password(pe.encode("123456"))
                .roles("normal");
        auth.inMemoryAuthentication()
                .withUser("lisi")
                .password(pe.encode("123456"))
                .roles("normal");
        auth.inMemoryAuthentication()
                .withUser("admin")
                .password(pe.encode("admin"))
                .roles("admin","normal");
    }
    @Bean
    public PasswordEncoder passwordEncoder(){
        //实现类,实现类是加密算法
        return new BCryptPasswordEncoder();
    }
}
//controller
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String sauHello(){
        return "使用内存中的用户信息";
    }
    //指定normal和admin角色可以访问的方法
    @RequestMapping("/helloUser")
    @PreAuthorize(value = "hasAnyRole('admin','normal')")
    public String HelloUser(){
        return "HEllo 拥有normal以及admin角色的用户";
    }

    @RequestMapping("/helloAdmin")
    @PreAuthorize(value = "hasAnyRole('admin')")
    public String HelloAdmin(){
        return "HEllo 拥有admin角色的用户";
    }
}

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

5版本要求必须加密!

基于角色的Role的身份认证,同一个用户可以有不同的角色。同时可以开启对方法级别的

1.设置用户的角色

继承WebSecurityConfigurerAdapter

重写configure方法,指定用户的roles

2.在类的上面加入启用方法级别的注解 

//启用方法级别的认证 ,表示可以启用@preAuthorize 和@postAuthorize
@EnableGlobalMethodSecurity(prePostEnabled = true)

3.在处理器方法的上面加入角色的信息,指定方法可以访问的角色列表。

@PreAuthorize(value = "hasAnyRole('admin','normal')")

 基于JDBC用户认证

从Mysql获取用户的身份信息(用户名称,密码,角色)

1.在spring security框架对象用户信息的表示类是UserDetails

UserDetails 是一个接口,高度抽象的用户信息类

User类:是UserDetails接口的实现类,构造方法有三个参数:username,password,authorities,需要向spring security提供user对象 

2.实现userDetailsService接口。

重写方法userDetails loadUserByname()

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
//启用方法级别的认证 ,表示可以启用@preAuthorize 和@postAuthorize
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    @Qualifier("MyUserDetailService")
    private UserDetailsService userDetailsService;
    //方法中配置用户和密码的信息,作为登录的信息
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }
}

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String sauHello(){
        return "使用内存中的用户信息";
    }
    //指定normal和admin角色可以访问的方法
    @RequestMapping("/helloUser")
    @PreAuthorize(value = "hasAnyRole('admin','normal')")
    public String HelloUser(){
        return "HEllo 拥有normal以及admin角色的用户";
    }

    @RequestMapping("/helloAdmin")
    @PreAuthorize(value = "hasAnyRole('admin')")
    public String HelloAdmin(){
        return "HEllo 拥有admin角色的用户";
    }
}

import cn.tedu.entity.UserInfo;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserInfoDao extends JpaRepository<UserInfo,Long> {
 //按照username查询数据库信息
    UserInfo findByUsername(String username);
}


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Data
@AllArgsConstructor
@NoArgsConstructor
//当前类是一个实体类,表示数据库中的一个表
@Entity
public class UserInfo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    private String role;
}

import cn.tedu.dao.UserInfoDao;
import cn.tedu.entity.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
public class JdbcInit {
    @Autowired
    private UserInfoDao dao;
    @PostConstruct
    public void init(){
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    UserInfo u=new UserInfo();
    u.setUsername("zhangsan");
    u.setPassword(encoder.encode("123456"));
    u.setRole("normal");
    dao.save(u);

    u=new UserInfo();
    u.setUsername("admin");
    u.setPassword(encoder.encode("admin"));
    u.setRole("admin");
    dao.save(u);
}
}

import cn.tedu.dao.UserInfoDao;
import cn.tedu.entity.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
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.Component;

import java.util.ArrayList;
import java.util.List;
@Component("MyUserDetailService")
public class MyUserDetailService implements UserDetailsService {
    @Autowired
    private UserInfoDao dao;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserInfo userInfo=null;
        User user=null;
        if(username !=null){
            userInfo=dao.findByUsername(username);
        }
        if(userInfo!=null) {
            List<GrantedAuthority> list = new ArrayList<>();
            //角色固定写法
            GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_"+userInfo.getRole());
            list.add(authority);
            user = new User(userInfo.getUsername(),userInfo.getPassword(),list);
        }
        //创建User对象

        return user;
    }
}

//application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/springdb
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.generate-ddl=false
spring.jpa.show-sql=true
spring.jpa.database=mysql
#自动生成
spring.jpa.hibernate.ddl-auto=update

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值