{"id":275560,"date":"2016-03-05T23:29:19","date_gmt":"2016-03-05T20:29:19","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=275560"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=275560","title":{"rendered":"\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Spring Security \u0438 JWT-\u0442\u043e\u043a\u0435\u043d\u043e\u0432"},"content":{"rendered":"<p>       \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! <a href=\"https:\/\/habrahabr.ru\/post\/278353\/\">\u0425\u0430\u0431\u0440 \u0436\u0438\u0432!<\/a> \u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0441\u0442 \u0432\u0440\u044f\u0434 \u043b\u0438 \u0441\u043e\u0431\u0435\u0440\u0451\u0442 \u043a\u0443\u0447\u0443 \u043b\u0430\u0439\u043a\u043e\u0432 \u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u043e \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0437\u0434\u043e\u0440\u043e\u0432\u044c\u044e \u0445\u0430\u0431\u0440\u0430. <\/p>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 Spring \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u2014 <a href=\"https:\/\/jwt.io\">JSON Web Token (JWT)<\/a>. \u042d\u0442\u043e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0443\u0436\u0435 \u043e\u0431\u043a\u0430\u0442\u0430\u043d \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. <\/p>\n<p>  <a name=\"habracut\"><\/a><\/p>\n<p>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u043d\u0435 \u0437\u0430\u0431\u043e\u0442\u0438\u0442\u044c\u0441\u044f \u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 (HTTP-\u0441\u0435\u0441\u0441\u0438\u0438), \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0411\u0414 \u2014 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043a\u0435\u043d\u0435. \u041d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e \u0442\u043e\u043a\u0435\u043d\u0435 JWT: \u0441\u0435\u0440\u0432\u0435\u0440 \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 JSON (\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0438 \u0442\u0435\u043b\u043e) \u0441 \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u043a\u043b\u044e\u0447\u043e\u043c \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0445\u044d\u0448, \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u044f\u044f \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b \u043a \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0435. \u041f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c base64Url, \u043f\u043e\u044d\u0442\u043e\u043c\u0443, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432 \u0442\u043e\u043a\u0435\u043d\u0435 \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c JWT \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043e. \u0428\u0438\u0444\u0440\u0443\u0439\u0442\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0441\u0430\u043c\u0438, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435, \u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0442\u043e\u043a\u0435\u043d\u0430 \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e.<\/p>\n<p>  \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0437\u043d\u0430\u043a\u043e\u043c \u0441 \u043e\u0441\u043d\u043e\u0432\u0430\u043c\u0438 Spring Secutity. \u041f\u0440\u043e \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/habrahabr.ru\/post\/203318\/\">\u0437\u0434\u0435\u0441\u044c<\/a><\/p>\n<h5>1). \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u0430<\/h5>\n<p>  \u0414\u043b\u044f \u0441\u0432\u043e\u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u044f \u0432\u0437\u044f\u043b \u043e\u0434\u043d\u0443 \u0438\u0437 <a href=\"https:\/\/github.com\/jwtk\/jjwt\">\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439<\/a> \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 JWT. \u0422\u043e\u043a\u0435\u043d \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"java\">package com.example.security;  import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.impl.crypto.MacProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Service;  import java.util.*;  @Service public class GetTokenServiceImpl implements GetTokenService {      @Autowired     private UserDetailsService userDetailsService;      @Override     public TokenObject getToken(String username, String password) throws Exception {         if (username == null || password == null)             return null;         User user = (User) userDetailsService.loadUserByUsername(username);         Map&lt;String, Object&gt; tokenData = new HashMap&lt;&gt;();         if (password.equals(user.getPassword())) {             tokenData.put(&quot;clientType&quot;, &quot;user&quot;);             tokenData.put(&quot;userID&quot;, user.getUserId().toString());             tokenData.put(&quot;username&quot;, authorizedUser.getUsername());             tokenData.put(&quot;token_create_date&quot;, new Date().getTime());             Calendar calendar = Calendar.getInstance();             calendar.add(Calendar.YEAR, 100);             tokenData.put(&quot;token_expiration_date&quot;, calendar.getTime());             JwtBuilder jwtBuilder = Jwts.builder();             jwtBuilder.setExpiration(calendar.getTime());             jwtBuilder.setClaims(tokenData);             String key = &quot;abc123&quot;;             String token = jwtBuilder.signWith(SignatureAlgorithm.HS512, key).compact();             return token;         } else {             throw new Exception(&quot;Authentication error&quot;);         }     }  }  <\/code><\/pre>\n<p>  \u0412 \u0438\u0442\u043e\u0433\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432\u0438\u0434\u0430 <i>&lt;\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a&gt;.&lt;\u0422\u0435\u043b\u043e&gt;.&lt;\u0421\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430&gt;<\/i>, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0443<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043a Spring Security. \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 <i>\u0444\u0438\u043b\u044c\u0442\u0440 <\/i>\u0438 <i>\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/i>.<\/p>\n<h5>2). \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430<\/h5>\n<p>  \u0424\u0438\u043b\u044c\u0442\u0440 \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <i>javax.servlet.Filter<\/i>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 URL \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0415\u0441\u043b\u0438 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432, \u0442\u043e \u043e\u043d\u0438 \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u2014 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u0451\u043c\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 \u044d\u0442\u0443 \u0446\u0435\u043f\u043e\u0447\u043a\u0443. \u041a\u0430\u0436\u0434\u044b\u0439 \u0444\u0438\u043b\u044c\u0442\u0440 \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0435 \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441, \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u043c \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0435 \u0438\u043b\u0438 \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u0441\u0440\u0430\u0437\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0432 \u043e\u0442\u0432\u0435\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0443.<\/p>\n<p>  \u0417\u0430\u0434\u0430\u0447\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u2014 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0443 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. <\/p>\n<pre><code class=\"java\">package com.example.security;  import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;  public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {      public TokenAuthenticationFilter() {         super(&quot;\/rest\/**&quot;);         setAuthenticationSuccessHandler((request, response, authentication) -&gt;         {             SecurityContextHolder.getContext().setAuthentication(authentication);               request.getRequestDispatcher(request.getServletPath() + request.getPathInfo()).forward(request, response);         });         setAuthenticationFailureHandler((request, response, authenticationException) -&gt; {             response.getOutputStream().print(authenticationException.getMessage());         });     }      @Override     public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)                                       throws AuthenticationException, IOException, ServletException {         String token = request.getHeader(&quot;token&quot;);         if (token == null)             token = request.getParameter(&quot;token&quot;);         if (token == null) {             TokenAuthentication authentication = new TokenAuthentication(null, null);             authentication.setAuthenticated(false);             return authentication;         }         TokenAuthentication tokenAuthentication = new TokenAuthentication(token);         Authentication authentication = getAuthenticationManager().authenticate(tokenAuthentication);         return authentication;     }      @Override     public void doFilter(ServletRequest req, ServletResponse res,                          FilterChain chain) throws IOException, ServletException {         super.doFilter(req, res, chain);     } } <\/code><\/pre>\n<p>  \u041c\u044b \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u0442 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 <i>org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter<\/i>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. \u041f\u0440\u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0438 URL \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u043c <i>&quot;\/rest\/**&quot;<\/i> \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u043c \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <i>attemptAuthentication()<\/i>. <br \/>  \u0422\u0430\u043a\u0436\u0435 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 \u0434\u0432\u0430 \u0445\u044d\u043d\u0434\u043b\u044d\u0440\u0430 \u2014 <i>AuthenticationSuccessHandler<\/i> \u0438 <i>AuthenticationFailureHandler<\/i>. \u0415\u0441\u043b\u0438 <i>attemptAuthentication<\/i> \u0432\u0435\u0440\u043d\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 <i>Authentication<\/i>, \u0442\u043e \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 \u0445\u044d\u043d\u0434\u043b\u0435\u0440, \u0432\u0442\u043e\u0440\u043e\u0439 \u0445\u044d\u043d\u0434\u043b\u044d\u0440 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u0438 \u0432\u044b\u0431\u0440\u043e\u0441\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u043c <i>attemptAuthentication<\/i> \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f <i>AuthenticationException<\/i>.<br \/>  \u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u043f\u0440\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c <i>SecurityContextHolder.getContext().setAuthentication(authentication)<\/i>. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <i>ThreadLocal<\/i>, \u0442.\u0435. \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d, \u043f\u043e\u043a\u0430 \u0436\u0438\u0432 \u043f\u043e\u0442\u043e\u043a \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c. \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043c\u044b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0443 \u0441 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u044b\u043c URL.<\/p>\n<h5>3). \u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<\/h5>\n<p>  \u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <i>org.springframework.security.authentication.AuthenticationManager<\/i> \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c <i>authenticate()<\/i>. \u0414\u0430\u043d\u043d\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <i>org.springframework.security.core.Authentication<\/i> (\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f). <br \/>  \u0417\u0430\u0434\u0430\u0447\u0430 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u2014 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0431\u044a\u0435\u043a\u0442 <i>Authentication<\/i> \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0435\u0433\u043e. \u041f\u0440\u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (<i>principal<\/i>), \u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0430 (<i>authorities<\/i>), \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <i>setAuthenticated(true)<\/i>. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0443\u0434\u0430\u0447\u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 <i>AuthenticationException<\/i>. <\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0434\u0451\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <i>org.springframework.security.core.Authentication<\/i>:<\/p>\n<pre><code class=\"java\">package com.example.security;  import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import javax.servlet.http.HttpServletRequest; import java.util.Collection; import java.util.List; import java.util.Map;  public class TokenAuthentication implements Authentication {     private String token;     private Collection&lt;? extends GrantedAuthority&gt; authorities;     private boolean isAuthenticated;     private UserDetails principal;      public TokenAuthentication(String token) {         this.token = token;         this.details = request;     }      public TokenAuthentication(String token, Collection&lt;SimpleGrantedAutority&gt; authorities, boolean isAuthenticated,                                                  UserDetails principal) {         this.token = token;         this.authorities = authorities;         this.isAuthenticated = isAuthenticated;         this.principal = principal;     }      @Override     public Collection&lt;? extends GrantedAuthority&gt; getAuthorities() {         return authorities;     }      @Override     public Object getCredentials() {         return null;     }      @Override     public Object getDetails() {         return details;     }      @Override     public String getName() {         if (principal != null)             return ((UserDetails) principal).getUsername();         else             return null;     }      @Override     public Object getPrincipal() {         return principal;     }      @Override     public boolean isAuthenticated() {         return isAuthenticated;     }      @Override     public void setAuthenticated(boolean b) throws IllegalArgumentException {         isAuthenticated = b;     }      public String getToken() {         return token;     }  }  <\/code><\/pre>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0434\u0451\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438:<\/p>\n<pre><code class=\"java\">package com.example.security;  import io.jsonwebtoken.Jwts; import io.jsonwebtoken.impl.DefaultClaims; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.authentication.AuthenticationServiceException import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Service; import org.springframework.security.core.GrantedAuthority; import javax.servlet.http.HttpServletRequest; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors;  @Service public class TokenAuthenticationManager implements AuthenticationManager {      @Autowired     private UserDetailsService userDetailsService;      @Override     public Authentication authenticate(Authentication authentication) throws AuthenticationException {         try {             if (authentication instanceof TokenAuthentication) {                 TokenAuthentication readyTokenAuthentication = processAuthentication((TokenAuthentication) authentication);                 return readyTokenAuthentication;             } else {                 authentication.setAuthenticated(false);                 return authentication;             }         } catch (Exception ex) {             if(ex instanceof AuthenticationServiceException)                throw ex;         }     }      private TokenAuthentication processAuthentication(TokenAuthentication authentication) throws AuthenticationException {         String token = authentication.getToken();         String key = &quot;key123&quot;;         DefaultClaims claims;         try {             claims = (DefaultClaims) Jwts.parser().setSigningKey(key).parse(token).getBody();         } catch (Exception ex) {             throw new AuthenticationServiceException(&quot;Token corrupted&quot;);         }         if (claims.get(&quot;TOKEN_EXPIRATION_DATE&quot;, Long.class) == null)             throw new AuthenticationServiceException(&quot;Invalid token&quot;);         Date expiredDate = new Date(claims.get(&quot;TOKEN_EXPIRATION_DATE&quot;, Long.class));         if (expiredDate.after(new Date()))                return buildFullTokenAuthentication(authentication, claims);          else              throw new AuthenticationServiceException(&quot;Token expired date error&quot;);           }      private TokenAuthentication buildFullTokenAuthentication(TokenAuthentication authentication, DefaultClaims claims) {         User user = (User) userDetailsService.loadUserByUsername(claims.get(&quot;USERNAME&quot;, String.class));         if (user.isEnabled()) {             Collection&lt;GrantedAutority&gt; authorities = user.getAuthorities();             TokenAuthentication fullTokenAuthentication =                                               new TokenAuthentication(authentication.getToken(), authorities, true, user);             return fullTokenAuthentication;         } else {             throw new AuthenticationServiceException(&quot;User disabled&quot;);;         }     } }  <\/code><\/pre>\n<h5>4). \u041a\u0430\u043a \u0432\u0441\u0451 \u044d\u0442\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u0435<\/h5>\n<p>  \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440. \u0421\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e 2-\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438<\/p>\n<p>  \u041f\u0435\u0440\u0432\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u2014 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440 \u0432 \u0444\u0430\u0439\u043b\u0435 <i>web.xml<\/i> \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<pre><code class=\"xml\">    &lt;filter&gt;         &lt;filter-name&gt;springSecurityTokenFilter&lt;\/filter-name&gt;         &lt;filter-class&gt;com.example.security.TokenAuthenticationFilter&lt;\/filter-class&gt;     &lt;\/filter&gt;     &lt;filter-mapping&gt;         &lt;filter-name&gt;springSecurityTokenFilter&lt;\/filter-name&gt;         &lt;url-pattern&gt;\/rest\/**&lt;\/url-pattern&gt;     &lt;\/filter-mapping&gt; <\/code><\/pre>\n<p>  \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u0435 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u043d\u0443\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u0434\u0430\u0442\u044c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f Spring. \u0415\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043c\u0435\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440 \u0438\u043b\u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0431\u0438\u043d\u043e\u0432 Spring, \u043d\u0443\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u0442\u043e\u0440\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c.<\/p>\n<p>  \u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u2014 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Spring Security.<\/p>\n<p>  \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e\u043a\u0430\u0436\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Java Config<\/p>\n<pre><code class=\"java\">package com.example.security;  import com.example.security.RestTokenAuthenticationFilter; import com.example.security.TokenAuthenticationManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; 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.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;   @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter {      @Autowired     @Qualifier(&quot;userDetailsService&quot;)     UserDetailsService userDetailsService;      @Autowired     TokenAuthenticationManager tokenAuthenticationManager;      @Override     protected void configure(HttpSecurity http) throws Exception {         http                 .headers().frameOptions().sameOrigin()                 .and()                 .addFilterAfter(restTokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)                 .authorizeRequests()                 .antMatchers(&quot;\/rest\/*&quot;).authenticated()     }      @Bean(name = &quot;restTokenAuthenticationFilter&quot;)     public RestTokenAuthenticationFilter restTokenAuthenticationFilter() {         RestTokenAuthenticationFilter restTokenAuthenticationFilter = new RestTokenAuthenticationFilter();         tokenAuthenticationManager.setUserDetailsService(userDetailsService);         restTokenAuthenticationFilter.setAuthenticationManager(tokenAuthenticationManager);         return restTokenAuthenticationFilter;     } }  <\/code><\/pre>\n<p>  \u0412 \u0441\u0442\u0440\u043e\u043a\u0435<br \/>  <i>.addFilterAfter(restTokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)<\/i><br \/>   \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043d\u0430\u0448 \u0444\u0438\u043b\u044c\u0442\u0440 \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u043f\u043e\u0441\u043b\u0435 <a href=\"http:\/\/docs.spring.io\/spring-security\/site\/docs\/4.0.3.RELEASE\/apidocs\/org\/springframework\/security\/config\/annotation\/web\/HttpSecurityBuilder.html#addFilter-javax.servlet.Filter-\">\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e<\/a> \u0444\u0438\u043b\u044c\u0442\u0440\u0430 <i>UsernamePasswordAuthenticationFilter<\/i>.<\/p>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432 Spring Security \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c JSON Web Token \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430. <\/p>\n<p>  \u0416\u0435\u043b\u0430\u044e \u0432\u0441\u0435\u043c \u0443\u0441\u043f\u0435\u0445\u043e\u0432!<\/p>\n<p>  \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435!               <\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habrahabr.ru\/post\/278411\/\"> https:\/\/habrahabr.ru\/post\/278411\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! <a href=\"https:\/\/habrahabr.ru\/post\/278353\/\">\u0425\u0430\u0431\u0440 \u0436\u0438\u0432!<\/a> \u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0441\u0442 \u0432\u0440\u044f\u0434 \u043b\u0438 \u0441\u043e\u0431\u0435\u0440\u0451\u0442 \u043a\u0443\u0447\u0443 \u043b\u0430\u0439\u043a\u043e\u0432 \u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u043e \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0437\u0434\u043e\u0440\u043e\u0432\u044c\u044e \u0445\u0430\u0431\u0440\u0430. <\/p>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 Spring \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u2014 <a href=\"https:\/\/jwt.io\">JSON Web Token (JWT)<\/a>. \u042d\u0442\u043e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0443\u0436\u0435 \u043e\u0431\u043a\u0430\u0442\u0430\u043d \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-275560","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/275560","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=275560"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/275560\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=275560"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=275560"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=275560"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}