可以看到,在登录之后,我们在请求 /hello 会直接返回hello world , 那是不是只要登录一次,后面就可以一直访问呢?当然不是的,登录成功之后,会将信息保存在session 中,再登录的时候,就会通过session 校验,这样就可以访问到了,当session过期获取我们手动清理掉后,就需要重新登录了。我们来试试。打开控制台,application 中的cookies 中的jsessionid 清理掉。
我们接着请求试试,可以发现删除后,就会重新回到登录界面。
========================================================================
上面我们使用的默认的用户名和密码,但是实际上我们肯定不会这么做的,上面只是说明springboot 完全的集成了Spring security 。下面我们先来简单的配置用户名密码,之所以这样说,因为我们实际过程中应该还是不会这么用的。之所以要讲,让大家了解的更全面,也为下面铺垫。
首先我们来简单的,我们可以直接在application.properties 中配置用户名和密码。来代替默认用户名和密码的效果。
spring.security.user.name=quellanan
spring.security.user.password=123456
spring.security.user.roles=admin
分别是设置用户名,密码,角色。我们这里暂时只用了用户认证,所以角色设不设置无所谓。配置好这些之后我们重启项目在界面上试试再。
没有问题,但是没有什么用,我们实际中是不会这么干的吧。
在内存中配置的话,相对来说要复杂点,我们创建一个config 包,在包下创建SecurityConfig 类继承 WebSecurityConfigurerAdapter
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder()) // 指定加密方式
.withUser(“qaz”).password(passwordEncoder().encode(“123456”)).roles(“admin”)
.and()
.withUser(“test”).password(passwordEncoder().encode(“123456”)).roles(“USER”);
}
@Bean
public PasswordEncoder passwordEncoder() {
// BCryptPasswordEncoder:Spring Security 提供的加密工具
return new BCryptPasswordEncoder();
}
}
这里我们重写了configure(AuthenticationManagerBuilder auth) 方法,就是将定义的用户配置到内存中。这里有一个问题需要说明一下,就是这里配置的话,密码需要用BCryptPasswordEncoder 加密。如果不加密的话,项目编译启动不会报错,但是登陆的时候就会提示账号密码错误。
还有一个问题就是,如果我们在这配置了,那我们在application.peoperties 中配置的就会失效。
上面说的这两种方法,其实都是不常用的,我们在实际项目中根本不会在项目中写死用户信息的。基本上都是存在数据库中。所以下面我们就开始讲解我们最常用的模式吧。
由于这一类,涉及的较多,就单独一级标题出来,不放在二级标题里面了。
=========================================================================
既然是用到数据库,项目中自然要引入数据的配置啦,我这里用的是mysql 和mybatis.
这是整个项目成型后的目录结构,先放出来,大家心里有底,然后一步一步的来。
简单的三张表,user,roles,roles_user 。
下面是 sql。直接执行就可以
/*
Date: 2017-12-26 18:36:12
*/
CREATE DATABASE quellanan
DEFAULT CHARACTER SET utf8;
USE quellanan
;
SET FOREIGN_KEY_CHECKS=0;
– Table structure for roles
DROP TABLE IF EXISTS roles
;
CREATE TABLE roles
(
id
int(11) NOT NULL AUTO_INCREMENT,
name
varchar(32) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
– Records of roles
INSERT INTO roles
VALUES (‘1’, ‘超级管理员’);
INSERT INTO roles
VALUES (‘2’, ‘普通用户’);
INSERT INTO roles
VALUES (‘3’, ‘测试角色1’);
INSERT INTO roles
VALUES (‘4’, ‘测试角色2’);
INSERT INTO roles
VALUES (‘5’, ‘测试角色3’);
– Table structure for roles_user
DROP TABLE IF EXISTS roles_user
;
CREATE TABLE roles_user
(
id
int(11) NOT NULL AUTO_INCREMENT,
rid
int(11) DEFAULT ‘2’,
uid
int(11) DEFAULT NULL,
PRIMARY KEY (id
),
KEY rid
(rid
),
KEY roles_user_ibfk_2
(uid
),
CONSTRAINT roles_user_ibfk_1
FOREIGN KEY (rid
) REFERENCES roles
(id
),
CONSTRAINT roles_user_ibfk_2
FOREIGN KEY (uid
) REFERENCES user
(id
) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=131 DEFAULT CHARSET=utf8;
– Records of roles_user
INSERT INTO roles_user
VALUES (‘1’, ‘1’, ‘1’);
INSERT INTO roles_user
VALUES (‘2’, ‘2’, ‘2’);
INSERT INTO roles_user
VALUES (‘3’, ‘3’, ‘3’);
INSERT INTO roles_user
VALUES (‘4’, ‘1’, ‘4’);
– Table structure for user
DROP TABLE IF EXISTS user
;
CREATE TABLE user
(
id
int(11) NOT NULL AUTO_INCREMENT,
username
varchar(64) DEFAULT NULL,
nickname
varchar(64) DEFAULT NULL,
password
varchar(255) DEFAULT NULL,
enabled
tinyint(1) DEFAULT ‘1’,
email
varchar(64) DEFAULT NULL,
userface
varchar(255) DEFAULT NULL,
regTime
datetime DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
– Records of user
INSERT INTO user
VALUES (‘1’, ‘quellanan’, ‘’, ‘$2a
10
10
10Hv0YGLi/siOswCTP236MtOTWbClcM6rN1LCyqwfRmrwCJZqXHsj5a’, ‘1’, ‘quellanan@qq.com’,‘’, ‘2017-12-08 09:30:22’);
INSERT INTO user
VALUES (‘2’, ‘qaz’, ‘’, ‘$2a$10$6H69XLebCrGhHeHzDXEoH.0x8tMFS0XfdDPwI5s.Eu9pbqRpncA.G’, ‘1’, ‘quellanan@qq.com’,‘’, ‘2017-12-08 09:30:22’);
INSERT INTO user
VALUES (‘3’, ‘wsx’, ‘’, ‘$2a$10$6H69XLebCrGhHeHzDXEoH.0x8tMFS0XfdDPwI5s.Eu9pbqRpncA.G’, ‘1’, ‘quellanan@qq.com’,‘’, ‘2017-12-08 09:30:22’);
INSERT INTO user
VALUES (‘4’, ‘test’, ‘’, ‘$2a$10$6H69XLebCrGhHeHzDXEoH.0x8tMFS0XfdDPwI5s.Eu9pbqRpncA.G’, ‘1’, ‘quellanan@qq.com’,‘’, ‘2017-12-08 09:30:22’);
SET FOREIGN_KEY_CHECKS=1;
我们首先在原先pom 文件基础上增加,如下依赖。
mysql
mysql-connector-java
runtime
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.0
org.apache.commons
commons-pool2
org.projectlombok
lombok
前面三个是mysql 和mybatis的依赖。lombok 是一个工具类插件。
同时我们需要修改一下pom 文件中的build ,不然我们项目可能会找不到mybatis 的xml文件。
src/main/java
**/*.xml
src/main/resources
org.springframework.boot
spring-boot-maven-plugin
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/quellanan?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
这里如果想要打印mybatis 的sql 日志。可以添加一个mybatis-config.xml文件,和application.properties 同目录
<?xml version="1.0" encoding="UTF-8" ?>并在application.properties 中加上
mybatis.config-location=classpath:/mybatis-config.xml
我们在entry 包下创建 RoleEntry。代码如下:
@Getter
@Setter
public class RoleEntry {
private Long id;
private String name;
}
我们在创建 UserEntry ,但是UserEntry 比较特殊,因为我们需要使用Spring security 。所以这里,UserEntry 需要实现 UserDetails。
代码如下:
@Setter
@Getter
public class UserEntry implements UserDetails {
private Long id;
private String username;
private String password;
private String nickname;
private boolean enabled;
private List roles;
private String email;
private String userface;
private Timestamp regTime;
/**
-
获取角色权限
-
@return
*/
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List authorities = new ArrayList<>();
for (RoleEntry role : roles) {
authorities.add(new SimpleGrantedAuthority(“ROLE_” + role.getName()));
}
return authorities;
}
/**
-
获取密码
-
@return
*/
@Override
public String getPassword() {
return password;
}
/**
-
获取用户名
-
@return
*/
@Override
public String getUsername() {
return username;
}
/**
- 用户账号是否过期
*/
@Override
public boolean isAccountNonExpired() {
return true;
}
/**
- 用户账号是否被锁定
*/
@Override
public boolean isAccountNonLocked() {
return true;
}
/**
- 用户密码是否过期
*/
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
- 用户是否可用
*/
@Override
public boolean isEnabled() {
return enabled;
}
}
可以看到,基本上都是重写的方法。也比较简单。
这里我将xml 文件和接口放在一起了,你们也可以在resources 中创建一个mapper,将xml 文件放在哪里。
mapper层没有什么好说的,是mybatis 的一些知识,我们这里讲代码贴出来。
RolesMapper
@Mapper
public interface RolesMapper {
List getRolesByUid(Long uid);
}
RolesMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>SELECT r.* FROM roles r,roles_user ru WHERE r.id
=ru.rid
AND ru.uid
=#{uid}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
最后希望可以帮助到大家!
千千万万要记得:多刷题!!多刷题!!
之前算法是我的硬伤,后面硬啃了好长一段时间才补回来,算法才是程序员的灵魂!!!!
篇幅有限,以下只能截图分享部分的资源!!
(1)多线程(这里以多线程为代表,其实整理了一本JAVA核心架构笔记集)
(2)刷的算法题(还有左神的算法笔记)
(3)面经+真题解析+对应的相关笔记(很全面)
(4)视频学习(部分)
ps:当你觉得学不进或者累了的时候,视频是个不错的选择
在这里,最后只一句话:祝大家offer拿到手软!!
712074084470)]
[外链图片转存中…(img-8UOUuwYB-1712074084470)]
[外链图片转存中…(img-6gWmDsb0-1712074084471)]
[外链图片转存中…(img-ntEg4CS2-1712074084471)]
[外链图片转存中…(img-WvtpEhoP-1712074084472)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-KDiAC8Xr-1712074084472)]
最后希望可以帮助到大家!
千千万万要记得:多刷题!!多刷题!!
之前算法是我的硬伤,后面硬啃了好长一段时间才补回来,算法才是程序员的灵魂!!!!
篇幅有限,以下只能截图分享部分的资源!!
(1)多线程(这里以多线程为代表,其实整理了一本JAVA核心架构笔记集)
[外链图片转存中…(img-yrsDlC1O-1712074084473)]
(2)刷的算法题(还有左神的算法笔记)
[外链图片转存中…(img-7yOkvEpG-1712074084473)]
(3)面经+真题解析+对应的相关笔记(很全面)
[外链图片转存中…(img-9MPOeHEz-1712074084473)]
(4)视频学习(部分)
ps:当你觉得学不进或者累了的时候,视频是个不错的选择
在这里,最后只一句话:祝大家offer拿到手软!!