成功登录vaadin应用后重定向

问题描述 投票:0回答:1

这是我的:

 login.tsx

import { ViewConfig } from '@vaadin/hilla-file-router/types.js';
import { useSignal } from '@vaadin/hilla-react-signals';
import { LoginI18n, LoginOverlay, LoginOverlayElement } from '@vaadin/react-components/LoginOverlay.js';
import { useAuth } from 'Frontend/util/auth.js';

export const config: ViewConfig = {
  menu: { exclude: true },
};

const loginI18n: LoginI18n = {
  ...new LoginOverlayElement().i18n,
  header: { title: 'RiconTrans Login', description: '' },
};

export default function LoginView() {
  const { login } = useAuth();
  const loginError = useSignal(false);

  return (
    <LoginOverlay
      opened
      error={loginError.value}
      noForgotPassword
      i18n={loginI18n}
      onLogin={async ({ detail: { username, password } }) => {
        const { defaultUrl, error, redirectUrl } = await login(username, password);

        if (error) {
          loginError.value = true;
        } else {
          const url = redirectUrl ?? defaultUrl ?? '/Main';  // Ensure the path starts with '/'
          const path = new URL(url, document.baseURI).pathname;
          document.location.href = path;  
        }
      }}
    />
  );
}

); }

作为登录的视图,这是我的安全包:

AuthenticatedUser

package com.ricontrans.application.security;

import com.ricontrans.application.data.User;
import com.ricontrans.application.data.UserRepository;
import com.ricontrans.application.services.UserService;
import com.vaadin.flow.spring.security.AuthenticationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Component
public class AuthenticatedUser {

    private static final Logger logger = LoggerFactory.getLogger(AuthenticatedUser.class);

    private final UserService userService;
    private final AuthenticationContext authenticationContext;
    public AuthenticatedUser(AuthenticationContext authenticationContext, UserService userService) {
        this.userService = userService;
        this.authenticationContext = authenticationContext;
    }

    @Transactional
    public Optional<Object> get() {
        logger.info("Attempting to get authenticated user.");
        Optional<Object> user = authenticationContext.getAuthenticatedUser(UserDetails.class)
                .map(userDetails -> {
                    logger.info("Authenticated user found: {}", userDetails.getUsername());
                    
                    // Call your custom findByUsername method from UserService
                    Optional<User> foundUser = UserService.findByUsername(userDetails.getUsername());

                    if (foundUser.isPresent()) {
                        return (Object) foundUser.get(); // Cast User to Object
                    } else {
                        return Optional.empty();
                    }
                });


        user.ifPresentOrElse(
                u -> logger.info("User retrieved from repository: {}", u),
                () -> logger.warn("No user found in repository.")
        );

        return user;
    }

    public Optional<UserDetails> getCurrentUserDetails() {
        logger.info("Attempting to get current user details from security context.");
        org.springframework.security.core.Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.getPrincipal() instanceof UserDetails) {
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            logger.info("Current user details found: {}", userDetails.getUsername());
            return Optional.of(userDetails);
        }
        logger.info("No user details found in security context.");
        return Optional.empty();
    }

    public void logout() {
        logger.info("Logging out user.");
        authenticationContext.logout();
    }
}

SecurityConfiguration

package com.ricontrans.application.security;

