Spring 安全性 5 身份验证失败



我正在尝试使用 Spring 安全性 5 来验证使用。

@Configuration
@ComponentScan(basePackages = { "com.lashes.studio.security" })
@EnableWebSecurity
public class CustomSecurityService extends WebSecurityConfigurerAdapter {
    @Autowired
    private AuthenticationSuccessHandler myAuthenticationSuccessHandler;
    @Autowired
    private AuthenticationFailureHandler authenticationFailureHandler;
    @Autowired
    private LogoutSuccessHandler myLogoutSuccessHandler;
    @Autowired
    private MyUserDetailsService userDetailsService;
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(SecurityUtils.passwordEncoder());
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/", "/mail.js/**", "/font-awesome/**", "/css/**", "/js/**", "/img/**", "/fonts/**",
                        "/login*", "/login*", "/logout*", "/signin/**", "/signup/**", "/customLogin",
                        "/user/registration*", "/registrationConfirm*", "/expiredAccount*", "/registration*",
                        "/badUser*", "/user/resendRegistrationToken*", "/forgetPassword*", "/user/resetPassword*",
                        "/user/changePassword*", "/adminlogin/**", "/eauthenticationmanagerbuildermailError*",
                        "/admin/**", "/admin/js/**", "/resources/**", "/old/user/registration*", "/successRegister*")
                .permitAll()
                .antMatchers("/invalidSession").anonymous()
                .antMatchers("/user/updatePassword*", "/user/savePassword*", "/updatePassword*")
                .hasAuthority("CHANGE_PASSWORD_PRIVILEGE").and().formLogin().loginPage("/login")
                .defaultSuccessUrl("/admin/homepage.html").failureUrl("/login?error=true")
                //.successHandler(myAuthenticationSuccessHandler).failureHandler(authenticationFailureHandler).permitAll()
                .and().sessionManagement().invalidSessionUrl("/invalidSession.html").maximumSessions(1)
                .sessionRegistry(sessionRegistry()).and().sessionFixation().none().and().logout()
                .logoutSuccessHandler(myLogoutSuccessHandler).invalidateHttpSession(false)
                .logoutSuccessUrl("/logout.html?logSucc=true").deleteCookies("JSESSIONID").permitAll().and()
                .rememberMe().rememberMeServices(rememberMeServices()).key("theKey");
    }

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }
    @Bean
    public RememberMeServices rememberMeServices() {
        CustomRememberMeServices rememberMeServices = new 
    CustomRememberMeServices("theKey", userDetailsService,
                new InMemoryTokenRepositoryImpl());
        return rememberMeServices;
    }
   }

我的用户详细信息服务是

@Service("userDetailsService")
@Transactional
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private LoginAttemptService loginAttemptService;
    @Autowired
    private HttpServletRequest request;
    public MyUserDetailsService() {
        super();
    }
    // API
    @Override
    public UserDetails loadUserByUsername(final String email) throws UsernameNotFoundException {
        final String ip = getClientIP();
        if (loginAttemptService.isBlocked(ip)) {
            throw new RuntimeException("blocked");
        }
        try {
            final User user = userRepository.findByEmail(email);
            if (user == null) {
                throw new UsernameNotFoundException("No user found with username: " + email);
            }
            org.springframework.security.core.userdetails.User u =  new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), user.isEnabled(), true, true, true, getAuthorities(user.getRoles()));
            return u;
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }
    // UTIL
    private final Collection<? extends GrantedAuthority> getAuthorities(final Collection<Role> roles) {
        return getGrantedAuthorities(getPrivileges(roles));
    }
    private final List<String> getPrivileges(final Collection<Role> roles) {
        final List<String> privileges = new ArrayList<String>();
        final List<Privilege> collection = new ArrayList<Privilege>();
        for (final Role role : roles) {
            collection.addAll(role.getPrivileges());
        }
        for (final Privilege item : collection) {
            privileges.add(item.getName());
        }
        return privileges;
    }
    private final List<GrantedAuthority> getGrantedAuthorities(final List<String> privileges) {
        final List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for (final String privilege : privileges) {
            authorities.add(new SimpleGrantedAuthority(privilege));
        }
        return authorities;
    }
    private final String getClientIP() {
        final String xfHeader = request.getHeader("X-Forwarded-For");
        if (xfHeader == null) {
            return request.getRemoteAddr();
        }
        return xfHeader.split(",")[0];
    }
}

我的登录表单是

<form class="login100-form validate-form" th:action="@{/login}" method="post">
                    <span class="login100-form-title p-b-26">
                        Welcome
                    </span>
                    <span class="login100-form-title p-b-48">
                        <i class="zmdi zmdi-font"></i>
                    </span>
                    <div class="wrap-input100 validate-input" data-validate = "Valid email is: a@b.c">
                        <input class="input100" type="text" name="username">
                        <span class="focus-input100" data-placeholder="Email"></span>
                    </div>
                    <div class="wrap-input100 validate-input" data-validate="Enter password">
                        <span class="btn-show-pass">
                            <i class="zmdi zmdi-eye"></i>
                        </span>
                        <input class="input100" type="password" name="password">
                        <span class="focus-input100" data-placeholder="Password"></span>
                    </div>
                    <div class="container-login100-form-btn">
                        <div class="wrap-login100-form-btn">
                            <div class="login100-form-bgbtn"></div>
                            <button class="login100-form-btn" type="submit">
                                Login
                            </button>
                        </div>
                    </div>
                </form>

因此,每当我尝试登录单击登录按钮时,我总是被重定向到失败页面,即

http://localhost:8080/login?error=true

编辑::已添加

public class SecurityUtils {

    @Bean
    public static PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
        // return new BCryptPasswordEncoder();
    }
}

我不太确定身份验证过程。 有关身份验证流程的简要说明会很好阅读。除此之外,我猜我的密码编码器可能有问题。所以我不确定我是否使用了正确的编码器。

在哪里检查输入字段中的密码和数据库中的编码密码?

在您的登录页面中,我没有看到csrf token字段。 而且我在您的安全配置中看不到http.csrf().disable(),所以我怀疑 Spring 安全性拒绝登录 POST,因为缺少令牌。

例如,JSP 可以具有标记

<input type="hidden"
       name="${_csrf.parameterName}"
       value="${_csrf.token}"/>

https://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/csrf.html

最新更新