SpringBoot + Security实现权限控制
网上找了好几个,因为各种原因不太行,下面这个亲测可行
参考:https://blog.csdn.net/u012702547/article/details/54319508
基于SpringBoot + JPA
安全框架:Security5
页面:Thymeleaf + BootStrap
工程目录结构:
引入依赖包
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.</modelVersion> <groupId>com.zit</groupId>
<artifactId>Hello</artifactId>
<version>0.0.-SNAPSHOT</version>
<packaging>jar</packaging> <properties>
<project.build.sourceEncoding>UTF-</project.build.sourceEncoding>
</properties> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0..RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency> <dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.</version>
</dependency> </dependencies> <repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories> </project>
配置文件
application.properties
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=
logging.level.org.springframework.security=info
spring.thymeleaf.cache=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent_output=true spring.thymeleaf.cache=false
1、实体类
(1)用户
package com.zit; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; /**
*
*/
@Entity
public class SysUser implements UserDetails {
@Id
@GeneratedValue
private Long id;
private String username;
private String password; @ManyToMany(cascade = {CascadeType.REFRESH},fetch = FetchType.EAGER)
private List<SysRole> roles; public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public void setUsername(String username) {
this.username = username;
} public void setPassword(String password) {
this.password = password;
} public List<SysRole> getRoles() {
return roles;
} public void setRoles(List<SysRole> roles) {
this.roles = roles;
} @Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> auths = new ArrayList<>();
List<SysRole> roles = this.getRoles();
for (SysRole role : roles) {
auths.add(new SimpleGrantedAuthority(role.getName()));
}
return auths;
} @Override
public String getPassword() {
return this.password;
} @Override
public String getUsername() {
return this.username;
} @Override
public boolean isAccountNonExpired() {
return true;
} @Override
public boolean isAccountNonLocked() {
return true;
} @Override
public boolean isCredentialsNonExpired() {
return true;
} @Override
public boolean isEnabled() {
return true;
}
}
(2)角色
package com.zit; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id; /**
*
*/
@Entity
public class SysRole {
@Id
@GeneratedValue
private Long id;
private String name; public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
2、JPA访问数据库
package com.zit; import org.springframework.data.jpa.repository.JpaRepository; public interface SysUserRepository extends JpaRepository<SysUser, Long> {
SysUser findByUsername(String username);
}
3、控制器
(1)控制器给页面传值的对象
package com.zit; /**
* 传递在页面上的消息
*/
public class Msg {
private String title;
private String content;
private String extraInfo; public Msg() {
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
} public String getExtraInfo() {
return extraInfo;
} public void setExtraInfo(String extraInfo) {
this.extraInfo = extraInfo;
} public Msg(String title, String content, String extraInfo) {
this.title = title;
this.content = content;
this.extraInfo = extraInfo;
}
}
(2)控制类
package com.zit; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class HomeController {
@RequestMapping("/")
public String index(Model model) {
Msg msg = new Msg("测试标题", "测试内容", "额外信息,只对管理员显示");
model.addAttribute("msg", msg);
return "index";
}
}
4、自定义UserDetailsService
package com.zit; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; public class CustomUserService implements UserDetailsService {
@Autowired
SysUserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
SysUser user = userRepository.findByUsername(s);
if (user == null) {
throw new UsernameNotFoundException("用户名不存在");
}
System.out.println("s:"+s);
System.out.println("username:"+user.getUsername()+";password:"+user.getPassword());
return user;
}
}
5、SpringMVC配置
package com.zit; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
}
当用户访问login时跳转到login.html页面
6、配置Spring Security
由于Spring Security5必须自定义密码加密,所以建立一个自定义密码加密类
(1)MyPasswordEncoder.java
package com.zit; import org.springframework.security.crypto.password.PasswordEncoder; public class MyPasswordEncoder implements PasswordEncoder { @Override
public String encode(CharSequence arg0) {
return arg0.toString();
} @Override
public boolean matches(CharSequence arg0, String arg1) {
return arg1.equals(arg0.toString());
} }
(2)Security配置
package com.zit; import org.springframework.context.annotation.Bean;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService; @Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
UserDetailsService customUserService() {
return new CustomUserService();
} @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserService())
.passwordEncoder(new MyPasswordEncoder());
} @Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//security允许页面加载css文件夹下的静态资源
.antMatchers("/css/**").permitAll()
.anyRequest().authenticated()
.and().formLogin().loginPage("/login").failureUrl("/login?error").permitAll()
.and()
.logout()
.permitAll();
}
}
1.首先当我们要自定义Spring Security的时候我们需要继承自WebSecurityConfigurerAdapter来完成,相关配置重写对应 方法即可。
2.我们在这里注册CustomUserService的Bean,然后通过重写configure方法添加我们自定义的认证方式。
3.在configure(HttpSecurity http)方法中,我们设置了登录页面,而且登录页面任何人都可以访问,然后设置了登录失败地址,也设置了注销请求,注销请求也是任何人都可以访问的。
4.permitAll表示该请求任何人都可以访问,.anyRequest().authenticated()
,表示其他的请求都必须要有权限认证。
7、静态资源
(1)CSS
下载bootstrap包,取其bootstrap.min.css
另,自己写一个signin.css,如下:
body {
padding-top: 40px;
padding-bottom: 40px;
background-color: #eee;
} .form-signin {
max-width: 330px;
padding: 15px;
margin: auto;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
margin-bottom: 10px;
}
.form-signin .checkbox {
font-weight: normal;
}
.form-signin .form-control {
position: relative;
height: auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 10px;
font-size: 16px;
}
.form-signin .form-control:focus {
z-index: ;
}
.form-signin input[type="email"] {
margin-bottom: -1px;
border-bottom-right-radius: ;
border-bottom-left-radius: ;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: ;
border-top-right-radius: ;
}
(2)HTML
login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>登录</title>
<link rel="stylesheet" th:href="@{css/bootstrap.min.css}"/>
<link rel="stylesheet" th:href="@{css/signin.css}"/>
<style type="text/css">
body {
padding-top: 50px;
}
.starter-template {
padding: 40px 15px;
text-align: center;
}
</style>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">Spring Security演示</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a th:href="@{/}">首页</a></li>
<li><a th:href="@{http://www.baidu.com}">百度</a></li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="starter-template">
<p th:if="${param.logout}" class="bg-warning">已注销</p>
<p th:if="${param.error}" class="bg-danger">有错误,请重试</p>
<h2>使用账号密码登录</h2>
<form class="form-signin" role="form" name="form" th:action="@{/login}" action="/login" method="post">
<div class="form-group">
<label for="username">账号</label>
<input type="text" class="form-control" name="username" value="" placeholder="账号"/>
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control" name="password" placeholder="密码"/>
</div>
<input type="submit" id="login" value="Login" class="btn btn-primary"/>
</form>
</div>
</div> </body>
</html>
index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<meta charset="UTF-8"/>
<title sec:authentication="name"></title>
<link rel="stylesheet" th:href="@{css/bootstrap.min.css}"/>
<style type="text/css">
body {
padding-top: 50px;
}
.starter-template {
padding: 40px 15px;
text-align: center;
}
</style>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">Spring Security演示</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a th:href="@{/}">首页</a></li>
<li><a th:href="@{http://www.baidu.com}">百度</a></li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="starter-template">
<h1 th:text="${msg.title}"></h1>
<p class="bg-primary" th:text="${msg.content}"></p>
<div sec:authorize="hasRole('ROLE_ADMIN')">
<p class="bg-info" th:text="${msg.extraInfo}"></p>
</div>
<div sec:authorize="hasRole('ROLE_USER')">
<p class="bg-info">无更多显示信息</p>
</div>
<form th:action="@{/logout}" method="post">
<input type="submit" class="btn btn-primary" value="注销"/>
</form>
</div>
</div>
</body>
</html>
SpringBoot + Security实现权限控制的更多相关文章
- request.getRemoteUser() Spring Security做权限控制后
一. request.getRemoteUser();//获取当前缓存的用户,比如Spring Security做权限控制后就会将用户登录名缓存到这里 request.getRemoteAddr(); ...
- 在Spring Boot中使用Spring Security实现权限控制
丢代码地址 https://gitee.com/a247292980/spring-security 再丢pom.xml <properties> <project.build.so ...
- Spring Security 动态url权限控制(三)
一.前言 本篇文章将讲述Spring Security 动态分配url权限,未登录权限控制,登录过后根据登录用户角色授予访问url权限 基本环境 spring-boot 2.1.8 mybatis-p ...
- spring security 3.1 实现权限控制
spring security 3.1 实现权限控制 简单介绍:spring security 实现的权限控制,能够分别保护后台方法的管理,url连接訪问的控制,以及页面元素的权限控制等, secur ...
- springboot整合security实现基于url的权限控制
权限控制基本上是任何一个web项目都要有的,为此spring为我们提供security模块来实现权限控制,网上找了很多资料,但是提供的demo代码都不能完全满足我的需求,因此自己整理了一版. 在上代码 ...
- springboot集成shiro 实现权限控制(转)
shiro apache shiro 是一个轻量级的身份验证与授权框架,与spring security 相比较,简单易用,灵活性高,springboot本身是提供了对security的支持,毕竟是自 ...
- springboot + 注解 + 拦截器 + JWT 实现角色权限控制
1.关于JWT,参考: (1)10分钟了解JSON Web令牌(JWT) (2)认识JWT (3)基于jwt的token验证 2.JWT的JAVA实现 Java中对JWT的支持可以考虑使用JJWT开源 ...
- SpringBoot集成Shiro实现权限控制
Shiro简介 Apache Shiro是一个功能强大且易于使用的Java安全框架,用于执行身份验证,授权,加密和会话管理.使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序-从最小的移 ...
- 轻松上手SpringBoot+SpringSecurity+JWT实RESTfulAPI权限控制实战
前言 我们知道在项目开发中,后台开发权限认证是非常重要的,springboot 中常用熟悉的权限认证框架有,shiro,还有就是springboot 全家桶的 security当然他们各有各的好处,但 ...
随机推荐
- Codeforces 797C - Minimal string
C. Minimal string 题目链接:http://codeforces.com/problemset/problem/797/C time limit per test 1 second m ...
- Asp.net core 学习笔记 ( DI 依赖注入 )
比起 Angular 的依赖注入, core 的相对简单许多, 容易明白 所有 provider 都在 startup 里配置. public void ConfigureServices(IServ ...
- English trip V1 - B 19. Life of Confucius 孔子的生活 Teacher:Patrick Key:
In this lesson you will learn to describe a daily routine. (日常生活) 课上内容(Lesson) 词汇(Key Word ) contrac ...
- c++的const总结
转自:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html 为什么使用const?采用符号常量写出的代码更容易维护:指 ...
- [LintCode] Serialize and Deserialize Binary Tree(二叉树的序列化和反序列化)
描述 设计一个算法,并编写代码来序列化和反序列化二叉树.将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”. 如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉 ...
- 「THUWC 2017」在美妙的数学王国中畅游
这个题目很明显在暗示你要用泰勒展开. 直接套上去泰勒展开的式子,精度的话保留12项左右即可. 分别维护每一项的和,可能比较难写吧. 然后强行套一个LCT就没了.
- python-day71--django多表双下划线查询及分组聚合及F/Q查询
#====================================双下划线的跨表查询===============# 前提 此时 related_name=bookList 属性查询: # 查 ...
- 第 3 章 HTML5 网页中的文本和图像
文字和图像是网页中最主要.最常用的元素. 在互联网高速发展的今天,网站已经成为一个展示与宣传自我的通信工具(公司或个人可以通过网站介绍公司的服务与产品或介绍自己).这些都离不开网站中的网页,而网页的内 ...
- python中的apscheduler模块
1.简介 apscheduler是python中的任务定时模块,它包含四个组件:触发器(trigger),作业存储(job store),执行器(executor),调度器(scheduler). 2 ...
- HTML相关知识点总结
1.表格<table>常用属性 cellspacing:两个单元格之间的距离 注:属性值为数字,效果图如下(左边cellspacing="0",右边cellspacin ...