首页 > 其他分享 >security自定义数据源

security自定义数据源

时间:2022-10-09 18:09:36浏览次数:50  
标签:自定义 数据源 springframework manager 123 org import security


security默认使用的就是内存方式定义数据源

一、基于内存的数据源

1、配置文件方式

默认的用户定义在SecurityProperties里边,是一个静态内部类,如果要定义自己的用户名密码,必然是要去覆盖默认配置,在配置文件中配置

spring.security.user.name=admin
spring.security.user.password=admin
spring.security.user.roles=ADMIN

此时重启项目,就可以使用自己定义的用户名/密码登录了。

2、配置类中重写configure方式

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Bean
PasswordEncoder passwordEncoder() {
//暂时先不给密码进行加密,所以返回 NoOpPasswordEncoder 的实例
return NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
//如果需要配置多个用户,用 and 相连
.withUser("123")
.password("123").roles("admin");
}
}

3、配置类中重写userDetailsService方式

通过重写 WebSecurityConfigurerAdapter 中的 userDetailsService 方法来提供一个 UserDetailService 实例进而配置多个用户:

@Configuration
public class SecurityConfig1 extends WebSecurityConfigurerAdapter {

@Bean
PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
@Override
@Bean
public UserDetailsService userDetailsServiceBean() throws Exception {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("admin").password("admin").roles("admin").build());
manager.createUser(User.withUsername("123").password("123").roles("user").build());
return manager;
}
}

4、自定义实现类方式

重写UserDetailsService接口中的loadUserByUsername方法,并在配置类型申明

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
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.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;

/**
* 自定义认证服务实现security中的方法
*/
@Service
public class MyUserDetailsServiceImpl implements UserDetailsService {

//实现security接口类userdetails唯一方法
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {

//这个设置一个角色
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList("role");

return new User("123",getPass(),authorities);
}

//对配置的用户密码123进行加密
public String getPass(){
return new BCryptPasswordEncoder().encode("123");
}
}
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.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.annotation.Resource;

@Configuration
public class SecurityConfig1 extends WebSecurityConfigurerAdapter {

//注入自己的实现类
@Resource
private MyUserDetailsServiceImpl userDetailsService;
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}

 总结:以上四种基于内存的方式认证推荐第二种

二、基于数据库数据源

1、基于默认的数据库模型认证

UserDetailsService 都有哪些实现类

security自定义数据源_mysql

可以看到,在几个能直接使用的实现类中,除了 InMemoryUserDetailsManager 之外,还有一个 JdbcUserDetailsManager,使用 JdbcUserDetailsManager 可以让我们通过 JDBC 的方式将数据库和 Spring Security 连接起来。

JdbcUserDetailsManager 自己提供了一个数据库模型,这个数据库模型保存在如下位置:

org/springframework/security/core/userdetails/jdbc/users.ddl

这里面sql语句如下

create table users(username varchar_ignorecase(50) not null primary key,password varchar_ignorecase(500) not null,enabled boolean not null);
create table authorities (username varchar_ignorecase(50) not null,authority varchar_ignorecase(50) not null,constraint fk_authorities_users foreign key(username) references users(username));
create unique index ix_auth_username on authorities (username,authority);

可以看到,脚本中有一种数据类型 varchar_ignorecase,这个其实是针对 HSQLDB 数据库创建的,而我们使用的 MySQL 并不支持这种数据类型,所以这里需要大家手动调整一下数据类型,将 varchar_ignorecase 改为 varchar 即可。

修改完成后,创建数据库,执行完成后的脚本。

执行完 SQL 脚本后,我们可以看到一共创建了两张表:users 和 authorities。

  • users 表中保存用户的基本信息,包括用户名、用户密码以及账户是否可用。
  • authorities 中保存了用户的角色。
  • authorities 和 users 通过 username 关联起来。

配置完成后,接下来,我们将 InMemoryUserDetailsManager 提供的用户数据用 JdbcUserDetailsManager 代替掉,如下:

@Autowired
DataSource dataSource;
@Override
@Bean
protected UserDetailsService userDetailsService() {
JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
manager.setDataSource(dataSource);
if (!manager.userExists("admin")) {
manager.createUser(User.withUsername("admin").password("123").roles("admin").build());
}
if (!manager.userExists("123")) {
manager.createUser(User.withUsername("123").password("123").roles("user").build());
}
return manager;
}
  • 首先构建一个 JdbcUserDetailsManager 实例。
  • 给 JdbcUserDetailsManager 实例添加一个 DataSource 对象。
  • 调用 userExists 方法判断用户是否存在,如果不存在,就创建一个新的用户出来(因为每次项目启动时这段代码都会执行,所以加一个判断,避免重复创建用户)。
  • 用户的创建方法和我们之前 InMemoryUserDetailsManager 中的创建方法基本一致

