Spring Security实现JDBC用户登录认证
在搭建博客后端服务框架时,我采用邮件注册+Spring Security登录认证方式,结合mysql数据库,给大家展示下具体是怎么整合的。
本篇是基于上一篇:spring boot实现邮箱验证码注册
1.引入Spring Security相关依赖
<!--spring security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>
2.添加相关页面
2.1 login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Example </title>
</head>
<body>
<div th:if="${param.error}" style="color: red;">
用户名或密码错误!
</div>
<div th:if="${param.logout}" style="color: darkgreen;">
注销成功!
</div>
<form th:action="@{/login}" method="post">
<div><label> 用户名 : <input type="text" name="username"/> </label></div>
<div><label> 密码: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="submit"/> <input type="reset" value="reset"/></div>
</form>
<p>Click <a th:href="@{/welcome}">here</a> go to home page.</p>
</body>
</html>
3.创建User表及实体类
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(100) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`active_code` varchar(100) DEFAULT NULL,
`active_status` int(11) DEFAULT '0',
`roles` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
package com.laoxu.easyblog.entity;
import lombok.Data;
import java.io.Serializable;
/**
* @description: 用户
* @author: luohanye
* @create: 2019-04-17
**/
@Data
public class User implements Serializable {
private Integer id;
private String username;
private String password;
private String email;
// 激活状态 0 未激活 1 已激活
private Integer activeStatus;
// 激活码
private String activeCode;
// 角色
private String roles;
}
4.创建自定义UserDetailService实现类
package com.laoxu.easyblog.service;
import com.laoxu.easyblog.dao.UserDao;
import com.laoxu.easyblog.entity.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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 java.util.ArrayList;
import java.util.List;
/**
* 自定义UserService
*/
@Service
public class MyUserService<T extends User> implements UserDetailsService {
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try {
User user = userDao.selectByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("用户名不存在");
}
//用户权限
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
if (StringUtils.isNotBlank(user.getRoles())) {
String[] roles = user.getRoles().split(",");
for (String role : roles) {
if (StringUtils.isNotBlank(role)) {
authorities.add(new SimpleGrantedAuthority(role.trim()));
}
}
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
5.创建MD5工具类
package com.laoxu.easyblog.common;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* md5工具类
*/
public class MD5Util {
public static final int time = 5;
public static final String SALT = "springsecurity";
/**
* 密码加密方法
*
* @param password
* @return
*/
public static String encode(String password) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("MD5 algorithm not available. Fatal (should be in the JDK).");
}
try {
for (int i = 0; i < time; i++) {
byte[] bytes = digest.digest((password + SALT).getBytes("UTF-8"));
password = String.format("%032x", new BigInteger(1, bytes));
}
return password;
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("UTF-8 encoding not available. Fatal (should be in the JDK).");
}
}
public static void main(String[] args) {
System.out.println(MD5Util.encode("123456"));
}
}
6.创建自定义密码验证类
package com.laoxu.easyblog.common;
import org.springframework.security.crypto.password.PasswordEncoder;
public class MyPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence rawPassword) {
return MD5Util.encode((String) rawPassword);
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
//user Details Service验证
return encodedPassword.equals(MD5Util.encode((String) rawPassword));
}
}
7.添加Spring Security配置
package com.laoxu.easyblog.config;
import com.laoxu.easyblog.common.MyPasswordEncoder;
import com.laoxu.easyblog.entity.User;
import com.laoxu.easyblog.service.MyUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.annotation.Resource;
import javax.sql.DataSource;
/**
* Spring Security配置
*
* @author xusucheng
* @create 2018-10-26
**/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
/* @Autowired
private DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource);
}*/
@Resource
private MyUserService<User> userService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(new MyPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/css/**", "/js/**", "/fonts/**", "/images/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/welcome").hasRole("ADMIN")
.and().formLogin().loginPage("/login").permitAll().defaultSuccessUrl("/welcome")
.and().logout().permitAll()
;
}
@Override
public void configure(WebSecurity web) throws Exception {
//忽略
web.ignoring().antMatchers("/wd/**");
}
}
8.配置视图转发器
package com.laoxu.easyblog.config;
import com.laoxu.easyblog.interceptor.LoginHandlerInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
/**
* @author xusucheng
* @create 2018-10-23
**/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Value("${spring.mvc.view.prefix}")
private String prefix="";
@Value("${spring.mvc.view.suffix}")
private String suffix="";
@Value("${spring.mvc.view.view-name}")
private String viewName="";
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/static/assets/");
registry.addResourceHandler("/wd/**").addResourceLocations("classpath:/wd/");
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/welcome").setViewName("welcome");
}
@Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(prefix);
resolver.setSuffix(suffix);
resolver.setViewClass(JstlView.class);
resolver.setViewNames(viewName);
return resolver;
}
/* @Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/login","/register","/assets/**","/wd/**","/account/changePwd","/account/add");
}*/
}
9.测试
9.1 注册账号
访问:localhost:8080 先注册一个账号,例如:lisi 123
9.2 激活账号
9.3 登录失败,没有ROLE_ADMIN权限


