Nuñ*_*ada 6 java rest jwt spring-boot
我有这门课:
\n@Configuration\n@EnableWebSecurity\n@EnableGlobalMethodSecurity(prePostEnabled = true)\npublic class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter {\n\n private static final String SALT = "fd&lkj\xc2\xa7isfs23#$1*(_)nof";\n\n private final JwtAuthenticationEntryPoint unauthorizedHandler;\n private final JwtTokenUtil jwtTokenUtil;\n private final UserSecurityService userSecurityService;\n\n @Value("${jwt.header}")\n private String tokenHeader;\n\n\n public ApiWebSecurityConfig(JwtAuthenticationEntryPoint unauthorizedHandler, JwtTokenUtil jwtTokenUtil,\n UserSecurityService userSecurityService) {\n this.unauthorizedHandler = unauthorizedHandler;\n this.jwtTokenUtil = jwtTokenUtil;\n this.userSecurityService = userSecurityService;\n }\n\n @Autowired\n public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {\n auth\n .userDetailsService(userSecurityService)\n .passwordEncoder(passwordEncoder());\n }\n\n @Bean\n public BCryptPasswordEncoder passwordEncoder() {\n return new BCryptPasswordEncoder(12, new SecureRandom(SALT.getBytes()));\n }\n\n @Bean\n @Override\n public AuthenticationManager authenticationManagerBean() throws Exception {\n return super.authenticationManagerBean();\n }\n\n @Override\n protected void configure(HttpSecurity httpSecurity) throws Exception {\n\n httpSecurity\n // we don't need CSRF because our token is invulnerable\n .csrf().disable()\n\n .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()\n\n // don't create session\n .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()\n .authorizeRequests()\n // Un-secure H2 Database\n .antMatchers("/h2-console/**/**").permitAll()\n .antMatchers("/api/v1/users").permitAll()\n .antMatchers("/error").permitAll()\n .anyRequest().authenticated();\n\n // Custom JWT based security filter\n JwtAuthorizationTokenFilter authenticationTokenFilter = new JwtAuthorizationTokenFilter(userDetailsService(), jwtTokenUtil, tokenHeader);\n httpSecurity\n .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);\n\n // disable page caching\n httpSecurity\n .headers()\n .frameOptions()\n .sameOrigin() // required to set for H2 else H2 Console will be blank.\n .cacheControl();\n }\n\n @Override\n public void configure(WebSecurity web) {\n\n // AuthenticationTokenFilter will ignore the below paths\n web\n .ignoring()\n .antMatchers(\n HttpMethod.POST,\n "/api/v1/auth"\n )\n .antMatchers(\n HttpMethod.POST,\n "/api/v1/users"\n )\n .antMatchers(\n HttpMethod.GET,\n "/api/v1/countries"\n );\n\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n和
\n@Provider\n@Slf4j\npublic class JwtAuthorizationTokenFilter extends OncePerRequestFilter {\n\n private UserDetailsService userDetailsService;\n private JwtTokenUtil jwtTokenUtil;\n private String tokenHeader;\n\n public JwtAuthorizationTokenFilter(UserDetailsService userDetailsService,\n JwtTokenUtil jwtTokenUtil,\n String tokenHeader) {\n this.userDetailsService = userDetailsService;\n this.jwtTokenUtil = jwtTokenUtil;\n this.tokenHeader = tokenHeader;\n }\n\n\n @Override\n protected boolean shouldNotFilter(HttpServletRequest request) {\n return new AntPathMatcher().match("/api/v1/users",\n request.getServletPath());\n }\n\n\n @Override\n protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException,\n IOException {\n\n log.info("processing authentication for '{}'", request.getRequestURL());\n log.info("tokenHeader '{}'", tokenHeader);\n\n final String requestHeader = request.getHeader(this.tokenHeader);\n\n log.info("requestHeader '{}'", requestHeader);\n\n String username = null;\n String authToken = null;\n\n if (requestHeader != null && requestHeader.startsWith("Bearer ")) {\n authToken = requestHeader.substring(7);\n\n log.info("authToken '{}'", authToken);\n\n try {\n username = jwtTokenUtil.getUsernameFromToken(authToken);\n } catch (IllegalArgumentException e) {\n logger.info("an error occured during getting username from token", e);\n } catch (ExpiredJwtException e) {\n logger.info("the token is expired and not valid anymore", e);\n }\n } else {\n logger.info("couldn't find bearer string, will ignore the header");\n }\n\n log.info("checking authentication for user '{}'", username);\n\n if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {\n logger.info("security context was null, so authorizating user");\n\n // It is not compelling necessary to load the use details from the database. You could also store the information\n // in the token and read it from it. It's up to you ;)\n UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);\n\n // For simple validation it is completely sufficient to just check the token integrity. You don't have to call\n // the database compellingly. Again it's up to you ;)\n if (jwtTokenUtil.validateToken(authToken, userDetails)) {\n UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());\n authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));\n log.info("authorizated user '{}', setting security context", username);\n SecurityContextHolder.getContext().setAuthentication(authentication);\n }\n }\n chain.doFilter(request, response);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n和
\n@RestController\n@Slf4j\npublic class AuthenticationRestController {\n\n\n private static final Logger LOG = LoggerFactory.getLogger (AuthenticationRestController.class);\n\n @Value("${jwt.header}")\n private String tokenHeader;\n\n @Autowired\n private AuthenticationManager authenticationManager;\n\n @Autowired\n private JwtTokenUtil jwtTokenUtil;\n\n @Autowired\n private UserSecurityService userSecurityService;\n\n @PostMapping(path = "/api/v1/auth", consumes = "application/json", produces = "application/json")\n public ResponseEntity<JwtAuthenticationResponse>\n createAuthenticationToken( @RequestBody JwtAuthenticationRequest authenticationRequest,\n HttpServletRequest request) throws AuthenticationException {\n\n LOG.info("authenticating {} " , authenticationRequest.getUsername());\n\n authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());\n\n // Reload password post-security so we can generate the token\n final User userDetails = (User) userSecurityService.loadUserByUsername(authenticationRequest.getUsername());\n\n if (!userDetails.isEnabled()) {\n throw new UserDisabledException();\n }\n\n if (LOG.isDebugEnabled()) {\n LOG.debug("UserDetails userDetails [ " + authenticationRequest.getUsername() + " ]");\n }\n\n\n final String token = jwtTokenUtil.generateToken(userDetails);\n\n // Return the token\n return ResponseEntity.ok(new JwtAuthenticationResponse(token));\n }\n\n\n @GetMapping(path = "${jwt.route.authentication.refresh}", consumes = "application/json", produces = "application/json")\n public ResponseEntity<?> refreshAndGetAuthenticationToken(HttpServletRequest request) {\n String authToken = request.getHeader(tokenHeader);\n final String token = authToken.substring(7);\n String username = jwtTokenUtil.getUsernameFromToken(token);\n JwtUser user = (JwtUser) userSecurityService.loadUserByUsername(username);\n\n if (jwtTokenUtil.canTokenBeRefreshed(token, user.getLastPasswordResetDate())) {\n String refreshedToken = jwtTokenUtil.refreshToken(token);\n return ResponseEntity.ok(new JwtAuthenticationResponse(refreshedToken));\n } else {\n return ResponseEntity.badRequest().body(null);\n }\n }\n\n @ExceptionHandler({AuthenticationException.class})\n public ResponseEntity<String> handleAuthenticationException(AuthenticationException e) {\n return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(e.getMessage());\n }\n\n /**\n * Authenticates the user. If something is wrong, an {@link AuthenticationException} will be thrown\n */\n private void authenticate(String username, String password) {\n\n Objects.requireNonNull(username);\n Objects.requireNonNull(password);\n\n\n try {\n authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));\n } catch (DisabledException e) {\n e.printStackTrace();\n throw new AuthenticationException("User is disabled!", e);\n } catch (BadCredentialsException e) {\n throw new AuthenticationException("Bad credentials!", e);\n } catch (Exception e) {\n e.printStackTrace();\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n和
\n@RestController\n@RequestMapping("/api/v1/styles")\n@Slf4j\npublic class StyleResourceController {\n\n \n @PutMapping(path = "/{styleCode}")\n @ResponseStatus(HttpStatus.OK)\n public void setAlerts(@RequestHeader(value = "Authorization") String authHeader, @PathVariable String styleCode)\n\n throws DataAccessException {\n\n System.out.println("add style {} ");\n\n final User user = authUserOnPath(authHeader);\n\n System.out.println("user {} " + user);\n\n protected User authUserOnPath(String authHeader) {\n\n String authToken = authHeader.substring(7);\n\n String username = jwtTokenUtil.getUsernameFromToken(authToken);\n User user = userService.findByUserName(username);\n\n if (user == null)\n throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "UserNotFound");\n\n return user;\n\n }\n\n\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n和
\n@Component\npublic class JwtTokenUtil implements Serializable {\n\n //static final String CLAIM_KEY_USERNAME = "sub";\n //static final String CLAIM_KEY_CREATED = "iat";\n private static final long serialVersionUID = -3301605591108950415L;\n // @SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "It's okay here")\n private Clock clock = DefaultClock.INSTANCE;\n\n @Value("${jwt.secret}")\n private String secret;\n\n @Value("${jwt.expiration}")\n private Long expiration;\n\n public String getUsernameFromToken(String token) {\n return getClaimFromToken(token, Claims::getSubject);\n }\n\n public Date getIssuedAtDateFromToken(String token) {\n return getClaimFromToken(token, Claims::getIssuedAt);\n }\n\n public Date getExpirationDateFromToken(String token) {\n return getClaimFromToken(token, Claims::getExpiration);\n }\n\n public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {\n final Claims claims = getAllClaimsFromToken(token);\n return claimsResolver.apply(claims);\n }\n\n private Claims getAllClaimsFromToken(String token) {\n return Jwts.parser()\n .setSigningKey(secret)\n .parseClaimsJws(token)\n .getBody();\n }\n\n private Boolean isTokenExpired(String token) {\n final Date expiration = getExpirationDateFromToken(token);\n return expiration.before(clock.now());\n }\n\n private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {\n return (lastPasswordReset != null && created.before(lastPasswordReset));\n }\n\n private Boolean ignoreTokenExpiration(String token) {\n // here you specify tokens, for that the expiration is ignored\n return false;\n }\n\n public String generateToken(UserDetails userDetails) {\n Map<String, Object> claims = new HashMap<>();\n return doGenerateToken(claims, userDetails.getUsername());\n }\n\n private String doGenerateToken(Map<String, Object> claims, String subject) {\n final Date createdDate = clock.now();\n final Date expirationDate = calculateExpirationDate(createdDate);\n\n return Jwts.builder()\n .setClaims(claims)\n .setSubject(subject)\n .setIssuedAt(createdDate)\n .setExpiration(expirationDate)\n .signWith(SignatureAlgorithm.HS512, secret)\n .compact();\n }\n\n public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) {\n final Date created = getIssuedAtDateFromToken(token);\n return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset)\n && (!isTokenExpired(token) || ignoreTokenExpiration(token));\n }\n\n public String refreshToken(String token) {\n final Date createdDate = clock.now();\n final Date expirationDate = calculateExpirationDate(createdDate);\n\n final Claims claims = getAllClaimsFromToken(token);\n claims.setIssuedAt(createdDate);\n claims.setExpiration(expirationDate);\n\n return Jwts.builder()\n .setClaims(claims)\n .signWith(SignatureAlgorithm.HS512, secret)\n .compact();\n }\n\n public Boolean validateToken(String token, UserDetails userDetails) {\n JwtUser user = (JwtUser) userDetails;\n final String username = getUsernameFromToken(token);\n final Date created = getIssuedAtDateFromToken(token);\n return (\n username.equals(user.getUsername())\n && !isTokenExpired(token)\n && !isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate())\n );\n }\n\n private Date calculateExpirationDate(Date createdDate) {\n return new Date(createdDate.getTime() + expiration * 1000);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n但是当我从令牌获取用户时为空:
\n17:19:22.017 [http-nio-1133-exec-8] INFO c.d.c.JwtAuthorizationTokenFilter - tokenHeader 'Authorization'\n17:19:22.017 [http-nio-1133-exec-8] INFO c.d.c.JwtAuthorizationTokenFilter - requestHeader 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2OTE3NjcxMzYsImlhdCI6MTYzMTI4NzEzNn0.C9s3dbjWNVyGdV5k0LXsNhMGMvPzboTx1J6sGEbfXVOP1CzCLeZFgVPQ4o8jgugvgURF3BcnsWAk7ygd7RCvdg'\n17:19:22.017 [http-nio-1133-exec-8] INFO c.d.c.JwtAuthorizationTokenFilter - authToken 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2OTE3NjcxMzYsImlhdCI6MTYzMTI4NzEzNn0.C9s3dbjWNVyGdV5k0LXsNhMGMvPzboTx1J6sGEbfXVOP1CzCLeZFgVPQ4o8jgugvgURF3BcnsWAk7ygd7RCvdg'\n17:19:22.018 [http-nio-1133-exec-8] INFO c.d.c.JwtAuthorizationTokenFilter - checking authentication for user 'null'\nRun Code Online (Sandbox Code Playgroud)\n
小智 1
enter code here@Component 公共类 JwtUtil {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
Date now =new Date();
Date ExpirationDate =new Date(now.getTime()+ expiration*1000);
public User getUser(final String token) {
Claims body = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
User u = new User();
u.setUsername(body.getSubject());
u.setUserId(Integer.parseInt((String) body.get("userId")));
Set<Role> roles =new HashSet<>();
roles.add(Role.CONSUMER);
roles.add(Role.SELLER);
u.setRoles(roles);
return u;
}
public String generateToken(String username) {
User u = new User();
Claims claims = Jwts.claims().setSubject(username);
claims.put("userId", u.getUserId());
Set<Role> roles =new HashSet<>();
roles.add(Role.CONSUMER);
roles.add(Role.SELLER);
claims.put("role",roles );
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration( ExpirationDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public boolean validateToken(final String token) {
return getClaims(secret,token)
.getExpiration()
.after(new Date (System.currentTimeMillis()));
}
public Claims getClaims(String secret ,String token) {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}
Run Code Online (Sandbox Code Playgroud)
}
| 归档时间: |
|
| 查看次数: |
1368 次 |
| 最近记录: |