import com.vaadin.flow.spring.security.VaadinWebSecurity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends VaadinWebSecurity {

    private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);
    private static final String LOGIN_FAILURE_URL = "/login?error";
    private static final String SUCCESS_URL = "/Main";
    private static final String LOGIN_URL = "/login";
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        logger.debug("Configuring HTTP security.");

        http.authorizeHttpRequests(authorize -> {
            logger.debug("Permitting all requests to /images/*.png");
            authorize.requestMatchers(new AntPathRequestMatcher("/images/*.png")).permitAll();
        });

        // Icons from the line-awesome addon
        http.authorizeHttpRequests(authorize -> {
            logger.debug("Permitting all requests to /line-awesome/**/*.svg");
            authorize.requestMatchers(new AntPathRequestMatcher("/line-awesome/**/*.svg")).permitAll();
        });

        // Set custom success and failure handlers
        http.formLogin()
            .loginPage(LOGIN_URL)
            .successForwardUrl(SUCCESS_URL)
            .failureUrl(LOGIN_FAILURE_URL)
            .permitAll();

        super.configure(http);
        logger.debug("Setting login view to /login");
        setLoginView(http, LOGIN_URL);
    }
}


    // Set custom success and failure handlers
    http.formLogin()
        .loginPage(LOGIN_URL)
        .successForwardUrl(SUCCESS_URL)
        .failureUrl(LOGIN_FAILURE_URL)
        .permitAll();

    super.configure(http);
    logger.debug("Setting login view to /login");
    setLoginView(http, LOGIN_URL);
}

UserDetailsServiceImpl

package com.ricontrans.application.security;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ricontrans.application.data.User;
import com.ricontrans.application.data.UserRepository;
import com.ricontrans.application.services.UserService;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.ricontrans.application.data.Role;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    private static final Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    @Autowired
    public UserDetailsServiceImpl(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    @Transactional
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
          logger.info("Attempting to load user by username: {}", username);
          try {
              User user = UserService.findByUsername(username)
                      .orElseThrow(() -> new UsernameNotFoundException("No user present with username: " + username));

              logger.info("User found: {}", username);
              Set<Role> roles = UserService.findRolesByUserId(user.getId());
              List<GrantedAuthority> authorities = roles.stream()
                      .map(role -> new SimpleGrantedAuthority("ROLE_" + role.getRoleName()))
                      .collect(Collectors.toList());

              logger.info("Assigning roles to user: {}", authorities);
              logger.info("user.getUsername(): {}", user.getUsername());
              logger.info("user.getHashedPassword()", user.getHashedPassword());
              return new org.springframework.security.core.userdetails.User(user.getUsername(),
                      user.getHashedPassword(), authorities);
          } catch (Exception e) {
              logger.error("Error loading user by username: {}. Exception: {}", username, e.getMessage(), e);
              throw e;
          }
      }

    private static List<GrantedAuthority> getAuthorities(User user) {
        return user.getRoles().stream()
                .map(role -> new SimpleGrantedAuthority("ROLE_" + role))
                .collect(Collectors.toList());
    }
}

我还有一个用于数据库查询的用户服务文件。来自我名为“qq”的用户的日志记录

2024-07-08 14:11:52 INFO  c.r.a.security.AuthenticatedUser - Authenticated user found: qq
2024-07-08 14:11:52 INFO  c.r.application.services.UserService - Attempting to find user by username: qq
2024-07-08 14:11:52 INFO  c.r.application.services.UserService - User found by username 'qq': com.ricontrans.application.data.User@11
2024-07-08 14:11:52 INFO  c.r.a.security.AuthenticatedUser - User retrieved from repository: com.ricontrans.application.data.User@11
2024-07-08 14:11:52 INFO  c.r.a.security.AuthenticatedUser - Attempting to get authenticated user.
2024-07-08 14:11:52 INFO  c.r.a.security.AuthenticatedUser - Authenticated user found: qq
2024-07-08 14:11:52 INFO  c.r.application.services.UserService - Attempting to find user by username: qq
2024-07-08 14:11:52 INFO  c.r.application.services.UserService - User found by username 'qq': com.ricontrans.application.data.User@11
2024-07-08 14:11:52 INFO  c.r.a.security.AuthenticatedUser - User retrieved from repository: com.ricontrans.application.data.User@11

一切看起来都是正确的,但问题是: 重定向到

/Main
永远不会发生,它只是重定向到根路由,所有用户都经过身份验证,因为他可以访问所有需要权限的视图。此外,我尝试在成功登录后显示通知的所有事情都不会发生。

java reactjs authentication vaadin tsx
1个回答
0
投票

尝试在

defaultSuccessUrl
课程中使用
successForwardUrl
代替
SecurityConfiguration

© www.soinside.com 2019 - 2024. All rights reserved.