因为要连接数据库,所以还需导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

配置文件配置

spring.datasource.username=root spring.datasource.password=root spring.datasource.url=jdbc:mysql:///security?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

2、自定义数据库认证

Spring Security适应系统,而非让系统适应Spring Security,是Spring Security框架开发者和使用者的共识,上面使用了 InMemoryUserDetailsManager 和 JdbcUserDetailsManager 两个UserDetailsService 实现类。生效方式也很简单,只需加入 Spring 的 IoC 容器,就会被 Spring Security自动发现并使用。自定义数据库结构实际上也仅需实现一个自定义的UserDetailsService。

UserDetailsService仅定义了一个loadUserByUsername方法,用于获取一个UserDetails对象。UserDetails对象包含了一系列在验证时会用到的信息,包括用户名、密码、权限以及其他信息

这里结合mybatis认证,需要导入的依赖

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.0.0</version>
</dependency>
<dependency>
     <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
</dependency>

 自定义类

@Service
public class MyUserDetailsServiceImpl implements UserDetailsService {

@Resource
private UserDao userDao;
//实现security接口类userdetails唯一方法
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
SysUser user = userDao.getUserByUserName(userName);
//这里查出结果如:userName = "admin" passWord="$2a$10$FsNmqBMoxqRQAzcjvF8YD.Sqh3SaSkO40FfuC.VraGuKTcTeC3wDm";密码是经过BCryptPasswordEncoder加密的
if(user==null){
throw new UsernameNotFoundException("用户不存在");
}
//这个设置一个角色
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList("role");

return new User(user.getUserName(),user.getPassWord(),authorities);
}
}

配置类

@Configuration
public class SecurityConfig1 extends WebSecurityConfigurerAdapter {

//注入自己的实现类
@Resource
private MyUserDetailsServiceImpl userDetailsService;

@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}

标签:自定义,数据源,springframework,manager,123,org,import,security
From: https://blog.51cto.com/u_11334685/5740956

相关文章

  • 4、security之自定义数据源
    security默认使用的就是内存方式定义数据源一、基于内存的数据源1、配置文件方式默认的用户定义在SecurityProperties里边,是一个静态内部类,如果要定义自己的用户名密码,必然......
  • security 会话并发管理
    一、简介会话指得是浏览器和服务端通过session交互过程二、会话并发管理1、什么是会话并发当前系统中,同一个用户是否可以在多台设备登录,springsecurity默认没有限制,可以在多......
  • Spring多数据源配置
    Spring多数据源配置,这里持久层框架使用mybatis,集成Mybatis多数据源有两种方式:1、创建多个SqlSessionFactory,扫描每个SqlSessionFactoryBean对应的包,形成了每个Factory对应一......
  • Springboot自定义Stater
    1、默认启动器Boot会将项目中常用的场景做成对应的starter启动器,项目中涉及到什么场景就引入该场景对应的启动器,项目中引入这些启动器之后,和这个starter相关的依赖也会被引......
  • springCloud Eureka 注册中心,注册的服务自定义名字,和显示ip地址
     在微服务中,在注册中心中,有这样的需求,就是我们要给我们的服务名字,起个其他的名字,不带主机名的那种。 还有就是,我们需要看下注册中心的服务的 ip地址 和 端口号,方便来查......
  • 锁定屏幕时接收用户输入的快捷键热键并执行自定义AutoHotkey脚本-2022年10月8日
    锁定屏幕时接收用户输入的快捷键热键并执行自定义AutoHotkey脚本-2022年10月8日   到淘宝网店铺Knight20搜索“USB无线脚踏开关自定义快捷组合电路板按键模拟小......
  • WordPress自定义文章类型
    WordPress里面内置了两种常用的PostType:Post(文章)、Page(页面),分别用来展示两种类型的内容,一种是相对动态的文章,另一种是相对固定的页面。除此之外,WordPress还内置了其......
  • 【Java基础】异常概述、try-catch、throws方式处理异常及自定义异常
    目录​​一、异常的概述​​​​二、try-catch方式处理异常​​​​三、Throwable成员方法​​​​四、throws方式处理异常​​​​五、自定义异常​​一、异常的概述   ......
  • Java服务发起HTTPS请求报错:PKIX path building failed: sun.security.provider.certpa
    Java服务发起HTTPS请求报错:PKIXpathbuildingfailed:sun.security.provider.certpath.SunCertPathBuilderException1.从域名的https导出下载证书文件下载证书第一步是......
  • springboot项目编译时,使用自定义注解类找不到符号
    springboot项目编译时,使用自定义注解类找不到符号Java项目编译时,使用自定义注解类找不到符号Spring-boot项目编辑器:idea问题:编译时找不到符号。项目中用到了自定义注解类......