Ошибка 401 рендеринга в Spring boot 2 с Spring Security 5 - PullRequest
0 голосов
/ 02 сентября 2018

Spring boot 1.x в Spring boot 2.x

Когда я использую Spring Boot 1.x в приложении, защищенном с помощью Spring, я использую GenericFilterBean для перехвата повторного получения и проверки его токена в другом сервисе, используя REST с restTemplate для проверки токена на сервере аутентификации. Я получаю следующий ответ когда я использую недопустимый токен, появляется следующее сообщение об ошибке 500:

{
    "timestamp": 1535838247986,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "org.springframework.web.client.HttpClientErrorException",
    "message": "401 Unauthorized",
    "path": "/ users"
}

Ошибка консоли:

org.springframework.web.client.HttpClientErrorException $ Unauthorized: 401 Unauthorized
at org.springframework.web.client.HttpClientErrorException.create (HttpClientErrorException.java:81) ~ [spring-web-5.1.0.RC2.jar: 5.1.0.RC2]
at org.springframework.web.client.DefaultResponseErrorHandler.handleError (DefaultResponseErrorHandler.java:97) ~ [spring-web-5.1.0.RC2.jar: 5.1.0.RC2]
at org.springframework.web.client.DefaultResponseErrorHandler.handleError (DefaultResponseErrorHandler.java:79) ~ [spring-web-5.1.0.RC2.jar: 5.1.0.RC2]
at org.springframework.web.client.ResponseErrorHandler.handleError (ResponseErrorHandler.java:63) ~ [spring-web-5.1.0.RC2.jar: 5.1.0.RC2]
at org.springframework.web.client.RestTemplate.handleResponse (RestTemplate.java:777) ~ [spring-web-5.1.0.RC2.jar: 5.1.0.RC2]
at org.springframework.web.client.RestTemplate.doExecute (RestTemplate.java:735) ~ [spring-web-5.1.0.RC2.jar: 5.1.0.RC2]
at org.springframework.web.client.RestTemplate.execute (RestTemplate.java:669) ~ [spring-web-5.1.0.RC2.jar: 5.1.0.RC2]
at org.springframework.web.client.RestTemplate.exchange (RestTemplate.java:578) ~ [spring-web-5.1.0.RC2.jar: 5.1.0.RC2]

Пока все хорошо.

Но когда я использую мезокод с spring boor 2, api возвращает страницу ошибки 500:

<! doctype html> <html lang = "en"> <head> <title> HTTP Status 500 - Internal Server Error h1 {font-family: Tahoma, Arial, sans-serif; color: white; background-color: # 525D76; font-size: 22px;} h2 {font-family: Tahoma, Arial, sans-serif; : Tahoma, Arial, sans-serif; color: white; background-color: # 525D76; font-size: 14px;} body {font-family: Tahoma, Arial, sans-serif; color: black; background-color: white;} b {font-family: Tahoma, Arial, sans-serif; color: white; background-color: # 525D76;} p {font-family: Tahoma, Arial, sans-serif ; background: color; black; font-size: 12px;} a {color: black;} a.name {color: black;} .line {height: 1px; background-color: # 525D76; border: none; </ h1> </ body> </ body> </ h1>

Ошибка консоли:

org.springframework.web.client.HttpClientErrorException: 401 Unauthorized
at org.springframework.web.client.DefaultResponseErrorHandler.handleError (DefaultResponseErrorHandler.java:91) ~ [spring-web-4.3.7.RELEASE.jar: 4.3.7.RELEASE]
at org.springframework.web.client.RestTemplate.handleResponse (RestTemplate.java:700) ~ [spring-web-4.3.7.RELEASE.jar: 4.3.7.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute (RestTemplate.java:653) ~ [spring-web-4.3.7.RELEASE.jar: 4.3.7.RELEASE]
at org.springframework.web.client.RestTemplate.execute (RestTemplate.java:613) ~ [spring-web-4.3.7.RELEASE.jar: 4.3.7.RELEASE]
at org.springframework.web.client.RestTemplate.exchange (RestTemplate.java:531) ~ [spring-web-4.3.7.RELEASE.jar: 4.3.7.RELEASE]

Код: WebSecurityConfig

    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.HttpMethod;
    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.web.authentication.UsernamePasswordAuthenticationFilter;

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable().authorizeRequests()
                    .antMatchers("/").permitAll()
                    .antMatchers(HttpMethod.POST, "/login").permitAll()
                    .anyRequest().authenticated()
                    .and()
                    // We filter the api/login requests
                    .addFilterBefore(new JWTLoginFilter("/login", authenticationManager()),
                            UsernamePasswordAuthenticationFilter.class)
                    // And filter other requests to check the presence of JWT in header
                    .addFilterBefore(new JWTAuthenticationFilter(),
                            UsernamePasswordAuthenticationFilter.class);
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            // Create a default account
            auth.inMemoryAuthentication()
                    .withUser("admin")
                    .password("password")
                    .roles("ADMIN");
        }
    }

Код: TokenAuthenticationService

    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    import org.springframework.http.HttpEntity;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.MediaType;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.web.client.RestTemplate;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.Date;

    import static java.util.Collections.emptyList;

    class TokenAuthenticationService {
        static final long EXPIRATIONTIME = 864_000_000; // 10 days
        static final String SECRET = "ThisIsASecret";
        static final String TOKEN_PREFIX = "Bearer";
        static final String HEADER_STRING = "Authorization";

        static void addAuthentication(HttpServletResponse res, String username) {
            String JWT = Jwts.builder()
                    .setSubject(username)
                    .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                    .signWith(SignatureAlgorithm.HS512, SECRET)
                    .compact();
            res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);
        }

        static Authentication getAuthentication(HttpServletRequest request) {
            String token = request.getHeader(HEADER_STRING);
            if (token != null) {

                RestTemplate restTemplate = new RestTemplate();
                HttpHeaders header = new HttpHeaders();
                header.setContentType(MediaType.APPLICATION_JSON);
                header.add("Authorization", token);

                HttpEntity<String> entity = new HttpEntity<>("parameters", header);

restTemplate.exchange("http://http://www.mocky.io/v2/5b8b11362c0000eb15281054", HttpMethod.GET, entity, String.class);// this request return 401 and, in this moment a app render error

                String user ="";

                return user != null ?
                        new UsernamePasswordAuthenticationToken(emptyList(), user, null) :
                        null;
            }
            return null;
        }
    }

Этот запрос возвращает 401, и в этот момент приложение выдает ошибку

restTemplate.exchange("http://http://www.mocky.io/v2/5b8b11362c0000eb15281054", HttpMethod.GET, entity, String.class);

Единственное отличие в этом коде - версия с загрузочной пружиной.

В чем причина такого поведения?

Как заставить весеннюю загрузку 2 правильно вернуть ошибку API?

...