JWT教程_2 SpringSecurity与JWT整合
3. SpringSecurity与JWT整合
依赖:
<dependencies><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.21</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</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><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency>
</dependencies>
application.properties:
spring.thymeleaf.cache=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springsecurity001?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
mybatis.mapper-locations=classpath:mapper/*.xml
启动类SecurityJwtApplication:
@SpringBootApplication
@MapperScan("com.blu.mapper")
public class SecurityJwtApplication {public static void main(String[] args) {SpringApplication.run(SecurityJwtApplication.class, args);}@Beanpublic BCryptPasswordEncoder bcryptPasswordEncoder(){return new BCryptPasswordEncoder();}}
MyUser:
@Data
public class MyUser implements UserDetails {private Integer id;private String name;private String password;private List<MyRole> roles;@JsonIgnore@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return roles;}@JsonIgnore@Overridepublic String getUsername() {return name;}@JsonIgnore@Overridepublic boolean isAccountNonExpired() {return true;}@JsonIgnore@Overridepublic boolean isAccountNonLocked() {return true;}@JsonIgnore@Overridepublic boolean isCredentialsNonExpired() {return true;}@JsonIgnore@Overridepublic boolean isEnabled() {return true;}}
MyRole:
@Data
public class MyRole implements GrantedAuthority {private Integer id;private String name;@JsonIgnore@Overridepublic String getAuthority() {return name;}}
MyUserMapper:
public interface MyUserMapper {MyUser findByName(String name);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.blu.mapper.MyUserMapper"><resultMap type="com.blu.entity.MyUser" id="myUserMap"><id column="uid" property="id"></id><result column="uname" property="name"></result><result column="password" property="password"></result><collection property="roles" ofType="com.blu.entity.MyRole"><id column="rid" property="id" /><result column="rname" property="name" /></collection></resultMap><select id="findByName" parameterType="String"resultMap="myUserMap">select u.id uid,u.name uname,u.password,r.id rid,r.name rnamefrom user u,role r,role_user ur where u.name = #{name} and ur.user_id = u.id and ur.role_id = r.id</select>
</mapper>
UserService:
public interface UserService extends UserDetailsService {}
UserServiceImpl:
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate MyUserMapper myUserMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {MyUser myUser = myUserMapper.findByName(username);return myUser;}}
JwtLoginFilter:
public class JwtLoginFilter extends AbstractAuthenticationProcessingFilter {public JwtLoginFilter(String defaultFilterProcessesUrl, AuthenticationManager authenticationManager) {super(new AntPathRequestMatcher(defaultFilterProcessesUrl));setAuthenticationManager(authenticationManager);}/*** 从登录参数json数据中获取用户名密码,然后调用AuthenticationManager.authenticate()方法进行校验。*/@Overridepublic Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse resp) throws AuthenticationException, IOException, ServletException {//将用户传的json数据转为user对象MyUser user = new ObjectMapper().readValue(req.getInputStream(),MyUser.class);return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword()));}/*** 校验成功*/@Overrideprotected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {Collection<? extends GrantedAuthority> authorities = authResult.getAuthorities();StringBuffer sb = new StringBuffer();for (GrantedAuthority authority : authorities) {sb.append(authority.getAuthority()).append(",");}String jwt = Jwts.builder().claim("authorities", sb).setSubject(authResult.getName()).setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 1000))//设置过期时间.signWith(SignatureAlgorithm.HS512, "root@123")//设置加密方式,以及key.compact();//设置登录成功后返回的信息Map<String,String> map = new HashMap<>();map.put("token",jwt);map.put("msg","登录成功");response.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();writer.write(new ObjectMapper().writeValueAsString(map));writer.flush();writer.close();}/*** 校验失败*/@Overrideprotected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {Map<String,String> map = new HashMap<>();map.put("msg","登录失败");response.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();writer.write(new ObjectMapper().writeValueAsString(map));writer.flush();writer.close();}
}
JwtFilter:
public class JwtFilter extends GenericFilterBean {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) servletRequest;//从请求头中获取tokenString jwtToken = req.getHeader("authorization");Jws<Claims> jws = Jwts.parser().setSigningKey("root@123").parseClaimsJws(jwtToken.replace("Bearer", ""));Claims claims = jws.getBody();String username = claims.getSubject();//获取角色List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get("authorities"));UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,"",authorities);SecurityContextHolder.getContext().setAuthentication(token);filterChain.doFilter(servletRequest,servletResponse);}
}
测试接口:
@RestController
public class StringController {@GetMapping("hello")public String hello() {return "hello BLU!";}@GetMapping("hi")public String hi() {return "hi everyone!";}@GetMapping("admin")public String admin() {return "hello admin!";}}
Security配置类:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{@Autowiredprivate UserServiceImpl userServiceImpl;@Autowiredprivate BCryptPasswordEncoder bcryptPasswordEncoder;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers(HttpMethod.GET,"/hi").permitAll().antMatchers("/hello").hasRole("vip1").antMatchers("/admin").hasRole("admin");http.formLogin().loginPage("/tologin").usernameParameter("name").passwordParameter("password").loginProcessingUrl("/login");http.csrf().disable();http.addFilterBefore(new JwtLoginFilter("/login",authenticationManager()),UsernamePasswordAuthenticationFilter.class).addFilterBefore(new JwtFilter(),UsernamePasswordAuthenticationFilter.class);}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userServiceImpl).passwordEncoder(bcryptPasswordEncoder);}}
测试错误密码登录:
测试正确密码登录:
测试访问(有权限):
测试访问(无权限):
测试访问(错误token):
JWT教程_2 SpringSecurity与JWT整合相关推荐
- JWT 教程_1 SpringBoot与JWT整合
https://gitee.com/fakerlove/spring-security 文章目录 1. 介绍 2. SpringBoot与JWT整合 2.1 JWT的结构: 2.2 JWT的使用测试: ...
- JWT教程_3 oauth和JWT 整合
https://gitee.com/fakerlove/spring-security 4. oauth和JWT 整合 编写jwt 类 package com.example.demo3.config ...
- SpringSecurity与JWT认证
SpringSecurity 教程 1. 简介 1.1 概念 1.2 入门案例 1.3 自定义登录逻辑 1.4 自定义登录页面 1.5 自定用户名参数 1.5 自定义成功处理器 1.6 登录失败处理器 ...
- GitHub开源项目学习 电商系统Mall (五) mall整合SpringSecurity和JWT实现认证和授权(二)
mall整合SpringSecurity和JWT实现认证和授权(二) https://github.com/macrozheng/mall 登录注册功能实现 UmsAdminController类 实 ...
- GitHub开源项目学习 电商系统Mall (四) mall整合SpringSecurity和JWT实现认证和授权(一)
mall整合SpringSecurity和JWT实现认证和授权(一) https://github.com/macrozheng/mall 跳过了官方Learning中较简单的Swagger-UI的实 ...
- 商城项目(三)整合SpringSecurity和JWT实现认证和授权
整合SpringSecurity和JWT实现认证和授权 环境搭建 SpringSecurity JWT Hutool 项目使用表说明 ums_admin:后台用户表 ums_role:后台用户角色表 ...
- jwt判断token是否过期_4spring-security5整合jwt做登录、权限验证,全网最全!!!可用...
github源码: https://github.com/gyb123456/spring-security5-jwt,最烦那些写文档只截图一半还不给源码的人,要不你就截全图,要不就给源码! 前言: ...
- SpringSecurity,jwt oathu sso,YeZiJie
Spring Security 中文文档 参考手册 中文版 (springcloud.cc) 一 springsecurity 1 SpringSecurity框架简介 安全框架:解决系统安全问题的框 ...
- SpringBoot + SpringSecurity + Mybatis-Plus + JWT + Redis 实现分布式系统认证和授权(刷新Token和Token黑名单)
1. 前提 本文在基于SpringBoot整合SpringSecurity实现JWT的前提中添加刷新Token以及添加Token黑名单.在浏览之前,请查看博客: SpringBoot + Sp ...
最新文章
- C# Task的使用
- 【Java面试题】3 Java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?超详细解析...
- jacoco入门_代码覆盖度工具jacoco的入门
- php如何按降序,PHP数组如何按键名实现降序排列
- Altera的几个常用的Synthesis attributes(转载)
- 装饰器3--装饰器作用原理
- 我的第一个Python程序(简单的用户名密码登录程序)
- vue向ifarm传值_vue组件间传值
- 阿里云服务器ECS云盾提醒网站被WebShell木马后门分析与对策
- oracle 导入性能,EXP,EXPDP数据导入本地性能测试的一点心得
- SSRF libcurl protocol wrappers利用分析
- 小米笔记安装双系统linux,小米笔记本电脑怎么安装双系统?-小米win7
- Google 2018 更新内容
- Yapi 配置 pm2服务
- 搭建Web服务器建网站的步骤
- 用Python分析了30000+《独行月球》影评数据,看看观众们怎么说~
- Python毕业设计选题推荐
- 对8086的存储器扩展
- python生成6位数验证码_Python随机生成一个6位的验证码代码分享
- SystemUI架构分析学习
热门文章
- Android中的USB中的UsbAccessory和UsbDevice的区别
- Android 循环缓冲区
- postgis之获取二进制的长度
- Tensorflow2.0实战之GAN
- python 科学计算设计_Python程序设计与科学计算
- java placeholder_java swing JTextField设置PlaceHolder
- python string转date类型_java string类型怎么转化成date类型
- 计算机地址如何表达,计算机中的地址是表示
- rstudio server docker 部署_Docker环境运行Spring Cloud项目
- js数组获取index_想自学JS吗?想提升JS底层原理吗?76张脑图带你彻底搞懂原生JS...