SpringSecurity学习之基于数据库的用户认证
SpringSecurity给我们提供了一套最基本的认证方式,可是这种方式远远不能满足大多数系统的需求。不过好在SpringSecurity给我们预留了许多可扩展的接口给我们,我们可以基于这些接口实现自己的认证方式。
一、前期准备工作
1.1、创建示例数据库
Student表:
- create table student
- (
- id int auto_increment
- primary key,
- stuName varchar(8) null,
- password varchar(16) null,
- joinTime datetime null,
- clz_id int null
- )
- ;
Classes(班级)表:
- create table classes
- (
- id int auto_increment
- primary key,
- clz_name varchar(16) not null
- )
- ;
1.2、添加相关依赖
- compile group: 'mysql', name: 'mysql-connector-java'
- compile group: 'org.springframework.security', name: 'spring-security-taglibs'
- compile('org.springframework.boot:spring-boot-starter-jdbc')
二、实现步骤
2.1 定义Student类
- package com.bdqn.lyrk.security.study.app.pojo;
- import org.springframework.security.core.GrantedAuthority;
- import org.springframework.security.core.userdetails.User;
- import java.sql.Timestamp;
- import java.util.Collection;
- public class Student extends User {
- private Timestamp joinTime;
- public Timestamp getJoinTime() {
- return joinTime;
- }
- public void setJoinTime(Timestamp joinTime) {
- this.joinTime = joinTime;
- }
- public Student(String username, String password, Collection<? extends GrantedAuthority> authorities) {
- super(username, password, authorities);
- }
- }
在这里定义的类继承User,User是SpringSecurity里的一个类,用以描述一个用户和其最基本的属性,当然我们要扩展它的用户我们也可以实现UserDetails接口
2.2 实现UserDetailsService
- package com.bdqn.lyrk.security.study.app.service;
- import com.bdqn.lyrk.security.study.app.pojo.Student;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.jdbc.core.JdbcTemplate;
- import org.springframework.security.core.GrantedAuthority;
- import org.springframework.security.core.authority.SimpleGrantedAuthority;
- import org.springframework.security.core.userdetails.User;
- 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.sql.Timestamp;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- @Service
- public class UserService implements UserDetailsService {
- @Autowired
- private JdbcTemplate jdbcTemplate;
- @Override
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
- User.UserBuilder users = User.withDefaultPasswordEncoder();
- 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);
- Timestamp joinTime = null;
- if (map != null && map.size() > 0) {
- String stuName = (String) map.get("stuName");
- String password = (String) map.get("password");
- joinTime = (Timestamp) map.get("joinTime");
- String clzName = (String) map.get("clz_name");
- users.password(password);
- users.username(stuName);
- SimpleGrantedAuthority authority = new SimpleGrantedAuthority(clzName);
- List<GrantedAuthority> list = new ArrayList<>();
- list.add(authority);
- users.authorities(list);
- }
- UserDetails userDetails = users.build();
- Student student = new Student(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());
- // UserDetails userDetails = User.withDefaultPasswordEncoder().
- student.setJoinTime(joinTime);
- return student;
- }
- }
在这个接口里我们要实现根据用户名查找用户的方法,那么一般情况下我们都会根据自己系统的用户表来获取用户信息,这里面注意几个方面:
1)需要设置PasswordEncoder
2) 需要设置其角色信息,那么在这里我用班级来表示用户的角色
3)用户的三个重要属性就是 用户名,密码与权限
4) 这里的返回值(UserDetails)不能返回null,如果根据用户名找不到对应的用户可以抛出UsernameNotFoundException异常
2.3 改造WebSecurityConfig
- package com.bdqn.lyrk.security.study.app.config;
- import com.bdqn.lyrk.security.study.app.service.UserService;
- import org.springframework.beans.factory.annotation.Autowired;
- 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.configuration.EnableWebSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- /**
- * spring-security的相关配置
- *
- * @author chen.nie
- * @date 2018/6/7
- **/
- @EnableWebSecurity
- public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
- @Autowired
- private UserService userService;
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- /*
- 1.配置静态资源不进行授权验证
- 2.登录地址及跳转过后的成功页不需要验证
- 3.其余均进行授权验证
- */
- http.
- authorizeRequests().antMatchers("/static/**").permitAll().
- and().authorizeRequests().antMatchers("/user/**").hasRole("7022").
- and().authorizeRequests().anyRequest().authenticated().
- and().formLogin().loginPage("/login").successForwardUrl("/toIndex").permitAll()
- .and().logout().logoutUrl("/logout").invalidateHttpSession(true).deleteCookies().permitAll()
- ;
- }
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- //设置自定义userService
- auth.userDetailsService(userService);
- }
- }
在这里主要做以下处理:
1)针对于/user/**路径的请求需要设置对应的权限
2) 做用户注销的处理,用户注销时需要销毁session与cookie
3)配置自定义UserDetailService
2.4、改造index.jsp
- <%--
- Created by IntelliJ IDEA.
- User: chen.nie
- Date: 2018/6/8
- Time: 上午9:56
- To change this template use File | Settings | File Templates.
- --%>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
- <html>
- <head>
- <title>Title</title>
- </head>
- <body>
- 欢迎:${user.username}
- <sec:authorize access="hasRole('7022')">
- 加入时间:${user.joinTime}
- </sec:authorize>
- <form action="/logout" method="post">
- <input type="submit" value="退出" />
- <sec:csrfInput/>
- </form>
- </body>
- </html>
在这里面我们使用spring对security标签的支持判断当前用户是否有对应的角色,另外我们在处理登出操作时必须为post提交且有对应的token防止csrf
SpringSecurity学习之基于数据库的用户认证的更多相关文章
- spring security基于数据库表进行认证
我们从研究org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.class的源码开始 public class JdbcDaoI ...
- 项目一:第十一天 2、运单waybill快速录入 3、权限demo演示-了解 5、权限模块数据模型 6、基于shiro实现用户认证-登录(重点)
1. easyui DataGrid行编辑功能 2. 运单waybill快速录入 3. 权限demo演示-了解 4. Apache shiro安全框架概述 5. 权限模块数据模型 6. 基于shiro ...
- 5分钟搞懂:基于token的用户认证
https://www.qikegu.com/easy-understanding/880 用户认证 用户认证或者说用户登录是确认某人确实是某人的过程,生活中靠身份证,网络上就要靠账号和密码.用户提供 ...
- Laravel 5 中使用 JWT(Json Web Token) 实现基于API的用户认证
在JavaScript前端技术大行其道的今天,我们通常只需在后台构建API提供给前端调用,并且后端仅仅设计为给前端移动App调用.用户认证是Web应用的重要组成部分,基于API的用户认证有两个最佳解决 ...
- Linux下基于LDAP统一用户认证的研究
Linux下基于LDAP统一用户认证的研究 本文出自 "李晨光原创技术博客" 博客,谢绝转载!
- JWT 实现基于API的用户认证
基于 JWT-Auth 实现 API 验证 如果想要了解其生成Token的算法原理,请自行查阅相关资料 需要提及的几点: 使用session存在的问题: session和cookie是为了解决http ...
- Spring Security笔记:使用数据库进行用户认证(form login using database)
在前一节,学习了如何自定义登录页,但是用户名.密码仍然是配置在xml中的,这样显然太非主流,本节将学习如何把用户名/密码/角色存储在db中,通过db来实现用户认证 一.项目结构 与前面的示例相比,因为 ...
- Docker Mongo数据库开启用户认证
一.启动mongo容器的几种方式 #简化版 docker run --name mongo1 -p 21117:27017 -d mongo --noprealloc --smallfiles #自定 ...
- springSecurity + jwt + redis 前后端分离用户认证和授权
记录一下使用springSecurity搭建用户认证和授权的代码... 技术栈使用springSecurity + redis + JWT + mybatisPlus 部分代码来自:https://b ...
随机推荐
- hadoop 组件 hdfs架构及读写流程
一 . Namenode Namenode 是整个系统的管理节点 就像一本书的目录,储存文件信息,地址,接受用户请求,等 二 . Datanode 提供真实的文件数据,存储服务 文件块(block)是 ...
- XCode中安装cocoapods步骤
Ruby是一种功能强大的面向对象的脚本语言 Gem是一个管理Ruby库和程序的标准包,它通过Ruby Gem(如 http://rubygems.org/ )源来查找.安装.升级和卸载软件包,非常的便 ...
- java实现在图片上编辑文本内容
package com.yin.text; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; impor ...
- iOS笔记之UIKit_UINavigationController
//设置导航条的样式 self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent; //默认是白色 B ...
- A - Class Statistics
A - Class Statistics Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Subm ...
- 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 准 ...
- 国内代码托管平台(Git)
可以说GitHub的出现完全颠覆了以往大家对代码托管网站的认识.GitHub不但是一个代码托管网站,更是一个程序员的SNS社区.GitHub真正迷人的是它的创新能力与Geek精神,这些都是无法模仿的. ...
- windows 7 下elasticsearch5.0 安装head 插件
windows 7 下elasticsearch5.0 安装head 插件 elasticsearch5.0 和2有了很大的变化,以前的很多插件都有了变化比如 bigdesk head,以下是安装he ...
- .net core 与ELK(1)安装Elasticsearch
1.安装java jdk [elsearch@localhost bin]$ java -version openjdk version "1.8.0_181" OpenJDK R ...
- NHibernate问题求大神解决!!!
这是我定义的实体类 对应的数据库表 映射文件 数据访问层写的是插入语句 错误: 捕捉到 NHibernate.Exceptions.GenericADOException HResult=-21462 ...