SpringSecurity整合jwt

x33g5p2x  于2022-03-21 转载在 Spring  
字(10.6k)|赞(0)|评价(0)|浏览(267)

1.pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.6.4</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.yl</groupId>
  12. <artifactId>jwt</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>jwt</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>11</java.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-security</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-web</artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>io.jsonwebtoken</groupId>
  30. <artifactId>jjwt</artifactId>
  31. <version>0.9.1</version>
  32. </dependency>
  33. <dependency>
  34. <groupId>javax.xml.bind</groupId>
  35. <artifactId>jaxb-api</artifactId>
  36. <version>2.3.0</version>
  37. </dependency>
  38. <dependency>
  39. <groupId>com.sun.xml.bind</groupId>
  40. <artifactId>jaxb-impl</artifactId>
  41. <version>2.3.0</version>
  42. </dependency>
  43. <dependency>
  44. <groupId>com.sun.xml.bind</groupId>
  45. <artifactId>jaxb-core</artifactId>
  46. <version>2.3.0</version>
  47. </dependency>
  48. <dependency>
  49. <groupId>javax.activation</groupId>
  50. <artifactId>activation</artifactId>
  51. <version>1.1.1</version>
  52. </dependency>
  53. <dependency>
  54. <groupId>org.springframework.boot</groupId>
  55. <artifactId>spring-boot-starter-test</artifactId>
  56. <scope>test</scope>
  57. </dependency>
  58. <dependency>
  59. <groupId>org.springframework.security</groupId>
  60. <artifactId>spring-security-test</artifactId>
  61. <scope>test</scope>
  62. </dependency>
  63. </dependencies>
  64. <build>
  65. <plugins>
  66. <plugin>
  67. <groupId>org.springframework.boot</groupId>
  68. <artifactId>spring-boot-maven-plugin</artifactId>
  69. </plugin>
  70. </plugins>
  71. </build>
  72. </project>

2.用户实体类

  1. package com.yl.jwt.model;
  2. import org.springframework.security.core.GrantedAuthority;
  3. import org.springframework.security.core.userdetails.UserDetails;
  4. import java.util.Collection;
  5. import java.util.List;
  6. public class User implements UserDetails {
  7. private String username;
  8. private String password;
  9. private List<GrantedAuthority> authorities;
  10. @Override
  11. public Collection<? extends GrantedAuthority> getAuthorities() {
  12. return null;
  13. }
  14. @Override
  15. public String getPassword() {
  16. return password;
  17. }
  18. @Override
  19. public String getUsername() {
  20. return username;
  21. }
  22. @Override
  23. public boolean isAccountNonExpired() {
  24. return true;
  25. }
  26. @Override
  27. public boolean isAccountNonLocked() {
  28. return true;
  29. }
  30. @Override
  31. public boolean isCredentialsNonExpired() {
  32. return true;
  33. }
  34. @Override
  35. public boolean isEnabled() {
  36. return true;
  37. }
  38. public void setUsername(String username) {
  39. this.username = username;
  40. }
  41. public void setPassword(String password) {
  42. this.password = password;
  43. }
  44. public void setAuthorities(List<GrantedAuthority> authorities) {
  45. this.authorities = authorities;
  46. }
  47. }

3. 自定义认证拦截器,登录成功,则返回token

  1. package com.yl.jwt.filter;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import com.yl.jwt.model.User;
  4. import io.jsonwebtoken.Jwts;
  5. import io.jsonwebtoken.SignatureAlgorithm;
  6. import org.springframework.security.authentication.AuthenticationManager;
  7. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  8. import org.springframework.security.core.Authentication;
  9. import org.springframework.security.core.AuthenticationException;
  10. import org.springframework.security.core.GrantedAuthority;
  11. import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
  12. import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
  13. import javax.servlet.FilterChain;
  14. import javax.servlet.ServletException;
  15. import javax.servlet.http.HttpServletRequest;
  16. import javax.servlet.http.HttpServletResponse;
  17. import java.io.IOException;
  18. import java.io.PrintWriter;
  19. import java.util.Collection;
  20. import java.util.Date;
  21. import java.util.HashMap;
  22. import java.util.Map;
  23. //登录成功返回token,登录失败返回错误信息
  24. public class JwtLoginFilter extends AbstractAuthenticationProcessingFilter {
  25. public JwtLoginFilter(String defaultFilterProcessesUrl, AuthenticationManager authenticationManager) {
  26. super(new AntPathRequestMatcher(defaultFilterProcessesUrl));
  27. setAuthenticationManager(authenticationManager);
  28. }
  29. @Override
  30. public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
  31. User user = new ObjectMapper().readValue(request.getInputStream(),User.class);
  32. return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword()));
  33. }
  34. //登陆成功
  35. @Override
  36. protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
  37. //获取当前用户的角色
  38. Collection<? extends GrantedAuthority> authorities = authResult.getAuthorities();
  39. StringBuilder sb = new StringBuilder();
  40. for (GrantedAuthority authority : authorities) {
  41. sb.append(authorities + ",");
  42. }
  43. // 构造token
  44. String token = Jwts.builder()
  45. .claim("authorities",sb)
  46. .setSubject(authResult.getName())
  47. .setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 1000))
  48. .signWith(SignatureAlgorithm.HS512,"admin@123")
  49. .compact();
  50. Map<String,Object> map = new HashMap<>();
  51. map.put("token",token);
  52. map.put("msg","login success");
  53. response.setContentType("application/json;charset=utf-8");
  54. PrintWriter writer = response.getWriter();
  55. writer.write(new ObjectMapper().writeValueAsString(map));
  56. writer.flush();
  57. writer.close();
  58. }
  59. //登录失败
  60. @Override
  61. protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
  62. Map<String,Object> map = new HashMap<>();
  63. map.put("msg","login fail");
  64. response.setContentType("application/json;charset=utf-8");
  65. PrintWriter writer = response.getWriter();
  66. writer.write(new ObjectMapper().writeValueAsString(map));
  67. writer.flush();
  68. writer.close();
  69. }
  70. }

