zoukankan      html  css  js  c++  java
  • spring-security-jwt的总结与实现

    jwt的总结与实现

    请求和响应

    1. 请求实体-规定的客户端传给jwt认证服务器的参数
    2. 响应实体-规定了jwt服务端颁发给客户端的jwt token的结果

    jwtUtil类

    主要提供了jwt的实现方法,如加密规则,生成token,获取token等

    SecurityConfigurer类

    主要设置了加密方法,用户信息读取方法,配置路由的授权规则等

    过滤器JwtRequestFilter

    对指定的http请求进行拦截和用户认证等

    测试类

    可以使用postman类似的工具进行jwt的测试

    1. post http://localhost:8080/authenticate {"username": "zzl","password": "zzl"} 返回jwt token
    2. get http://localhost:8080/index Header ["Authorization":"Bearer 上一步拿到的token""]

    jwt相关代码

    pom.xml主要依赖

       <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>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.1</version>
            </dependency>
            <dependency>
                <groupId>javax.xml.bind</groupId>
                <artifactId>jaxb-api</artifactId>
                <version>2.3.0</version>
            </dependency>
    

    JwtUtil.cs

    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.function.Function;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.stereotype.Component;
    
    @Component
    public class JwtUtil {
      private String SECRET_KEY = "secret";
    
      public String extractUsername(String token) {
        return extractClaim(token, Claims::getSubject);
      }
    
      public Date extractExpiration(String token) {
        return extractClaim(token, Claims::getExpiration);
      }
    
      public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = extractAllClaims(token);
        return claimsResolver.apply(claims);
      }
    
      private Claims extractAllClaims(String token) {
        return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
      }
    
      private Boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
      }
    
      public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        return createToken(claims, userDetails.getUsername());
      }
    
      private String createToken(Map<String, Object> claims, String subject) {
    
        return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(
            new Date(System.currentTimeMillis()))
            .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
            .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
      }
    
      public Boolean validateToken(String token, UserDetails userDetails) {
        final String username = extractUsername(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
      }
    }
    
    

    SecurityConfigurer.cs

    
    import com.lind.springsecurityjwt.filter.JwtRequestFilter;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.security.authentication.AuthenticationManager;
    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.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.config.http.SessionCreationPolicy;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.crypto.password.NoOpPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    
    @EnableWebSecurity
    public class SecurityConfigurer extends WebSecurityConfigurerAdapter {
    
      @Autowired
      private UserDetailsService myUserDetailsService;
      @Autowired
      private JwtRequestFilter jwtRequestFilter;
    
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService);
      }
    
      @Bean
      public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
      }
    
      @Override
      @Bean
      public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
      }
    
      @Override
      protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable()
            .authorizeRequests().antMatchers("/authenticate").permitAll().
            anyRequest().authenticated().and().
            exceptionHandling().and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    
      }
    }
    
    

    JwtRequestFilter.cs

    import com.lind.springsecurityjwt.service.MyUserDetailsService;
    import com.lind.springsecurityjwt.util.JwtUtil;
    import java.io.IOException;
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
    import org.springframework.stereotype.Component;
    import org.springframework.web.filter.OncePerRequestFilter;
    
    @Component
    public class JwtRequestFilter extends OncePerRequestFilter {
      @Autowired
      private MyUserDetailsService userDetailsService;
    
      @Autowired
      private JwtUtil jwtUtil;
    
      @Override
      protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
          throws ServletException, IOException {
    
        final String authorizationHeader = request.getHeader("Authorization");
    
        String username = null;
        String jwt = null;
    
        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
          jwt = authorizationHeader.substring(7);
          username = jwtUtil.extractUsername(jwt);
        }
    
    
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
    
          UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
    
          if (jwtUtil.validateToken(jwt, userDetails)) {
    
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                userDetails, null, userDetails.getAuthorities());
            usernamePasswordAuthenticationToken
                .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
          }
        }
        chain.doFilter(request, response);
      }
    
    }
    
    
  • 相关阅读:
    三、Vue CLI-单页面
    width100%,设置padding或border溢出解决方法
    一、Linux平台部署ASP.NET、ASP.NET CORE、PHP
    二、Core授权-2 之.net core 基于Identity 授权
    一、doT.js使用笔记
    一、域名认证信息
    HB-打包
    一、模型验证CoreWebApi 管道方式(非过滤器处理)2(IApplicationBuilder扩展方法的另一种写法)
    python 写的几道题
    美团面试总结
  • 原文地址:https://www.cnblogs.com/lori/p/12382761.html
Copyright © 2011-2022 走看看