9.4 登录成功,添加用户权限为ROLE_ADMIN

Spring Security实现JDBC用户登录认证的更多相关文章
- Spring Security默认的用户登录表单 页面源代码
Spring Security默认的用户登录表单 页面源代码 <html><head><title>Login Page</title></hea ...
- spring security实现记录用户登录时间等信息
目录 spring security实现记录用户登录时间等信息 一.原理分析 二.实现方式 2.1 自定义AuthenticationSuccessHandler实现类 2.2 在spring-sec ...
- Spring Security 使用数据库用户进行认证
本文参考或摘录自:http://haohaoxuexi.iteye.com/blog/2157769 本文使用Spring Security自带的方式连接数据库对用户进行认证. 1.Spring Se ...
- Spring Security 入门(1-3-1)Spring Security - http元素 - 默认登录和登录定制
登录表单配置 - http 元素下的 form-login 元素是用来定义表单登录信息的.当我们什么属性都不指定的时候 Spring Security 会为我们生成一个默认的登录页面. 如果不想使用默 ...
- spring security 动态 修改当前登录用户的 权限
1.前言 spring security 可以获取当前登录的用户信息,同时提供了接口 来修改权限列表信息 , 使用这个方法 ,可以动态的修改当前登录用户权限. 那么问题来了... 如果我是管理员 ,如 ...
- Spring security 获取当前用户
spring security中当前用户信息 1:如果在jsp页面中获取可以使用spring security的标签库 在页面中引入标签 1 <%@ taglib prefix=" ...
- Spring Boot+Spring Security:获取用户信息和session并发控制
说明 (1)JDK版本:1.8(2)Spring Boot 2.0.6(3)Spring Security 5.0.9(4)Spring Data JPA 2.0.11.RELEASE(5)hiber ...
- Spring Security OAuth2 SSO 单点登录
基于 Spring Security OAuth2 SSO 单点登录系统 SSO简介 单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自 ...
- Spring Security技术栈开发企业级认证与授权(一)环境搭建
本项目是基于慕课网的Spring Security技术栈开发企业级认证与授权,采用IDEA开发,本文章用来记录该项目的学习过程. 慕课网视频:https://coding.imooc.com/clas ...
- Spring Boot+Spring Security+JWT 实现 RESTful Api 认证(二)
Spring Boot+Spring Security+JWT 实现 RESTful Api 认证(二) 摘要 上一篇https://javaymw.com/post/59我们已经实现了基本的登录和t ...
随机推荐
- [转帖]如何监控Redis性能指标(译)
Redis给人的印象是简单.很快,但是不代表它不需要关注它的性能指标,此文简单地介绍了一部分Redis性能指标.翻译过程中加入了自己延伸的一些疑问信息,仍然还有一些东西没有完全弄明白.原文中Metri ...
- [转帖]Linux之pure-ftpd安装和使用
一.pure-ftpd简介 PureFTPd是一款专注于程序健壮和软件安全的免费FTP服务器软件(基于BSD License),以安全和配置简单为设计目标,支持虚拟主机,IPV6,PAM等功能.. ...
- 【转帖】io_uring vs epoll ,谁在网络编程领域更胜一筹?
io_uring vs epoll ,谁在网络编程领域更胜一筹? 2021-12-16 1473举报 简介: 从定量分析的角度,通过量化 io_uring 和 epoll 两种编程框架下的相关操作的耗 ...
- [转贴]Python 中 -m 的典型用法、原理解析与发展演变
在命令行中使用 Python 时,它可以接收大约 20 个选项(option),语法格式如下: python [-bBdEhiIOqsSuvVWx?] [-c command | -m module- ...
- [转帖] Linux命令拾遗-文本处理篇
https://www.cnblogs.com/codelogs/p/16060413.html 简介# 这是Linux命令拾遗系列的第二篇,本篇主要介绍Linux中与文本处理相关的命令,如xargs ...
- Linux 界面能够出现ip地址提示的方法
cat <<EOF >/etc/profile.d/ip.sh if [[ `tty | grep "pts"` ]]; then export PS1='['& ...
- ChatGPT背后的AI背景、技术门道和商业应用(万字长文,建议收藏)
作者:京东科技 李俊兵 各位看官好,我是球神(江湖代号). 自去年11月30日ChatGPT问世以来,迅速爆火出圈. 起初我依然以为这是和当年Transformer, Bert一样的"热点& ...
- Istio安装和部署
Istio的版本对k8s的版本是有要求的,不兼容的版本会引发一些隐蔽的错误,安装前先参考下图 版本 目前支持 发行日期 停止维护 支持的 Kubernetes 版本 未测试,可能支持的 Kuberne ...
- DES加密和base64加密
DES简介:参考知乎 https://www.zhihu.com/question/36767829 和博客https://www.cnblogs.com/idreamo/p/9333753.html ...
- 6.4 Windows驱动开发:内核枚举DpcTimer定时器
在操作系统内核中,DPC(Deferred Procedure Call)是一种延迟执行的过程调用机制,用于在中断服务例程(ISR)的上下文之外执行一些工作.DPC定时器是基于DPC机制的一种定时执行 ...