4. 自定义校验拦截器,校验用户每次发请求时携带的token是否正确

  1. package com.yl.jwt.filter;
  2. import io.jsonwebtoken.Claims;
  3. import io.jsonwebtoken.Jws;
  4. import io.jsonwebtoken.Jwts;
  5. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  6. import org.springframework.security.core.GrantedAuthority;
  7. import org.springframework.security.core.authority.AuthorityUtils;
  8. import org.springframework.security.core.context.SecurityContext;
  9. import org.springframework.security.core.context.SecurityContextHolder;
  10. import org.springframework.web.filter.GenericFilterBean;
  11. import javax.servlet.FilterChain;
  12. import javax.servlet.ServletException;
  13. import javax.servlet.ServletRequest;
  14. import javax.servlet.ServletResponse;
  15. import javax.servlet.http.HttpServletRequest;
  16. import java.io.IOException;
  17. import java.util.List;
  18. //用于校验每次用户访问接口时携带的token正不正确
  19. public class JwtFilter extends GenericFilterBean {
  20. @Override
  21. public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
  22. HttpServletRequest req = (HttpServletRequest)request;
  23. //从请求头获取token,注意:前端在传的时候也应当放在请求头里
  24. String authorization = req.getHeader("authorization");
  25. Jws<Claims> jws = Jwts.parser()
  26. .setSigningKey("admin@123")
  27. .parseClaimsJws(authorization.replaceAll("Bearer", ""));
  28. Claims body = jws.getBody();
  29. String username = body.getSubject();
  30. List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) body.get("authorities"));
  31. UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,null,authorities);
  32. SecurityContextHolder.getContext().setAuthentication(token);
  33. filterChain.doFilter(request,response);
  34. }
  35. }

5. security的配置

  1. package com.yl.jwt.config;
  2. import com.yl.jwt.filter.JwtFilter;
  3. import com.yl.jwt.filter.JwtLoginFilter;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  7. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  8. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  9. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  10. import org.springframework.security.crypto.password.PasswordEncoder;
  11. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  12. @Configuration
  13. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  14. @Bean
  15. PasswordEncoder passwordEncoder() {
  16. return new BCryptPasswordEncoder();
  17. }
  18. @Override
  19. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  20. auth.inMemoryAuthentication()
  21. .withUser("root")
  22. .password("$2a$10$O8G0X/sUPAA76MV7U3BwY.3Uo8/QMBcqK678Rwkoz.fowbce.CLtO") //123
  23. .roles("root")
  24. .and()
  25. .withUser("admin")
  26. .password("$2a$10$O8G0X/sUPAA76MV7U3BwY.3Uo8/QMBcqK678Rwkoz.fowbce.CLtO") //123
  27. .roles("admin");
  28. }
  29. @Override
  30. protected void configure(HttpSecurity http) throws Exception {
  31. http.authorizeRequests()
  32. .antMatchers("/root")
  33. .hasRole("root")
  34. .antMatchers("/admin")
  35. .hasRole("admin")
  36. .antMatchers("/login").permitAll()
  37. .anyRequest().authenticated()
  38. .and()
  39. .addFilterBefore(new JwtLoginFilter("/login",authenticationManager()), UsernamePasswordAuthenticationFilter.class)
  40. .addFilterBefore(new JwtFilter(),UsernamePasswordAuthenticationFilter.class)
  41. .csrf().disable();
  42. }
  43. }

6. controller

  1. package com.yl.jwt.controller;
  2. import org.springframework.web.bind.annotation.GetMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4. @RestController
  5. public class HelloController {
  6. @GetMapping("/hello")
  7. public String hello() {
  8. return "hello";
  9. }
  10. @GetMapping("/admin")
  11. public String admin() {
  12. return "hello admin";
  13. }
  14. @GetMapping("/root")
  15. public String root() {
  16. return "hello root";
  17. }
  18. }

7. 测试

1.没携带token访问接口

2.以json格式传参,登录获取token

3.携带token访问接口

相关文章