SpringSecurity给我们提供了一套最基本的认证方式,可是这种方式远远不能满足大多数系统的需求。不过好在SpringSecurity给我们预留了许多可扩展的接口给我们,我们可以基于这些接口实现自己的认证方式。

一、前期准备工作

1.1、创建示例数据库

Student表:

  1. create table student
  2. (
  3. id int auto_increment
  4. primary key,
  5. stuName varchar(8) null,
  6. password varchar(16) null,
  7. joinTime datetime null,
  8. clz_id int null
  9. )
  10. ;

Classes(班级)表:

  1. create table classes
  2. (
  3. id int auto_increment
  4. primary key,
  5. clz_name varchar(16) not null
  6. )
  7. ;

1.2、添加相关依赖

  1. compile group: 'mysql', name: 'mysql-connector-java'
  2. compile group: 'org.springframework.security', name: 'spring-security-taglibs'
  3. compile('org.springframework.boot:spring-boot-starter-jdbc')

二、实现步骤

2.1  定义Student类

  1. package com.bdqn.lyrk.security.study.app.pojo;
  2.  
  3. import org.springframework.security.core.GrantedAuthority;
  4. import org.springframework.security.core.userdetails.User;
  5.  
  6. import java.sql.Timestamp;
  7. import java.util.Collection;
  8.  
  9. public class Student extends User {
  10.  
  11. private Timestamp joinTime;
  12.  
  13. public Timestamp getJoinTime() {
  14. return joinTime;
  15. }
  16.  
  17. public void setJoinTime(Timestamp joinTime) {
  18. this.joinTime = joinTime;
  19. }
  20.  
  21. public Student(String username, String password, Collection<? extends GrantedAuthority> authorities) {
  22. super(username, password, authorities);
  23. }
  24.  
  25. }

  在这里定义的类继承User,User是SpringSecurity里的一个类,用以描述一个用户和其最基本的属性,当然我们要扩展它的用户我们也可以实现UserDetails接口

2.2 实现UserDetailsService

  1. package com.bdqn.lyrk.security.study.app.service;
  2.  
  3. import com.bdqn.lyrk.security.study.app.pojo.Student;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.jdbc.core.JdbcTemplate;
  6. import org.springframework.security.core.GrantedAuthority;
  7. import org.springframework.security.core.authority.SimpleGrantedAuthority;
  8. import org.springframework.security.core.userdetails.User;
  9. import org.springframework.security.core.userdetails.UserDetails;
  10. import org.springframework.security.core.userdetails.UserDetailsService;
  11. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  12. import org.springframework.stereotype.Service;
  13.  
  14. import java.sql.Timestamp;
  15. import java.util.ArrayList;
  16. import java.util.List;
  17. import java.util.Map;
  18.  
  19. @Service
  20. public class UserService implements UserDetailsService {
  21.  
  22. @Autowired
  23. private JdbcTemplate jdbcTemplate;
  24.  
  25. @Override
  26. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  27. User.UserBuilder users = User.withDefaultPasswordEncoder();
  28. Map<String, Object> map = jdbcTemplate.queryForMap("select t.clz_name,t1.stuName,t1.password,t1.joinTime from student t1 inner join classes t on t.id = t1.clz_id where stuName = ?", username);
  29. Timestamp joinTime = null;
  30. if (map != null && map.size() > 0) {
  31. String stuName = (String) map.get("stuName");
  32. String password = (String) map.get("password");
  33. joinTime = (Timestamp) map.get("joinTime");
  34. String clzName = (String) map.get("clz_name");
  35. users.password(password);
  36. users.username(stuName);
  37. SimpleGrantedAuthority authority = new SimpleGrantedAuthority(clzName);
  38. List<GrantedAuthority> list = new ArrayList<>();
  39. list.add(authority);
  40. users.authorities(list);
  41. }
  42. UserDetails userDetails = users.build();
  43. Student student = new Student(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());
  44. // UserDetails userDetails = User.withDefaultPasswordEncoder().
  45. student.setJoinTime(joinTime);
  46. return student;
  47. }
  48. }

  在这个接口里我们要实现根据用户名查找用户的方法,那么一般情况下我们都会根据自己系统的用户表来获取用户信息,这里面注意几个方面:

  1)需要设置PasswordEncoder

  2) 需要设置其角色信息,那么在这里我用班级来表示用户的角色

  3)用户的三个重要属性就是 用户名,密码与权限

  4) 这里的返回值(UserDetails)不能返回null,如果根据用户名找不到对应的用户可以抛出UsernameNotFoundException异常

2.3 改造WebSecurityConfig

  1. package com.bdqn.lyrk.security.study.app.config;
  2.  
  3. import com.bdqn.lyrk.security.study.app.service.UserService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  6. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  7. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  8. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  9.  
  10. /**
  11. * spring-security的相关配置
  12. *
  13. * @author chen.nie
  14. * @date 2018/6/7
  15. **/
  16. @EnableWebSecurity
  17. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  18.  
  19. @Autowired
  20. private UserService userService;
  21.  
  22. @Override
  23. protected void configure(HttpSecurity http) throws Exception {
  24. /*
  25. 1.配置静态资源不进行授权验证
  26. 2.登录地址及跳转过后的成功页不需要验证
  27. 3.其余均进行授权验证
  28. */
  29. http.
  30. authorizeRequests().antMatchers("/static/**").permitAll().
  31. and().authorizeRequests().antMatchers("/user/**").hasRole("7022").
  32. and().authorizeRequests().anyRequest().authenticated().
  33. and().formLogin().loginPage("/login").successForwardUrl("/toIndex").permitAll()
  34. .and().logout().logoutUrl("/logout").invalidateHttpSession(true).deleteCookies().permitAll()
  35. ;
  36. }
  37.  
  38. @Override
  39. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  40. //设置自定义userService
  41. auth.userDetailsService(userService);
  42. }
  43. }

