【问题标题】:Null being passed to Spring Security UserDetailsServiceNull 被传递给 Spring Security UserDetailsS​​ervice
【发布时间】:2013-11-19 16:59:45
【问题描述】:

我正在尝试使用 spring security 添加登录到我的 web 应用程序。

这是我第一次尝试使用纯代码配置添加 spring-security 3.2(我之前已经多次使用它与 xml 配置和标准 UserDetailsService 实现)。

我还看到了其他类似的关于迁移到 3.2 的问题,但都与 csrf 相关——我目前禁用了这些问题,只是为了排除这些变化。

我的配置如下所示:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired private UserDetailsServiceImpl userDetailsServiceImpl;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf()
                .disable()
            .authorizeRequests()
                .antMatchers("/resources/**").permitAll()
                .antMatchers("/dashboard").permitAll()
                .antMatchers("/sign-up").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/")
                .loginProcessingUrl("/loginprocess")
                .failureUrl("/?loginFailure=true")
                .permitAll()
                .and()
            .logout()
                .logoutUrl("/logout")
                .permitAll();
    }

     @Override
     protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
         auth
            .userDetailsService(userDetailsServiceImpl)
            .passwordEncoder(bCryptPasswordEncoder());
     }

     @Bean 
     public BCryptPasswordEncoder bCryptPasswordEncoder(){
         return new BCryptPasswordEncoder();
     }

我的登录表单如下所示:

<form class="form-signin" action="loginprocess" method="POST">
    <h3 class="form-signin-heading">Already Registered?</h3>
    <input type="text" class="form-control" name='j_username' placeholder="User name">
    <input type="password" class="form-control" name='j_password' placeholder="Password"><br/>
    <input class="btn btn-lg btn-primary" name="submit" type="submit" value='Sign in' >
    <a class="btn btn-lg btn-primary" href="#" >Sign up</a>
</form>

最后,我在 UserDetailsS​​ervice 的实现中尝试登录并调试和处理代码:

@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
    username = username.toLowerCase();

我看到这里传入的用户名字符串始终为空 - 因为这一切都被底层 spring 机制调用,所以我很难查看我提交的登录表单中的值发生了什么。

我之前看过并浏览了包含UsernamePasswordAuthenticationFilter 类的spring 代码,似乎obtainUsername(request) 调用只是从请求中获取null。

谁能告诉我可能出了什么问题或从哪里开始寻找的好地方? spring 在请求对象中的用户名/密码在哪里设置?


更新

我还尝试仅更改表单的操作 url 并发布到普通的 MVC 控制器 - 调试,发布的数据在 parameterMap 中存在且正确 - 所以看起来它是安全链中的东西从请求中删除我发布的数据?

【问题讨论】:

    标签: spring spring-mvc spring-security


    【解决方案1】:

    文档建议用户名/密码字段必须具有特定名称:-

    http://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/htmlsingle/#jc

    用户名必须以名为 username 的 HTTP 参数的形式出现

    密码必须以名为密码的 HTTP 参数的形式出现

    试试看它是否有效?

    【讨论】:

    • ...我现在发誓很多。他们为什么要这样对我?甚至遍历github.com/spring-projects/spring-security/blob/master/web/src/… 中的代码默认为 j_username。干得好,米奇。
    • 说真的。。为什么你会有不同的默认名称取决于你是否使用 xml/code 配置?
    • Java 配置有一些差异,我不确定为什么它们没有为参数名称保留相同的默认值。见spring.io/blog/2013/07/03/…。我们必须使用 ...formLogin().passwordParameter("j_password").usernameParameter("j_username")... 来保留旧名称。
    猜你喜欢
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    • 2017-10-27
    • 2013-02-11
    • 2011-09-01
    • 2011-05-02
    相关资源
    最近更新 更多