Vaadin 自定义登录页面自动注销

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

所以,我尝试了教程中的 Vaadin 登录组件 https://vaadin.com/docs/latest/security/enabling-security,它的工作原理就像一个魅力。

现在我正在尝试自定义登录表单,但每当我登录时,当我尝试导航到任何其他页面时,我都会被注销。请帮忙。

登录表格:

        @Route("login")
        @PageTitle("Login")
        @AnonymousAllowed
        
        public class LoginViewOverLay extends Div implements BeforeEnterObserver, ComponentEventListener<AbstractLogin.LoginEvent> {
       
            
            @Autowired
            private AuthenticationManager authenticationManager;
            @Autowired
            SecurityService securityservice;
            @Autowired UserDetailsServiceImpl userdetails;
            FormLayout form = new FormLayout();
            LoginOverlay loginOverlay = new LoginOverlay();
            public LoginViewOverLay() {
                add(loginOverlay);
                loginOverlay.setOpened(true);
                loginOverlay.addLoginListener(this);
            }
            
            @Override
            public void onComponentEvent(AbstractLogin.LoginEvent loginEvent) {

                try {
                    securityservice.authenticateUser(loginEvent.getUsername(), loginEvent.getPassword());
                    loginOverlay.close();
                    getUI().ifPresent(ui -> ui.navigate("/"));
                    
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        
            @Override
            public void beforeEnter(BeforeEnterEvent beforeEnterEvent) {
                if(beforeEnterEvent.getLocation()
                    .getQueryParameters()
                    .getParameters()
                    .containsKey("error")) {
                    loginOverlay.setError(true);
                }
            }
          
        }

我的保安服务类别:

@Component
public class SecurityService {
    @Autowired
    UserDetailsServiceImpl userdetails;
    @Autowired
    PasswordEncoder encoder;
    private final AuthenticationContext authenticationContext;

    public SecurityService(AuthenticationContext authenticationContext) {
        this.authenticationContext = authenticationContext;
    }

    public UserDetails getAuthenticatedUser() {
        return authenticationContext.getAuthenticatedUser(UserDetails.class).get();
    }

    public void logout() {
        authenticationContext.logout();
    }
    public UserDetails getAuthenticatedUser2() {
        SecurityContext context = SecurityContextHolder.getContext();
        Object principal = context.getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            return (UserDetails) context.getAuthentication().getPrincipal();
        }
        // Anonymous or no authentication.
        return null;
    }
    
    public void authenticateUser(UserDetails userDetails) {
        Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }
    public void authenticateUser(String username, String password) {
        UserDetails userDetails = userdetails.loadUserByUsername(username);
        if (encoder.matches(password, userDetails.getPassword())) {
            Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
          
        } else {
           // System.out.println("wrong");
        }
    }
}

我的用户详细信息类别:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    private final UserRepository userRepository;
    
    public UserDetailsServiceImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    @Transactional
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserLogin user = userRepository.findByUserNameAndEnabled(username, true);
        if (user == null) {
            throw new UsernameNotFoundException("No user present with username: " + username);
        } else {
            //System.out.println("Yes User");
            return new User(user.getUserName(), user.getHashedPassword(), getAuthorities(user));
            
        }

    }

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

    }
    
}

安全配置类:

@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends VaadinWebSecurity {

    @Autowired
    UserDetailsServiceImpl userdetails;
    
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
    

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authorize -> authorize
                .requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/images/*.png")).permitAll()
                // .requestMatchers(new AntPathRequestMatcher("/**",
                // HttpMethod.POST.toString())).permitAll()
                .requestMatchers(new AntPathRequestMatcher("/**", HttpMethod.DELETE.toString())).denyAll()
                .requestMatchers(new AntPathRequestMatcher("/**", HttpMethod.OPTIONS.toString())).denyAll()
                .requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.OPTIONS, "/**")).denyAll()
                
        ).sessionManagement(session -> session

                        .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).invalidSessionUrl("/")
                        .maximumSessions(1).sessionRegistry(sessionRegistry()).expiredUrl("/")
                        .maxSessionsPreventsLogin(false));

        super.configure(http);
    setLoginView(http, LoginViewOverLay.class);
    
    }
    
    @Bean
    SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }
    

}
spring-boot authentication spring-security vaadin
1个回答
0
投票

使用 Spring Security 6.0+ 时出现此问题

[Spring 安全文档][1] [1]:https://docs.spring.io/spring-security/reference/servlet/authentication/session-management.html

为了防止出现此问题,请使用 SecurityContextRepository 保存 SecurityContext,如下所示:

public void authenticateUser() {
    Authentication authentication = new UsernamePasswordAuthenticationToken(loginEvent.getUsername(), loginEvent.getPassword());
        Authentication authenticated = authenticationManager.authenticate(authentication);
        SecurityContextHolder.getContext().setAuthentication(authenticated);
        SecurityContext context = SecurityContextHolder.getContext();
        securityRepo.saveContext(context, VaadinServletRequest.getCurrent(), VaadinServletResponse.getCurrent());
          if (authenticated.isAuthenticated()) {
              UI.getCurrent().navigate(DashboardView.class); 
          } else {
              System.out.println("FAILURE");
          Notification.show("Authentication failed", 3000,
          Notification.Position.BOTTOM_CENTER); }
            }
© www.soinside.com 2019 - 2024. All rights reserved.