在搭建博客后端服务框架时,我采用邮件注册+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用户登录认证的更多相关文章

  1. Spring Security默认的用户登录表单 页面源代码

    Spring Security默认的用户登录表单 页面源代码 <html><head><title>Login Page</title></hea ...

  2. spring security实现记录用户登录时间等信息

    目录 spring security实现记录用户登录时间等信息 一.原理分析 二.实现方式 2.1 自定义AuthenticationSuccessHandler实现类 2.2 在spring-sec ...

  3. Spring Security 使用数据库用户进行认证

    本文参考或摘录自:http://haohaoxuexi.iteye.com/blog/2157769 本文使用Spring Security自带的方式连接数据库对用户进行认证. 1.Spring Se ...

  4. Spring Security 入门(1-3-1)Spring Security - http元素 - 默认登录和登录定制

    登录表单配置 - http 元素下的 form-login 元素是用来定义表单登录信息的.当我们什么属性都不指定的时候 Spring Security 会为我们生成一个默认的登录页面. 如果不想使用默 ...

  5. spring security 动态 修改当前登录用户的 权限

    1.前言 spring security 可以获取当前登录的用户信息,同时提供了接口 来修改权限列表信息 , 使用这个方法 ,可以动态的修改当前登录用户权限. 那么问题来了... 如果我是管理员 ,如 ...

  6. Spring security 获取当前用户

    spring security中当前用户信息 1:如果在jsp页面中获取可以使用spring security的标签库 在页面中引入标签   1 <%@ taglib prefix=" ...

  7. 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 ...

  8. Spring Security OAuth2 SSO 单点登录

    基于 Spring Security OAuth2 SSO 单点登录系统 SSO简介 单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自 ...

  9. Spring Security技术栈开发企业级认证与授权(一)环境搭建

    本项目是基于慕课网的Spring Security技术栈开发企业级认证与授权,采用IDEA开发,本文章用来记录该项目的学习过程. 慕课网视频:https://coding.imooc.com/clas ...

  10. Spring Boot+Spring Security+JWT 实现 RESTful Api 认证(二)

    Spring Boot+Spring Security+JWT 实现 RESTful Api 认证(二) 摘要 上一篇https://javaymw.com/post/59我们已经实现了基本的登录和t ...

随机推荐

  1. 神经网络优化篇:详解调试处理(Tuning process)

    调试处理 关于训练深度最难的事情之一是要处理的参数的数量,从学习速率\(a\)到Momentum(动量梯度下降法)的参数\(\beta\).如果使用Momentum或Adam优化算法的参数,\(\be ...

  2. 使用requests爬虫遇到的一个奇葩的问题:UnicodeEncodeError: 'latin-1' codec can't encode character

    每一位成功的程序员,背后也许都站着无数的秃头的男人--为其提供各种开发工具&代码库,当然也包括-- 各种玄学bug-- 玄学的开端 最近在用Python做一个爬虫项目的时候遇到一个很奇怪的问题 ...

  3. JVM内存用量的再学习

    JVM内存用量的再学习 背景 最近解决一个SQLServer的问题耗时很久. 最终找到了一个看似合理的问题解释. 但是感觉不能只是总结于数据库方面 因为为了解决这个问题增加了很多监控措施. 所以想就这 ...

  4. [转帖]Kafka 核心技术与实战学习笔记(七)kafka集群参数配置(上)

    一.Broker 端参数 Broke存储信息配置 log.dirs:非常重要,指定Broker需要使用的若干文件目录路径,没有默认值必须亲自指定. log.dir:他只能表示单个路径,补充上一个参数用 ...

  5. Linux时间戳转换成易读格式的方法

    背景 最近一直在学习Redis相关的知识. 其中遇到了一个redis monitor的命令 但是这里有一个问题是: 原生命令查询出来的时间是Unix时间戳格式的. 不太好发现查看与进行对照. 所以今天 ...

  6. kettle系统列文章03---如何建立一个作业

    上篇文章我们建立好了转换,我们希望这个转换可以做成定时任务,每一分钟执行一次 第一步:创建作业开始节点:文件---->新建---->作业----核心对象---->通用-----> ...

  7. miniIO系列文章03---abpvext中集成

    在Abp商业版本中已经提供了文件管理模块的,免费版本是没有的,本文将介绍如何使用Minio打造一个自己的文件管理模块. 在项目开始之前,需要先安装一个Minio服务,可以在本地pc或云主机中安装,具体 ...

  8. Windows 10 关闭搜索栏中“热门搜索”的显示。

    Windows 10 关闭搜索栏中"热门搜索"的显示. 任务栏取消"显示搜索突出显示"的设置可能无法取消"热门搜索"的显示, 这就需要您尝试 ...

  9. 收藏-即时通讯(IM)开源项目OpenIM-功能手册

    OpenIM简介 OpenIM是由IM技术专家打造的开源即时通讯组件,也是目前最受欢迎的开源IM项目之一,目前github star近万.开发者通过集成OpenIM组件,并私有化部署服务端,可以将即时 ...

  10. MySQL 权限与备份管理(精简笔记)

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RD ...