Spring Security 4 自定义登录 j_spring_security_check 返回 http 302

标签 spring spring-mvc spring-security

我问了一个关于最新的spring框架,基于代码的配置的问题here

初始化器

public class AppInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { SecurityConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { MvcConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
}

mvc 配置

    @EnableWebMvc
    @ComponentScan({ "com.appname.controller" })
    public class MvcConfig extends WebMvcConfigurerAdapter {
        @Bean
        public InternalResourceViewResolver viewResolver() {
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
            resolver.setPrefix("/WEB-INF/jsp/");
            resolver.setSuffix(".jsp");
            return resolver;
        }

@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/res/**").addResourceLocations("/res/");
    }
    }

安全配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private CustomUserDetailsService customUserDetailsService;

public SecurityConfig() {
    customUserDetailsService = new CustomUserDetailsService();
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
        throws Exception {
    auth.inMemoryAuthentication().withUser("user").password("password")
            .roles("USER");
    auth.userDetailsService(customUserDetailsService);
}

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/res/**").permitAll()
            .and().authorizeRequests()
            .anyRequest().hasRole("USER")
            .and().formLogin().loginPage("/account/signin").permitAll()
            .and().logout().permitAll();
    }
}

安全初始化程序

public class SecurityInitializer extends
        AbstractSecurityWebApplicationInitializer {

}

自定义登录

public class CustomUserDetailsService implements UserDetailsService {

    private AccountRepository accountRepository;

    public CustomUserDetailsService() {
        this.accountRepository = new AccountRepository();
    }

    @Override
    public UserDetails loadUserByUsername(String email)
            throws UsernameNotFoundException {

        Account account = accountRepository.getAccountByEmail(email);

        if (account == null) {
            throw new UsernameNotFoundException("Invalid email/password.");
        }

        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority("USER"));

        return new User(account.getEmail(), account.getPassword(), authorities);
    }
}

但是,现在我有关于自定义登录的新问题。

当发布到 j_spring_security_check 时,我会收到 http 302。

我正在请求/,但登录后,它仍停留在登录页面上。

因为我使用的是spring security 4.x版本,纯代码配置,所以在网上找不到更多引用。谁能帮忙找出原因。

编辑

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'securityConfig': 
Injection of autowired dependencies failed; 
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: 
private org.springframework.security.core.userdetails.UserDetailsService sg.mathschool.infra.SecurityConfig.userDetailsService; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [org.springframework.security.core.userdetails.UserDetailsService] found for dependency: 
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=userDetailsService)}

我更改了 CustomUserDetailsS​​ervice

@Service("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {

    private AccountRepository accountRepository;

    public CustomUserDetailsService() {
        this.accountRepository = new AccountRepository();
    }

    @Override
    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String email)
            throws UsernameNotFoundException {

        Account account = accountRepository.getAccountByEmail(email);

        if (account == null) {
            throw new UsernameNotFoundException("Invalid email/password.");
        }

        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority("USER"));

        return new User(account.getEmail(), account.getPassword(), authorities);
    }
}

安全配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("userDetailsService")
    private UserDetailsService userDetailsService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("password")
                .roles("USER");
        auth.userDetailsService(userDetailsService).passwordEncoder(
                passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/res/**").permitAll()
                .antMatchers("/account/**").permitAll().anyRequest()
                .hasRole("USER").and().formLogin().loginPage("/account/signin")
                .failureUrl("/account/signin?error").usernameParameter("email")
                .passwordParameter("password").and().logout()
                .logoutSuccessUrl("/account/signin?logout").and().csrf();

    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }
}

最佳答案

在 Spring Security 4.x 中,登录 URL 已更改为 login 而不是 j_spring_security_check,请参阅 Migrating from Spring Security 3.x to 4.x (XML Configuration) .

<form name='f'action="login" method='POST'>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
    <table>
        <tbody>
            <tr>
                <td>User Name</td>
                <td><input type="text" name="username" size="30" /></td>
            </tr>
            <tr>
                <td>Password</td>
                <td><input type="password" name="password" size="30" /></td>
            </tr>
            <tr>
                <td></td>
                <td><input type="submit" value="login" /></td>
            </tr>
        </tbody>
    </table>
</form>

关于Spring Security 4 自定义登录 j_spring_security_check 返回 http 302,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29554850/

相关文章:

java - 无法从 http : maven-artifact-manager:pom:2. maven.apache.org/maven2 传输 org.apache.maven ://repo. 0.6

Spring Security/MVC/JPA --> 不支持请求方法 'POST'

java - 使用 renjin 将 java 与 R 集成

spring - 使用 Spring Data REST 公开枚举

facebook - Grails Spring 安全 facebook 插件示例 FacebookAuthDAOImpl

java - spring @PostConstruct 未在 JBoss7 中触发

java - Jhipster/Spring Kafka 消费者与 Python 生产者

java - Spring - 找不到 org/springframework/context/event/EventListenerFactory 的类文件

Elasticsearch 配置加载包失败

java - Spring 安全 : all endpoints return status 200 and unresponsive to constraints as antMatchers