本文介绍basic auth和JWT验证结合

目录结构

依赖

  1. <dependency>
  2. <groupId>io.jsonwebtoken</groupId>
  3. <artifactId>jjwt</artifactId>
  4. <version>0.9.1</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.auth0</groupId>
  8. <artifactId>auth0</artifactId>
  9. <version>1.8.0</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.auth0</groupId>
  13. <artifactId>auth0-spring-security-api</artifactId>
  14. <version>1.1.0</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.springframework.boot</groupId>
  18. <artifactId>spring-boot-starter-security</artifactId>
  19. </dependency>
  20. <dependency>
  21. <groupId>org.json</groupId>
  22. <artifactId>json</artifactId>
  23. <version>20180813</version>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.glassfish</groupId>
  27. <artifactId>javax.xml.bind</artifactId>
  28. <version>10.0-b28</version>
  29. </dependency>

config配置文件WebSecurityConfig

  1. package com.springlearn.learn.config;
  2. import com.springlearn.learn.filter.JWTAuthenticationFilter;
  3. import com.springlearn.learn.filter.JWTLoginFilter;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.http.HttpMethod;
  8. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  9. import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
  10. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  11. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  12. import org.springframework.security.core.userdetails.User;
  13. import org.springframework.security.core.userdetails.UserDetails;
  14. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  15. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  16. import org.springframework.web.servlet.config.annotation.CorsRegistry;
  17. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  18. @Configuration
  19. public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {
  20. @Override
  21. protected void configure(HttpSecurity http) throws Exception {
  22. http.cors().and().csrf().disable();
  23. // 所有的请求都要验证
  24. http.authorizeRequests()
  25. .antMatchers("/").permitAll() // 访问 "/" 无需验证
  26. .antMatchers(HttpMethod.POST, "/login").permitAll() // 访问 "/login" 无需token即可进入
  27. .antMatchers(HttpMethod.GET, "/login").permitAll()
  28. .anyRequest()
  29. .authenticated()
  30. .and()
  31. .addFilterBefore( // 添加验证过滤器
  32. new JWTLoginFilter("/login", authenticationManager()),
  33. UsernamePasswordAuthenticationFilter.class
  34. )
  35. .addFilterBefore(
  36. new JWTAuthenticationFilter(),
  37. UsernamePasswordAuthenticationFilter.class
  38. );
  39. }
  40. @Bean
  41. public BCryptPasswordEncoder passwordEncoder() {
  42. BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
  43. return bCryptPasswordEncoder;
  44. }
  45. @Autowired
  46. public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
  47. String password = "234";
  48. String encrytedPassword = this.passwordEncoder().encode(password);
  49. System.out.println("Encoded password = " + encrytedPassword);
  50. // 这里使用写死的验证,你可以在这里访问数据库
  51. InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> mngConfig = auth.inMemoryAuthentication();
  52. UserDetails u1 = User.withUsername("yejiawei").password(encrytedPassword).roles("ADMIN").build();
  53. UserDetails u2 = User.withUsername("donglei").password(encrytedPassword).roles("USER").build();
  54. mngConfig.withUser(u1);
  55. mngConfig.withUser(u2);
  56. }
  57. @Override
  58. public void addCorsMappings(CorsRegistry registry) {
  59. registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
  60. .allowedHeaders("*");
  61. }
  62. }

filter过滤器JWTLoginFilter

  1. package com.springlearn.learn.filter;
  2. import java.io.IOException;
  3. import java.util.Collections;
  4. import java.util.HashMap;
  5. import java.util.Iterator;
  6. import java.util.Map;
  7. import java.util.stream.Collectors;
  8. import javax.servlet.FilterChain;
  9. import javax.servlet.ServletException;
  10. import javax.servlet.http.HttpServletRequest;
  11. import javax.servlet.http.HttpServletResponse;
  12. import com.springlearn.learn.service.TokenAuthenticationService;
  13. import org.json.JSONObject;
  14. import org.springframework.security.authentication.AuthenticationManager;
  15. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  16. import org.springframework.security.core.Authentication;
  17. import org.springframework.security.core.AuthenticationException;
  18. import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
  19. import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
  20. public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter{
  21. public JWTLoginFilter(String url, AuthenticationManager authManager) {
  22. super(new AntPathRequestMatcher(url));
  23. setAuthenticationManager(authManager);
  24. }
  25. @Override
  26. public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
  27. throws AuthenticationException, IOException, ServletException {
  28. // get方式获取参数
  29. // String username = request.getParameter("username");
  30. // String password = request.getParameter("password");
  31. // post方式获取数据
  32. String s = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
  33. JSONObject jsonObject = new JSONObject(s);
  34. HashMap<String, String> result = new HashMap<String, String>();
  35. String key = null;
  36. Iterator<?> keys = jsonObject.keys();
  37. while(keys.hasNext()) {
  38. key = (String) keys.next();
  39. result.put(key, jsonObject.getString(key));
  40. }
  41. System.out.printf("JWTLoginFilter.attemptAuthentication: username/password= %s,%s", result.get("username"), result.get("password"));
  42. System.out.println();
  43. return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(result.get("username"), result.get("password"), Collections.emptyList()));
  44. }
  45. @Override
  46. protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
  47. Authentication authResult) throws IOException, ServletException {
  48. System.out.println("JWTLoginFilter.successfulAuthentication:");
  49. // Write Authorization to Headers of Response.
  50. TokenAuthenticationService.addAuthentication(response, authResult.getName());
  51. String authorizationString = response.getHeader("Authorization");
  52. System.out.println("Authorization String=" + authorizationString);
  53. }
  54. @Override
  55. protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
  56. response.setContentType("application/json");
  57. response.setStatus(HttpServletResponse.SC_OK);
  58. response.getOutputStream().println((new JSONObject(){{
  59. put("status", 500);
  60. put("message", "Internal Server Error!!!");
  61. put("result", JSONObject.NULL);
  62. }}).toString());
  63. }
  64. }

