SpringBoot2.0整合SpringSecurity实现WEB JWT认证
相信很多做技术的朋友都做过前后端分离项目,项目分离后认证就靠JWT,费话不多说,直接上干活(写的不好还请多多见谅,大牛请绕行)
直接上代码,项目为Maven项目,结构如图:
包分类如下:
com.api.config 相关配置类
com.api.ctrl controller层
com.api.entity 相关实体类
com.api.repo jpa仓库相关
com.api.serice service层相关
ApiApplication 为启动类
主要配置核心类如下:
JWTAuthenticationFilter
package com.api.config;
import com.api.entity.User;
import com.api.repo.UserRepo;
import io.jsonwebtoken.Jwts;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
public class JWTAuthenticationFilter extends BasicAuthenticationFilter {
private UserRepo userRepo;
public JWTAuthenticationFilter(AuthenticationManager authenticationManager,UserRepo userRepo) {
super(authenticationManager);
this.userRepo = userRepo;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String header = request.getHeader("Authorization");
//如果不包含Bearer则退出
if(header != null && !header.startsWith("Bearer")){
chain.doFilter(request,response);
return;
}
UsernamePasswordAuthenticationToken authenticationToken = getAuthentication(request);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
chain.doFilter(request,response);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = request.getHeader("Authorization");
if (token != null) {
// parse the token.
String user = Jwts.parser()
.setSigningKey("HSMyJwtSecret".getBytes())
.parseClaimsJws(token.replace("Bearer ", ""))
.getBody()
.getSubject();
if (user != null) {
Integer userId = Integer.valueOf(user.split(":")[0]);
User currUser = userRepo.findById(userId).orElse(null);
if(currUser != null){
return new UsernamePasswordAuthenticationToken(currUser, null, new ArrayList<>());
}
return new UsernamePasswordAuthenticationToken(new User(), null, new ArrayList<>());
}
}
return null;
}
}
JWTLoginFilter
package com.api.config;
import com.api.entity.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
public class JWTLoginFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JWTLoginFilter(AuthenticationManager authenticationManager){
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
try {
User user = new ObjectMapper().readValue(request.getInputStream(), User.class);
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
user.getUsername(),
user.getPassword(),
new ArrayList<>()
)
);
}catch (Exception e){
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
String token = Jwts.builder()
.setSubject(((JwtUser) authResult.getPrincipal()).getUsername())
.setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 24 * 1000))
.signWith(SignatureAlgorithm.HS256,"HSMyJwtSecret".getBytes())
.compact();
response.addHeader("Authorization", "Bearer " + token);
response.getOutputStream().println(token);
}
}
MyUserDetailService
package com.api.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import java.util.Collection;
@Component
public class MyAuthencationProvider implements AuthenticationProvider {
@Autowired
private MyUserDetailService myUserDetailService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getPrincipal().toString();
JwtUser jwtUser = (JwtUser) myUserDetailService.loadUserByUsername(username);
Collection<? extends GrantedAuthority> authorities = jwtUser.getAuthorities();
return new UsernamePasswordAuthenticationToken(jwtUser, jwtUser.getPassword(), authorities);
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
}
MyUserDetailService
package com.api.config;
import com.api.entity.User;
import com.api.repo.UserRepo;
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;
import org.springframework.stereotype.Component;
@Component
public class MyUserDetailService implements UserDetailsService {
@Autowired
private UserRepo userRepo;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userRepo.findFirstByUsername(s);
if(user != null){
JwtUser jwtUser = new JwtUser(String.format("%s:%s",String.valueOf(user.getId()),user.getUsername()),user.getPassword());
return jwtUser;
}
throw new UsernameNotFoundException("用户名未找到");
}
}
WebSecurityConfig
package com.api.config;
import com.api.repo.UserRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(-1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyAuthencationProvider myAuthencationProvider;
@Autowired
private UserRepo userRepo;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, "/register").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JWTLoginFilter(authenticationManager()))
.addFilter(new JWTAuthenticationFilter(authenticationManager(),userRepo));
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(myAuthencationProvider);
}
}
JwtUser
package com.api.config;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class JwtUser implements UserDetails {
private String username;
private String password;
public JwtUser(String username,String password){
this.username = username;
this.password = password;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
}
MyMvcConfigurer
package com.api.config;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.SecurityConfig;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@AutoConfigureBefore(SecurityConfig.class)
public class MyMvcConfigurer implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
以上为config包下全部内容
项目POM.xml配置如下
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.api</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>api</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</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-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.wenhao</groupId>
<artifactId>jpa-spec</artifactId>
<version>3.2.3</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<compilerArgs>
<arg>-verbose</arg>
<arg>-Xlint:all,-options,-path</arg>
</compilerArgs>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.api.ApiApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimiter>@</delimiter>
<delimiter>#{*}</delimiter>
<delimiter>#</delimiter>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
</project>
以下为其他包结构以及类文件
以上配置成功后即可以POST方式访问
http://localhost:8080/login?username=xxx&password=xx 认证成功后会在返回jwt,下次请求认证的资源在header里边带上Authorization Bearer xxxxxx
即可。
SpringBoot2.0整合SpringSecurity实现WEB JWT认证的更多相关文章
- SpringBoot2.0 整合 SpringSecurity 框架,实现用户权限安全管理
本文源码:GitHub·点这里 || GitEE·点这里 一.Security简介 1.基础概念 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方 ...
- SpringBoot2.0整合SpringSecurity实现自定义表单登录
我们知道企业级权限框架一般有Shiro,Shiro虽然强大,但是却不属于Spring成员之一,接下来我们说说SpringSecurity这款强大的安全框架.费话不多说,直接上干货. pom文件引入以下 ...
- springboot2.0整合springsecurity前后端分离进行自定义权限控制
在阅读本文之前可以先看看springsecurity的基本执行流程,下面我展示一些核心配置文件,后面给出完整的整合代码到git上面,有兴趣的小伙伴可以下载进行研究 使用maven工程构建项目,首先需要 ...
- SpringBoot2.0 整合 Swagger2 ,构建接口管理界面
一.Swagger2简介 1.Swagger2优点 整合到Spring Boot中,构建强大RESTful API文档.省去接口文档管理工作,修改代码,自动更新,Swagger2也提供了强大的页面测试 ...
- springboot2.0整合logback日志(详细)
<div class="post"> <h1 class="postTitle"> springboot2.0整合logback日志(详 ...
- 第二篇:SpringBoot2.0整合ActiveMQ
本篇开始将具体介绍SpringBoot如何整合其它项目. 如何创建SpringBoot项目 访问https://start.spring.io/. 依次选择构建工具Maven Project.语言ja ...
- SpringBoot2.0 整合 QuartJob ,实现定时器实时管理
一.QuartJob简介 1.一句话描述 Quartz是一个完全由java编写的开源作业调度框架,形式简易,功能强大. 2.核心API (1).Scheduler 代表一个 Quartz 的独立运行容 ...
- SpringBoot2.0 整合 Dubbo框架 ,实现RPC服务远程调用
一.Dubbo框架简介 1.框架依赖 图例说明: 1)图中小方块 Protocol, Cluster, Proxy, Service, Container, Registry, Monitor 代表层 ...
- SpringBoot2.0 整合 Redis集群 ,实现消息队列场景
本文源码:GitHub·点这里 || GitEE·点这里 一.Redis集群简介 1.RedisCluster概念 Redis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的 ...
随机推荐
- 编译Python文件(了解)
目录 编译Python文件(了解) 批量生成.pyc文件(了解) 编译Python文件(了解) 为了提高加载模块的速度,强调强调强调:提高的是加载速度而绝非运行速度.python解释器会在__pyca ...
- 洛谷 1328 生活大爆炸版石头剪刀布(NOIp2014提高组)
[题解] 简单粗暴的模拟题. #include<cstdio> #include<algorithm> #include<cstring> #define LL l ...
- lnmp的安装--nginx
1.nginx的安装 安装所需环境 Nginx 是 C语言 开发,建议在 Linux 上运行,当然,也可以安装 Windows 版本,本篇则使用 CentOS 7 作为安装环境. 一. gcc 安装安 ...
- 一位ACMer过来人的心得
http://blog.csdn.net/acm_cxlove/article/details/8079348
- [K/3Cloud]有关单据显示行数限制和数据导出的建议
1.针对显示行数限制: 模仿现在很流行的"查看更多"的模式,动态加载数据. 我相信这一点建议别人也提过,还请总部对此开展头脑风暴,因为在实际使用中客户总是不理解为何要限制行数,解释 ...
- codevs1031 质数环
一个大小为N(N<=17)的质数环是由1到N共N个自然数组成的一个数环,数环上每两个相邻的数字之和为质数.如下图是一个大小为6的质数环.为了方便描述,规定数环上的第一个数字总是1.如下图可用1 ...
- HDU1565 方格取数1(构图+网络流最大独立集合)
题目大意:给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大. 解题思路:最大点 ...
- Ubuntu 16.04安装GIMP替代PS
GIMP虽然不能完全替代PS,但是也能弥补一下. 系统默认源中已经包含了GIMP,不需要使用PPA这些. 安装: sudo apt-get install gimp 启动: 通过Dash搜索GIMP即 ...
- 【Nginx】进程模型
转自:网易博客 服务器的并发模型设计是网络编程中很关键的一个部分,服务器的并发量取决于两个因素,一个是提供服务的进程数量,另外一个是每个进程可同时处理的并发连接数量.相应的,服务器的并发模型也由两个部 ...
- BC #62 div1 02
/* 数位DP题,设dp[n][k][j]为前n位最后一位是k时mod为j的个数.操作都相同,可以使用矩阵加速.本来对于每一位是7*10,可以把它压向一个向量. 加速矩阵为70*70,再加一维计算前缀 ...