在这里主要做以下处理:

 1)针对于/user/**路径的请求需要设置对应的权限

 2) 做用户注销的处理,用户注销时需要销毁session与cookie

 3)配置自定义UserDetailService

2.4、改造index.jsp

  1. <%--
  2. Created by IntelliJ IDEA.
  3. User: chen.nie
  4. Date: 2018/6/8
  5. Time: 上午9:56
  6. To change this template use File | Settings | File Templates.
  7. --%>
  8. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  9. <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
  10. <html>
  11. <head>
  12. <title>Title</title>
  13. </head>
  14. <body>
  15. 欢迎:${user.username}
  16. <sec:authorize access="hasRole('7022')">
  17. 加入时间:${user.joinTime}
  18. </sec:authorize>
  19. <form action="/logout" method="post">
  20. <input type="submit" value="退出" />
  21. <sec:csrfInput/>
  22. </form>
  23.  
  24. </body>
  25. </html>

  在这里面我们使用spring对security标签的支持判断当前用户是否有对应的角色,另外我们在处理登出操作时必须为post提交且有对应的token防止csrf

SpringSecurity学习之基于数据库的用户认证的更多相关文章

  1. spring security基于数据库表进行认证

    我们从研究org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.class的源码开始 public class JdbcDaoI ...

  2. 项目一:第十一天 2、运单waybill快速录入 3、权限demo演示-了解 5、权限模块数据模型 6、基于shiro实现用户认证-登录(重点)

    1. easyui DataGrid行编辑功能 2. 运单waybill快速录入 3. 权限demo演示-了解 4. Apache shiro安全框架概述 5. 权限模块数据模型 6. 基于shiro ...

  3. 5分钟搞懂:基于token的用户认证

    https://www.qikegu.com/easy-understanding/880 用户认证 用户认证或者说用户登录是确认某人确实是某人的过程,生活中靠身份证,网络上就要靠账号和密码.用户提供 ...

  4. Laravel 5 中使用 JWT(Json Web Token) 实现基于API的用户认证

    在JavaScript前端技术大行其道的今天,我们通常只需在后台构建API提供给前端调用,并且后端仅仅设计为给前端移动App调用.用户认证是Web应用的重要组成部分,基于API的用户认证有两个最佳解决 ...

  5. Linux下基于LDAP统一用户认证的研究

    Linux下基于LDAP统一用户认证的研究                   本文出自 "李晨光原创技术博客" 博客,谢绝转载!

  6. JWT 实现基于API的用户认证

    基于 JWT-Auth 实现 API 验证 如果想要了解其生成Token的算法原理,请自行查阅相关资料 需要提及的几点: 使用session存在的问题: session和cookie是为了解决http ...

  7. Spring Security笔记:使用数据库进行用户认证(form login using database)

    在前一节,学习了如何自定义登录页,但是用户名.密码仍然是配置在xml中的,这样显然太非主流,本节将学习如何把用户名/密码/角色存储在db中,通过db来实现用户认证 一.项目结构 与前面的示例相比,因为 ...

  8. Docker Mongo数据库开启用户认证

    一.启动mongo容器的几种方式 #简化版 docker run --name mongo1 -p 21117:27017 -d mongo --noprealloc --smallfiles #自定 ...

  9. springSecurity + jwt + redis 前后端分离用户认证和授权

    记录一下使用springSecurity搭建用户认证和授权的代码... 技术栈使用springSecurity + redis + JWT + mybatisPlus 部分代码来自:https://b ...

随机推荐

  1. hadoop 组件 hdfs架构及读写流程

    一 . Namenode Namenode 是整个系统的管理节点 就像一本书的目录,储存文件信息,地址,接受用户请求,等 二 . Datanode 提供真实的文件数据,存储服务 文件块(block)是 ...

  2. XCode中安装cocoapods步骤

    Ruby是一种功能强大的面向对象的脚本语言 Gem是一个管理Ruby库和程序的标准包,它通过Ruby Gem(如 http://rubygems.org/ )源来查找.安装.升级和卸载软件包,非常的便 ...

  3. java实现在图片上编辑文本内容

    package com.yin.text; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; impor ...

  4. iOS笔记之UIKit_UINavigationController

    //设置导航条的样式 self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent; //默认是白色  B ...

  5. A - Class Statistics

    A - Class Statistics Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Subm ...

  6. Caffe + Ubuntu 14.04 64bit + CUDA 6.5 配置说明2

    1. 安装build-essentials 安装开发所需要的一些基本包 sudo apt-get install build-essential 2. 安装NVIDIA驱动 (3.4.0) 2.1 准 ...

  7. 国内代码托管平台(Git)

    可以说GitHub的出现完全颠覆了以往大家对代码托管网站的认识.GitHub不但是一个代码托管网站,更是一个程序员的SNS社区.GitHub真正迷人的是它的创新能力与Geek精神,这些都是无法模仿的. ...

  8. windows 7 下elasticsearch5.0 安装head 插件

    windows 7 下elasticsearch5.0 安装head 插件 elasticsearch5.0 和2有了很大的变化,以前的很多插件都有了变化比如 bigdesk head,以下是安装he ...

  9. .net core 与ELK(1)安装Elasticsearch

    1.安装java jdk [elsearch@localhost bin]$ java -version openjdk version "1.8.0_181" OpenJDK R ...

  10. NHibernate问题求大神解决!!!

    这是我定义的实体类 对应的数据库表 映射文件 数据访问层写的是插入语句 错误: 捕捉到 NHibernate.Exceptions.GenericADOException HResult=-21462 ...