zoukankan      html  css  js  c++  java
  • [Java Spring JWT] JWT example

    Provider:

    package com.example.ec.security;
    
    import com.example.ec.domain.Role;
    import io.jsonwebtoken.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.stereotype.Component;
    
    import java.util.*;
    import java.util.stream.Collectors;
    
    /**
     * Utility Class for common Java Web Token operations
     *
     * Created by Mary Ellen Bowman
     */
    @Component
    public class JwtProvider{
    
        private final String ROLES_KEY = "roles";
    
        private JwtParser parser;
    
        private String secretKey;
        private long validityInMilliseconds;
    
        @Autowired
        public JwtProvider(@Value("${security.jwt.token.secret-key}") String secretKey,
                           @Value("${security.jwt.token.expiration}")long validityInMilliseconds) {
    
            this.secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes());
            this.validityInMilliseconds = validityInMilliseconds;
        }
    
        /**
         * Create JWT string given username and roles.
         *
         * @param username
         * @param roles
         * @return jwt string
         */
        public String createToken(String username, List<Role> roles) {
            //Add the username to the payload
            Claims claims = Jwts.claims().setSubject(username);
            //Convert roles to Spring Security SimpleGrantedAuthority objects,
            //Add to Simple Granted Authority objects to claims
            claims.put(ROLES_KEY, roles.stream().map(role ->new SimpleGrantedAuthority(role.getAuthority()))
                                            .filter(Objects::nonNull)
                                            .collect(Collectors.toList()));
            //Build the Token
            Date now = new Date();
            return Jwts.builder()
                    .setClaims(claims)
                    .setIssuedAt(now)
                    .setExpiration(new Date(now.getTime() + validityInMilliseconds))
                    .signWith(SignatureAlgorithm.HS256, secretKey)
                    .compact();
        }
    
        /**
         * Validate the JWT String
         *
         * @param token JWT string
         * @return true if valid, false otherwise
         */
        public boolean isValidToken(String token) {
            try {
                Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
                return true;
            } catch (JwtException | IllegalArgumentException e) {
                return false;
            }
        }
    
        /**
         * Get the username from the token string
         *
         * @param token jwt
         * @return username
         */
        public String getUsername(String token) {
            return Jwts.parser().setSigningKey(secretKey)
                    .parseClaimsJws(token).getBody().getSubject();
        }
    
        /**
         * Get the roles from the token string
         *
         * @param token jwt
         * @return username
         */
        public List<GrantedAuthority> getRoles(String token) {
            List<Map<String, String>>  roleClaims = Jwts.parser().setSigningKey(secretKey)
                    .parseClaimsJws(token).getBody().get(ROLES_KEY, List.class);
            return roleClaims.stream().map(roleClaim ->
                    new SimpleGrantedAuthority(roleClaim.get("authority")))
                    .collect(Collectors.toList());
        }
    }

    Filter:

    package com.example.ec.security;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
    import org.springframework.web.filter.GenericFilterBean;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    import java.util.Optional;
    
    /**
     * Filter for Java Web Token Authentication and Authorization
     *
     * Created by Mary Ellen Bowman
     */
    public class JwtTokenFilter extends GenericFilterBean {
        private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenFilter.class);
        private static final String BEARER = "Bearer";
    
        private ExploreCaliUserDetailsService userDetailsService;
    
        public JwtTokenFilter(ExploreCaliUserDetailsService userDetailsService) {
            this.userDetailsService = userDetailsService;
        }
    
        /**
         * Determine if there is a JWT as part of the HTTP Request Header.
         * If it is valid then set the current context With the Authentication(user and roles) found in the token
         *
         * @param req Servlet Request
         * @param res Servlet Response
         * @param filterChain Filter Chain
         * @throws IOException
         * @throws ServletException
         */
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)
                throws IOException, ServletException {
            LOGGER.info("Process request to check for a JSON Web Token ");
            //Check for Authorization:Bearer JWT
            String headerValue = ((HttpServletRequest)req).getHeader("Authorization");
            getBearerToken(headerValue).ifPresent(token-> {
                //Pull the Username and Roles from the JWT to construct the user details
                userDetailsService.loadUserByJwtToken(token).ifPresent(userDetails -> {
                    //Add the user details (Permissions) to the Context for just this API invocation
                    SecurityContextHolder.getContext().setAuthentication(
                            new PreAuthenticatedAuthenticationToken(userDetails, "", userDetails.getAuthorities()));
                });
            });
    
            //move on to the next filter in the chains
            filterChain.doFilter(req, res);
        }
    
        /**
         * if present, extract the jwt token from the "Bearer <jwt>" header value.
         *
         * @param headerVal
         * @return jwt if present, empty otherwise
         */
        private Optional<String> getBearerToken(String headerVal) {
            if (headerVal != null && headerVal.startsWith(BEARER)) {
                return Optional.of(headerVal.replace(BEARER, "").trim());
            }
            return Optional.empty();
        }
    }

    Security Config:

    package com.example.ec.security;
    
    import com.example.ec.repo.RoleRepository;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.authentication.AuthenticationManager;
    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.WebSecurityConfigurerAdapter;
    import org.springframework.security.config.http.SessionCreationPolicy;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    
    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Autowired
        RoleRepository roleRepository;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            // Entry points
            http.authorizeRequests()
                    .antMatchers("/packages/**").permitAll()
                    .antMatchers("/tours/**").permitAll()
                    .antMatchers("/ratings/**").permitAll()
                    .antMatchers("/users/signin").permitAll()
                    // Disallow everything else..
                    .anyRequest().authenticated();
    
            // Disable CSRF (cross site request forgery)
            http.csrf().disable();
    
            // No session will be created or used by spring security
            http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    
            http.addFilterBefore(new JwtTokenFilter(userDetailsService), UsernamePasswordAuthenticationFilter.class);
        }
    
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder(12);
        }
    
    }

    Usage to the endpoints:

    package com.example.ec.web;
    
    import com.example.ec.domain.User;
    import com.example.ec.service.UserService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpStatus;
    import org.springframework.security.access.prepost.PreAuthorize;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.client.HttpServerErrorException;
    
    import javax.validation.Valid;
    import java.util.List;
    
    @RestController
    @RequestMapping("/users")
    public class UserController {
        private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);
    
        @Autowired
        private UserService userService;
    
        @PostMapping("/signin")
        public String login(@RequestBody @Valid LoginDto loginDto) {
           return userService.signin(loginDto.getUsername(), loginDto.getPassword()).orElseThrow(()->
                   new HttpServerErrorException(HttpStatus.FORBIDDEN, "Login Failed"));
        }
    
        @PostMapping("/signup")
        @PreAuthorize("hasRole('ROLE_ADMIN')")
        @ResponseStatus(HttpStatus.CREATED)
        public User signup(@RequestBody @Valid LoginDto loginDto){
            return userService.signup(loginDto.getUsername(), loginDto.getPassword(), loginDto.getFirstName(),
                    loginDto.getLastName()).orElseThrow(() -> new HttpServerErrorException(HttpStatus.BAD_REQUEST,"User already exists"));
        }
    
        @GetMapping
        @PreAuthorize("hasRole('ROLE_ADMIN')")
        public List<User> getAllUsers() {
            return userService.getAll();
        }
    
    }
  • 相关阅读:
    2020.07.01
    2020年5月9日
    2020年4月25日
    2020年4月24日
    2020年4月23日
    2020年4月22日
    2020年3月29日
    2020.3.25
    nacos源码解析(三)-注册中心服务注册处理
    nacos源码解析(二)-客户端如何访问注册中心
  • 原文地址:https://www.cnblogs.com/Answer1215/p/14199035.html
Copyright © 2011-2022 走看看