filter过滤器JWTAuthenticationFilter

  1. package com.springlearn.learn.filter;
  2. import java.io.IOException;
  3. import javax.servlet.FilterChain;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.ServletRequest;
  6. import javax.servlet.ServletResponse;
  7. import javax.servlet.http.HttpServletRequest;
  8. import com.springlearn.learn.service.TokenAuthenticationService;
  9. import org.springframework.security.core.Authentication;
  10. import org.springframework.security.core.context.SecurityContextHolder;
  11. import org.springframework.web.filter.GenericFilterBean;
  12. public class JWTAuthenticationFilter extends GenericFilterBean {
  13. @Override
  14. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
  15. throws IOException, ServletException {
  16. System.out.println("JWTAuthenticationFilter.doFilter");
  17. Authentication authentication = TokenAuthenticationService.getAuthentication((HttpServletRequest) servletRequest);
  18. SecurityContextHolder.getContext().setAuthentication(authentication);
  19. filterChain.doFilter(servletRequest, servletResponse);
  20. }
  21. }

service中的TokenAuthenticationService

  1. package com.springlearn.learn.service;
  2. import java.io.IOException;
  3. import java.util.Collections;
  4. import java.util.Date;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import org.json.JSONObject;
  8. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  9. import org.springframework.security.core.Authentication;
  10. import io.jsonwebtoken.Jwts;
  11. import io.jsonwebtoken.SignatureAlgorithm;
  12. public class TokenAuthenticationService {
  13. static final long _expiretime = 864_000_000;
  14. static final String _secret = "ThisIsASecret";
  15. static final String _token_prefix = "Bearer";
  16. static final String _header_string = "Authorization";
  17. public static void addAuthentication(HttpServletResponse res, String username) throws IOException {
  18. String JWT =
  19. Jwts.builder()
  20. .setSubject(username)
  21. .setExpiration(new Date(System.currentTimeMillis() + _expiretime))
  22. .signWith(SignatureAlgorithm.HS512, _secret).compact();
  23. res.addHeader(_header_string, _token_prefix + " " + JWT);
  24. res.setContentType("application/json");
  25. res.setStatus(HttpServletResponse.SC_OK);
  26. res.getOutputStream().println((new JSONObject(){{
  27. put("status", 0);
  28. put("message", "");
  29. put("result", JWT);
  30. }}).toString());
  31. }
  32. public static Authentication getAuthentication(HttpServletRequest request) {
  33. String token = request.getHeader(_header_string);
  34. if (token != null) {
  35. // parse the token.
  36. String user = Jwts.parser().setSigningKey(_secret).parseClaimsJws(token.replace(_token_prefix, "")).getBody()
  37. .getSubject();
  38. return user != null ? new UsernamePasswordAuthenticationToken(user, null, Collections.emptyList()) : null;
  39. }
  40. return null;
  41. }
  42. }

启动文件DemoApplication

  1. package com.springlearn.learn;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class DemoApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(DemoApplication.class, args);
  8. }
  9. }

Controller中的TestController

  1. package com.springlearn.learn.controller;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import org.springframework.web.bind.annotation.RequestBody;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.RequestMethod;
  7. import org.springframework.web.bind.annotation.ResponseBody;
  8. import org.springframework.web.bind.annotation.RestController;
  9. @RestController
  10. public class TestController {
  11. @ResponseBody
  12. @RequestMapping(value = "/AuthTest", method = RequestMethod.GET)
  13. public String AuthTest(HttpServletRequest request, HttpServletResponse response) {
  14. return "OK";
  15. }
  16. @ResponseBody
  17. @RequestMapping(value = "/login", method = RequestMethod.GET)
  18. public String Login(@RequestBody Object user, HttpServletRequest request, HttpServletResponse response) {
  19. return "OK";
  20. }
  21. }

前端测试

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Document</title>
  8. <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  9. <script>
  10. axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
  11. axios.post('http://localhost:9001/login', {
  12. username: 'yejiawei',
  13. password: '234'
  14. }).then(function (response) {
  15. localStorage.setItem("token", response.data.result)
  16. }).catch(function (error) {
  17. console.log(error);
  18. }).then(function () {
  19. });
  20. // axios.get('http://localhost:9001/AuthTest', {
  21. // headers: {
  22. // "Authorization": localStorage.getItem("token")
  23. // }
  24. // }).then(function (response) {
  25. // console.log(response.data);
  26. // }).catch(function (error) {
  27. // console.log(error);
  28. // }).then(function () {
  29. // });
  30. </script>
  31. </head>
  32. <body>
  33. </body>
  34. </html>

