简体   繁体   English

带有JSON的Spring Security不起作用

[英]Spring Security with JSON does not work

I'm brand new to spring and I'm trying to figure out how to authenticate a user. 我是Spring的新手,所以我想弄清楚如何验证用户身份。

Currently, it looks like everything is set up correctly. 当前,看来一切都已正确设置。 When I use x-www-form-urlencoded , I can successfully log in. When using application/json , my application does not receive the emailAddress parameter. 当我使用x-www-form-urlencoded ,我可以成功登录。当使用application/json ,我的应用程序未收到emailAddress参数。

I have been googling and checking SO, but I can't find anything related. 我一直在谷歌搜索并检查SO,但找不到任何相关内容。

Here is my SecurityConfig . 这是我的SecurityConfig

package com.myapp.config;

import com.myapp.security.RestAuthenticationEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.web.bind.annotation.RestController;

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    @Qualifier("customUserDetailsService")
    private UserDetailsService userDetailsService;

    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;

    @Autowired
    public void configure(AuthenticationManagerBuilder builder) throws Exception {
        builder.userDetailsService(userDetailsService);
        builder.authenticationProvider(this.authenticationProvider());
    }

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

    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(passwordEncoder());

        return authenticationProvider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);

        http.csrf().disable()
            .exceptionHandling()
            .authenticationEntryPoint(restAuthenticationEntryPoint)
            .and()
            .authorizeRequests()
            .antMatchers("/").authenticated()
            .and()
            .formLogin().loginPage("/login").usernameParameter("emailAddress").passwordParameter("password")
            .successHandler(new SimpleUrlAuthenticationSuccessHandler())
            .failureHandler(new SimpleUrlAuthenticationFailureHandler())
            .and()
            .logout();
    }
}
formLogin().loginPage("/login").usernameParameter("emailAddress").passwordParameter("password")
                .successHandler(new SimpleUrlAuthenticationSuccessHandler())
                .failureHandler(new SimpleUrlAuthenticationFailureHandler())

In the above configure, a standard UsernamePasswordAuthenticationFilter is used to obtain username and password from request parameter. 在上面的配置中,使用标准的UsernamePasswordAuthenticationFilter从请求参数获取用户名和密码。 However, the standard filter do not parse parameters from your json string in the request. 但是,标准过滤器不会从请求中的json字符串中解析参数。

You may try to create a custom UsernamePasswordAuthenticationFilter to obtain username and password from the your json string and apply your custom filter in configuration. 您可以尝试创建自定义UsernamePasswordAuthenticationFilter以从json字符串中获取用户名和密码,然后在配置中应用自定义过滤器。 However, unlike XML configuration that can use <custom-filter position="FORM_LOGIN_FILTER" ref="yourCustomFilter" /> , you cannot replace the form login filter with your custom filter by Java Config. 但是,与可以使用<custom-filter position="FORM_LOGIN_FILTER" ref="yourCustomFilter" /> XML配置不同,您不能通过Java Config用自定义过滤器替换表单登录过滤器。

As a workaround, you can try with follows: 作为一种解决方法,您可以尝试以下操作:

  1. Create a custom filter extends AbstractAuthenticationProcessingFilter to obtain the username and password from json string and put the parsed parameters into the request. 创建一个自定义过滤器可扩展AbstractAuthenticationProcessingFilter以从json字符串获取用户名和密码,并将解析后的参数放入请求中。 The solution is to use HttpRequestWrapper class, which allow you to wrap one request with another. 解决方案是使用HttpRequestWrapper类,该类允许您将一个请求与另一个请求包装在一起。 You can subclass that, and override the getParameter to return username and password which is parsed from json string. 您可以对其进行子类化,并覆盖getParameter以返回从json字符串解析的用户名和密码。 You can then pass the wrapped request to chain.doFilter . 然后,您可以将包装的请求传递给chain.doFilter
  2. Add the custom filter before the standard UsernamePasswordAuthenticationFilter with HttpSecurity#addFilterBefore(yourCustomFilter, UsernamePasswordAuthenticationFilter.class) 使用HttpSecurity#addFilterBefore(yourCustomFilter, UsernamePasswordAuthenticationFilter.class)在标准UsernamePasswordAuthenticationFilter之前添加自定义过滤器

As the username and password is parsed from json string to the request parameter, the standard UsernamePasswordAuthenticationFilter should be able to perform authentication. 由于将用户名和密码从json字符串解析为request参数,因此标准的UsernamePasswordAuthenticationFilter应该能够执行身份验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM