-

   rss_rss_hh_new

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 51

:


[ ] Stateless Spring Security JWT

, 10 2017 . 20:07 +
AnarSultanov 20:07

Stateless Spring Security JWT

statefull , stateless JWT. JSON Web Token, , , .

, , . , , . , , .

JJWT, . , // . , (AngularJS) RESTful Web- (Spring) back-end.

, JWT , . , , , . .

access refresh , access . refresh , ? UX, . , . 10 access 60 , , refresh .

, . e cookies. , , .

, back-end front-end header /. , front-end, , , , .., cookies // back-end.

, , . , , . - , , , .

, . @RestController, TokenAuthenticationService cookies (access_token refresh_token).

    @RequestMapping(value = "/login", produces = "application/json", method = RequestMethod.GET)
    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    public void login(HttpServletResponse response) {
        SessionUser user = (SessionUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        tokenAuthenticationService.addAuthentication(response, user);
        SecurityContextHolder.getContext().setAuthentication(null);
    }

SessionUser UserDetails*

TokenAuthenticationService:

    public void addAuthentication(HttpServletResponse response, SessionUser user) {
        Cookie access = new Cookie("access_token", tokenHandler.createAccessToken(user));
        access.setPath("/");
        access.setHttpOnly(true);
        response.addCookie(access);

        Cookie refresh = new Cookie("refresh_token", tokenHandler.createRefreshToken(user));
        refresh.setPath("/");
        refresh.setHttpOnly(true);
        response.addCookie(refresh);
    }

TokenHandler c JWT Jwts.builder() Jwts.parser() , , :

public String createRefreshToken(SessionUser user) {
    // ,     username
}
public SessionUser parseRefreshToken(String token) {
    // username         UserDetailsService
}
public String createAccessToken(SessionUser user) {
    // ,        SessionUser
}
public SessionUser parseAccessToken(String token) {
    //       SessionUser
}

UserDetailsService*

, . , WebSecurityConfigurerAdapter, bean-a:

    @Bean
    public TokenAuthenticationService tokenAuthenticationService() {
        return new TokenAuthenticationService();
    }

    @Bean
    public TokenHandler tokenHandler() {
        return new TokenHandler();
    }

/ :

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        //   
        .antMatchers("/", "/login").permitAll()
        //     
        .anyRequest().authenticated()
        .and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService()), UsernamePasswordAuthenticationFilter.class)             
}

, :

public class StatelessAuthenticationFilter extends GenericFilterBean {

    private final TokenAuthenticationService tokenAuthenticationService;

    public StatelessAuthenticationFilter(TokenAuthenticationService tokenAuthenticationService) {
        this.tokenAuthenticationService= tokenAuthenticationService;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        Authentication authentication = tokenAuthenticationService.getAuthentication(httpRequest, httpResponse);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        filterChain.doFilter(request, response);
        SecurityContextHolder.getContext().setAuthentication(null);
    }
}

:
access ?
? .
?
?
? .
? access refresh .
?
? , access .
? .
TokenAuthenticationService:

public Authentication getAuthentication(HttpServletRequest request, HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();

        String accessToken = null;
        String refreshToken = null;
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (("access_token").equals(cookie.getName())) {
                    accessToken = cookie.getValue();
                }
                if (("refresh_token").equals(cookie.getName())) {
                    refreshToken = cookie.getValue();
                }
            }
        }

        if (accessToken != null && !accessToken.isEmpty()) {
            try {
                SessionUser user = tokenHandler.parseAccessToken(accessToken);
                return new UserAuthentication(user);
            } catch (ExpiredJwtException ex) {
                if (refreshToken != null && !refreshToken.isEmpty()) {
                    try {
                        SessionUser user = tokenHandler.parseRefreshToken(refreshToken);
                        Cookie access = new Cookie("access_token", tokenHandler.createAccessToken(user));
                        access.setPath("/");
                        access.setHttpOnly(true);
                        response.addCookie(access);
                        return new UserAuthentication(user);
                    } catch (JwtException e) {
                        return null;
                    }
                }
                return null;
            } catch (JwtException ex) {
                return null;
            }
        }
        return null;
    } 

UserAuthentication Authentication*

, Spring Security JWT.

, - refresh . , , , , .

, , , cookies , . , , , , .

, , refresh access , refresh . , . . , , ? 60 . .

(refresh_token) refresh :
1. id (BIGINT)
2. username (VARCHAR)
3. token (VARCHAR)
4. expires (TIMESTAMP)
RefreshTokenDao JdbcTemplate :

    public void insert(String username, String token, long expires) {
        String sql = "INSERT INTO refresh_token "
                + "(username, token, expires) VALUES (?, ?, ?)";
        jdbcTemplate.update(sql, username, token, new Timestamp(expires));
    }

    public int updateIfNotExpired(String username, String token, long expiration) {
        String sql = "UPDATE refresh_token "
                + "SET expires = ? "
                + "WHERE username = ? "
                + "AND token = ? "
                + "AND expires > ?";
        Timestamp now = new Timestamp(System.currentTimeMillis());
        Timestamp newExpirationTime = new Timestamp(now.getTime() + expiration);
        return jdbcTemplate.update(sql, newExpirationTime, username, token, now);
    }

. . , , 0 1.

TokenHandler. (createRefreshToken()) insert(). (parseRefreshToken()), updateIfNotExpired() 0, , ; , 0, , (new JwtException(Token is expired or missing)).

refresh . ( ) - , .

!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/337600/

:  

: [1] []
 

:
: 

: ( )

:

  URL