Java Проблема с перенаправлением нескольких страниц Spring Boot при входе в систему - PullRequest
1 голос
/ 16 июня 2020

post-second loginpost-first login Здравствуйте, я разрабатываю Java Spring Boot Web App, и у меня возникла проблема, когда при правильном входе пользователя в приложение app по какой-то причине возвращает пользователя на страницу входа, а не на главную. Однако, как только пользователь правильно входит в систему в первый раз (даже если он был возвращен на страницу входа), он может выйти, и если они попытаются снова войти в систему, они будут правильно переведены в "/ home "страница. Однако я не уверен, почему это происходит неправильно с первой попытки. Различные фрагменты кода, которые не работают должным образом, следующие: 1. Мой метод configure (), который, как вы видите, должен перенаправлять пользователя в «/ home» при успешном входе в систему. 2. функции @RequestMapping в моем AuthController. 3. мои плитки. xml файл

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //@formatter:off
        http
            .authorizeRequests()
                .antMatchers( "/login", "/js/**", "/css/**", "/img/**").permitAll()
                .antMatchers("/register").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/login")
                .defaultSuccessUrl("/home").permitAll()
                .and()
                .logout().permitAll();
        }
    @RequestMapping("/login")
    String admin() {
        return "app.login";
    }


    @RequestMapping("/")
    String login() {
        return "app.login";
    }
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">


<tiles-definitions>
  <definition name="app.default" template="/WEB-INF/layouts/default.jsp">
    <put-attribute name="title" value="bcore Hardware" />
  </definition>

  <definition name="app.home" extends="app.default">
    <put-attribute name="content" value="/WEB-INF/tiles/home.jsp" />
  </definition>

  <!-- WILL NEED ITS OWN TEMPLATE -->
  <definition name="app.login" extends="app.default">
    <put-attribute name="content" value="/WEB-INF/tiles/login.jsp" />
  </definition>

  <!-- WILL NEED ITS OWN TEMPLATE -->
  <definition name="app.newRecord" extends="app.default">
    <put-attribute name="content" value="/WEB-INF/tiles/newRecord.jsp" />
  </definition>


  <definition name="app.viewRecord" extends="app.default">
    <put-attribute name="content" value="/WEB-INF/tiles/viewRecord.jsp" />
  </definition>


  <definition name="app.editRecord" extends="app.default">
    <put-attribute name="content" value="/WEB-INF/tiles/editRecord.jsp" />
  </definition>

  <definition name="app.account" extends="app.default">
    <put-attribute name="content" value="/WEB-INF/tiles/account.jsp" />
  </definition>

  <definition name="app.editAccount" extends="app.default">
    <put-attribute name="content" value="/WEB-INF/tiles/editAccount.jsp" />
  </definition>


  <definition name="app.register" extends="app.default">
    <put-attribute name="content" value="/WEB-INF/tiles/register.jsp" />
  </definition>

</tiles-definitions>

Я хочу, чтобы он был структурирован так, чтобы пользователь, не вошедший в систему, имел доступ только к странице входа. Затем при успешном входе в систему они перенаправляются на домашнюю страницу с различными привилегиями для просмотра в зависимости от ролей, которая работает правильно. Любая помощь будет оценена.

Ответы [ 4 ]

1 голос
/ 23 июня 2020

Spring не будет перенаправлять вас в зависимости от вашей роли, вам нужно управлять перенаправлением вручную, он даст вам только доступ к нему.

Взгляните:

protected void configure(HttpSecurity http) throws Exception {
 
 http.authorizeRequests()
  .antMatchers("/admin").hasRole("ADMIN")
  .antMatchers("/user").hasRole("USER")
  .antMatchers("/").permitAll()
  .and().formLogin().defaultSuccessUrl("/redirect") //endpoint to manage redirects
  .and().logout()
  .permitAll();
}

Управление переадресацией /redirect

@GetMapping("/redirect")
public void getRedirect(HttpServletResponse resp, HttpServletRequest request) throws IOException {
 
 System.out.println("Auth: " + SecurityContextHolder.getContext().getAuthentication());

 Authentication auth = SecurityContextHolder.getContext().getAuthentication();
 System.out.println("Principal: " + auth.getPrincipal());
 System.out.println("Authorities: " + auth.getAuthorities()); //get it from here OR
 System.out.println(request.isUserInRole("ROLE_USER")); // get it from Here as WELL (ONLY IF YOU HAVE A REQUEST)

 if (request.isUserInRole("ROLE_USER")) {
  resp.sendRedirect("/user");
 } else if (request.isUserInRole("ROLE_ADMIN")) {
  resp.sendRedirect("/admin");
 }
}

Имейте в виду, что существуют различия в области действия

  • hasRole() приводит к Authorities: [ROLE_ADMIN]
  • hasAuthority() приводит к Authorities: [ADMIN]

enter image description here

введите описание изображения здесь

Надеюсь, это поможет!

1 голос
/ 19 июня 2020

Думаю, я нашел ответ, хотя я не уверен на 100%, что понимаю документацию. Все, что я сделал, это изменил "defaultSuccessUrl (" / home ")" на "defaultSuccessUrl (" / home ", true)", и это дало мне нужный результат. Документацию по этому поводу можно найти здесь: https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/configurers/AbstractAuthenticationFilterConfigurer.html#defaultSuccessUrl - java .lang.String-boolean-

И еще один похожий пост можно найти здесь: Spring security не работает редирект после успешного входа

1 голос
/ 20 июня 2020

Согласно документации defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse)

Указывает, где пользователи будут go после успешной аутентификации, если они не посетили защищенную страницу до аутентификации, или всегда верно.

Теперь давайте исследуем некоторый код,

AbstractAuthenticationFilterConfigurer состоит из методов defaultSuccessUrl(String defaultSuccessUrl) и defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse)

1.defaultSuccessUrl(String defaultSuccessUrl)

Это ярлык для вызова defaultSuccessUrl (String).

public final T defaultSuccessUrl(String defaultSuccessUrl) {
    return defaultSuccessUrl(defaultSuccessUrl, false);
}

2. defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse)

public final T defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse) {
        SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
        handler.setDefaultTargetUrl(defaultSuccessUrl);
        handler.setAlwaysUseDefaultTargetUrl(alwaysUse);
        this.defaultSuccessHandler = handler;
        return successHandler(handler);
    }

Как мы можем видеть, метод 1 в конечном итоге вызывает метод 2 с alwaysUse as false , используя методы 2 с alwaysUse as true , мы явно устанавливаем параметр, который в дальнейшем используется в SavedRequestAwareAuthenticationSuccessHandler следующим образом

if (isAlwaysUseDefaultTargetUrl()
        || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
    requestCache.removeRequest(request, response);
    super.onAuthenticationSuccess(request, response, authentication);

    return;
}  
0 голосов
/ 19 июня 2020

Я точно не знаю, в чем проблема. Но вы можете попробовать избежать стандартных строк login и successUrl и заменить их на .antMatchers(HttpMethod.POST, "/login").permitAll() и создать контроллер Post /login.

@PostMapping("login")
    public String login(@RequestBody UserDTO user) { ... }

Note

Я бы изменил аннотацию в ваш метод входа в систему, чтобы указать GET.

@RequestMapping(value = "/login", method = RequestMethod.GET)

или

@GetMapping("login"), что более рекомендуется (будьте осторожны с символом '/', я думаю в этом тот, который вам не нужен)

Надеюсь, поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...