Spring Security提供了非常好的认证扩展方法,比如:将用户信息存储到内存中,实际开发中用户信息通常在数据库,Spring Security可以实现从数据库读取用户信息,Spring security还支持多种授权方法。
4.3.1 自定义登录页面
Spring Security的默认配置没有明确设定一个登录页面的URL ,因此Spring Security会根据启用的功能自动生成一个登录页面URL ,并使用默认URL处理登录的提交内容,登录后跳转的到默认URL等等。尽管自动生成的登录页面很方便快速启动和运行,但大多数应用程序都希望定义自己的登录页面。
4.3.1.1 认证页面
将security-springmvc工程的login.jsp拷贝到security-springboot下,目录保持一致。
在这里插入代码片
4.3.1.2 配置认证页面
在WebConfig.java中配置认证页面地址:
//默认Url根路径剧阵专至Ij/login ,此url为spring security提供
@0verride
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login-view")
registry.addViewController("login-view").setViewName("login");
}
4.3.1.3 安全配置
在WebSecurityConfig中配置表单登录信息:
(1)允许表单登录 (2 )指定我们自己的登录页,spring security以重定向方式将路径转发到/login-view (3)指定登录处理的URL ,也就是用户名、密码表单提交的目的路径 (4)指定登录成功后的跳转URL (5 )我们必须允许所有用户访问我们的登录页(例如为验证的用户),这个formLogin() .permitAll()方法允许任意用户访问基于表单登录的所有的URL。
4.3.1.4 测试
当用户没有认证时访问系统的资源会重定向到login-view页面
在这里插入代码片
输入账号和密码,点击登录,报错:
在这里插入代码片
问题解决:
spring security为防止CSRF ( Cross-site request forgery跨站请求伪造)的发生,限制了除了get以外的大多数方 法。
解决方法1:
屏蔽CSRF控制,即spring security不再限制CSRF。 配置 WebSecurityConfig
@0verride
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()//屏蔽CSRF控制,即 spring security 不再限制CSRF
}
解决办法2 :
在login.jsp页面添加一个token , spring security会验证token ,如果token合法则可以继续请求。 修改 login.jsp
<form action="login" method="post">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
4.3.2 连接数据库认证
前边的例子我们是将用户信息存储在内存中,实际项目中用户信息存储在数据库中。根据前边对认证流程研究,只需要重新定义UserDetailService即可实现根据用户账号查询数据库。
4.3.2.1 创建数据库
创建user_db数据库
CREATE DATABASE ‘user_db’ CHARACTER SET ‘utf8‘ COLLATE ‘utf8_general_ci’;
创建t_user 表
CREATE TABLE 't_user' (
'id' bigint(20) NOT NULL COMMENT,用户id',
'username' varchar(64) NOT NULL,
'password' varchar(64) NOT NULL,
'fullname' varchar(255) NOT NULL COMMENT,用户姓名',
'mobile' varchar(ll) DEFAULT NULL COMMENT,手机号
PRIMARY KEY ('id') USING BTREE
)ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
4.3.2.2 代码实现
1 )定义dataSource
在application.properties 配置
spring.datasource.url=jdbc:mysql://localhost:3306/user_db
spring.datasource.username=root
spring.datasource.password=mysql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
2)添加依赖
<dependency>
<groupld>org.springframework.boot</groupld>
<artifactld>spring-boot-starter-test</artifactld>
<scope>test</scope>
</dependency>
<dependency>
<groupld>org.springframework.boot</groupld>
<artifactld>spring-boot-starter-jdbc</artifactld>
</dependency>
<dependency>
<groupld>mysql</groupld>
<artifactld>mysql-connector-java</artifactld>
<version>5.1.47</version>
</dependency>
3 )定义Dao
定义模型类型,在model包定义UserDto:
@Data
public class UserDto { private String id;
private String username;
private String password;
private String fullname;
private String mobile;
}
在Dao包定义UserDao :
@Repository
public class UserDao {
@Autowired
ZJdbcTemplate jdbcTemplate;
public UserDto getUserByUsername(String username){
String sql =r,select id,username,password,funname from t_user where username = ?";
List<UserDto> list = jdbcTemplate.query(sqlj new Object[Jlusername}^ new BeanPropertyRowMappero(UserDto. class));
if(list == null && list.size() <= 0)(
return null;
}
return list.get(0);
}
}
4.3.2.3 定义 UserDetailService
在service包下定义SpringDatallserDetailsService :
@Service
public class SpringDatallserDetailsService implements UserDetailsService {
@Autowired
UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//登录账号
System.out. println();
//根据账号去数据库查询...
UserDto user = userDao.getUserByUsername(username);
if(user == null){
return null;
}
//这里暂时使用静态麴居
UserDetails userDetails =User.withUsername(user.getFullname()).password(user.getPassword()).authorities("pl").build();
return userDetails;
}
}
4.3.2.3 测试
输入账号和密码请求认证,跟踪代码。
4.3.2.4 使用BCryptPasswordEncoder
按照我们前边讲的PasswordEncoder的使用方法,使用BCryptPasswordEncoder需要完成如下工作:
1、在安全配置类中定义BCryptPasswordEncoder
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
2、UserDetails中的密码存储BCrypt格式
前边实现了从数据库查询用户信息,所以数据库中的密码应该存储BCrypt格式
package com.uncle.seciruty.springboot.util;
import org.springframework.security.crypto.bcrypt.BCrypt;
/**
* @program: spring-boot-security
* @description:
* @author: 步尔斯特
* @create: 2021-08-06 22:12
*/
public class BCryptUtil {
public static void main(String[] args) {
String hashpw = BCrypt.hashpw("456", BCrypt.gensalt());
System.out.println(hashpw);
boolean checkpw = BCrypt.checkpw("456","$2a$10$bcJXXryMCxXtkxRkG1UekOkOe0BqxiqOYKJzGni64jnyWAD15wmDy");
System.out.println(checkpw);
//123 -> $2a$10$8iHn2TEvyzkUgO2np9glzufe.wtRyjA5u3xfvs/D.9FCzm1XvCAGm
//456 -> $2a$10$bcJXXryMCxXtkxRkG1UekOkOe0BqxiqOYKJzGni64jnyWAD15wmDy
}
}
```**加粗样式**
原文始发于微信公众号(步尔斯特):【微服务|Spring Security⑮】spring security自定义认证
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/48009.html