springboot成神之——basic auth和JWT验证结合的更多相关文章

  1. springboot成神之——Basic Auth应用

    本文介绍Basic Auth在spring中的应用 目录结构 依赖 入口DemoApplication 验证Authenication 配置WebSecurityConfig 控制器TestContr ...

  2. springboot成神之——ioc容器(依赖注入)

    springboot成神之--ioc容器(依赖注入) spring的ioc功能 文件目录结构 lang Chinese English GreetingService MyRepository MyC ...

  3. springboot成神之——application.properties所有可用属性

    application.properties所有可用属性 # =================================================================== # ...

  4. springboot成神之——springboot入门使用

    springboot创建webservice访问mysql(使用maven) 安装 起步 spring常用命令 spring常见注释 springboot入门级使用 配置你的pom.xml文件 配置文 ...

  5. springboot成神之——mybatis和mybatis-generator

    项目结构 依赖 generator配置文件 properties配置 生成文件 使用Example 本文讲解如何在spring-boot中使用mybatis和mybatis-generator自动生成 ...

  6. springboot成神之——swagger文档自动生成工具

    本文讲解如何在spring-boot中使用swagger文档自动生成工具 目录结构 说明 依赖 SwaggerConfig 开启api界面 JSR 303注释信息 Swagger核心注释 User T ...

  7. springboot成神之——log4j2的使用

    本文介绍如何在spring-boot中使用log4j2 说明 依赖 日志记录语句 log4j2配置文件 本文介绍如何在spring-boot中使用log4j2 说明 log4j2本身使用是非常简单的, ...

  8. springboot成神之——mybatis在spring-boot中使用的几种方式

    本文介绍mybatis在spring-boot中使用的几种方式 项目结构 依赖 WebConfig DemoApplication 方式一--@Select User DemoApplication ...

  9. springboot成神之——发送邮件

    本文介绍如何用spring发送邮件 目录结构 依赖 MailConfig TestController 测试 本文介绍如何用spring发送邮件 目录结构 依赖 <dependency> ...

随机推荐

  1. H5测试

    H5是什么? H5的全称是HTML5,其实就是:移动端WEB页面. H5与原生 APP的区别: APP是使用原生系统内核的,相当于直接在系统上操作,是我们传统意义上的软件,更加稳定. H5的APP先得 ...

  2. JAVA定时任务Timer

    故事起因 因业务需要,写了一个定时任务Timer,任务将在每天的凌晨2点执行,代码顺利码完,一切就绪,开始测试.运行程序,为了节省时间,将系统时间调整为第二天凌晨1点59分,看着秒针滴答滴答的转动,期 ...

  3. 51nod-1259-分块+dp

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1259 1259 整数划分 V2 基准时间限制:1 秒 空间限制:1310 ...

  4. JavaScript中url 传递参数(特殊字符)解决方法及转码解码的介绍

    有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号,那么就要使用他们的编码了.下表中列出了一些URL特殊符号及编码   十六进制值 1. + URL 中+号表示空格 %2B 2. 空 ...

  5. H264的start code是什么?

    H.264起始码 在网络传输h264数据时,一个UDP包就是一个NALU,解码器可以很方便的检测出NAL分界和解码.但是如果编码数据存储为一个文件,原来的解码器将无法从数据流中分别出每个NAL的起始位 ...

  6. Git介绍及基本操作

    Git基本概念 在Git中,我们将需要进行版本控制的文件目录叫做一个仓库(repository),每个仓库可以简单理解成一个目录,这个目录里面的所有文件都通过Git来实现版本管理,Git都能跟踪并记录 ...

  7. Java并发编程总结

    基础概念 1.什么是原子操作?在Java Concurrency API中有哪些原子类(atomic classes)?原子操作(atomic operation)意为"不可被中断的一个或一 ...

  8. 混用Application.LoadLevel 和 PhotonNetwork.LoadLevel

    最近这一周从上周五晚上加完班回家夜里都12点了. 又赶紧送孩子去儿童医院  .. 就肺炎住院了.  真是有啥别有病呢.  悲剧的是我周三夜里陪了一夜后. 转天晚上也发烧了.. 周四 周五输了两天液. ...

  9. xcode加载静态链接库.a文件总是失败

    明明项目是对的,代码没有问题,并且把项目作为库项目引入到新项目中没问题,可是一旦把项目编译出.a文件,引入到新项目中不知为何会有几率出现一大堆错误,其实是xcode的缓存机制在作怪,去这个目录: /U ...

  10. Jolt Awards: The Best Books

    Jolt大奖素有“软件业界的奥斯卡”之美誉,共设通用类图书.技术类图书.语言和开发环境.框架库和组件.开发者网站等十余个分类,每个分类设有一个“震撼奖”(Jolt Award)和三个“生产力奖”(Pr ...