Spring Security吃AngularJS POST请求 [英] Spring security eating angularjs POST request

查看:37
本文介绍了Spring Security吃AngularJS POST请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然使用spring security自定义登录表单,但是从HttpServletRequest中无法访问我从UI传递的参数.

While using spring security custom login form, the parameters I passed from UI aren't accessible in HttpServletRequest.

class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter {

    private final TokenAuthenticationService tokenAuthenticationService;
    private final CustomJDBCDaoImpl userDetailsService;

    protected StatelessLoginFilter(String urlMapping, TokenAuthenticationService tokenAuthenticationService,
            CustomJDBCDaoImpl userDetailsService, AuthenticationManager authManager) {
        super(new AntPathRequestMatcher(urlMapping));
        this.userDetailsService = userDetailsService;
        this.tokenAuthenticationService = tokenAuthenticationService;
        setAuthenticationManager(authManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {

                final UsernamePasswordAuthenticationToken loginToken = new UsernamePasswordAuthenticationToken(
                request.getAttribute("email").toString(), request.getAttribute("password").toString());
        return getAuthenticationManager().authenticate(loginToken);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
            FilterChain chain, Authentication authentication) throws IOException, ServletException {

        final UserDetails authenticatedUser = userDetailsService.loadUserByUsername(authentication.getName());
        final UserAuthentication userAuthentication = new UserAuthentication(authenticatedUser);

        tokenAuthenticationService.addAuthentication(response, userAuthentication);
        SecurityContextHolder.getContext().setAuthentication(userAuthentication);
    }
}

在AttemptAuthentication方法中,请求未使用我使用以下代码从POST请求传递的属性:

In AttemptAuthentication method request is not taking attributes I passed from the POST request using following code:

 var request = $http.post('/verifyUser', 
       {email: 'user', password: 'user',_csrf: $cookies['XSRF-TOKEN']})

我尝试使用调试器控制台对其进行跟踪,发现有效负载中填充了我转发的元素.

I tried to track it using debugger console and found the payload populate with the elements I forwarded.

{电子邮件":用户",密码":用户","_ csrf":"f1d88246-28a0-4e64-a988-def4cafa5004"}

{"email":"user","password":"user","_csrf":"f1d88246-28a0-4e64-a988-def4cafa5004"}

我的安全配置为:

http
                .exceptionHandling().and()
                .anonymous().and()
                .servletApi().and()
                .headers().cacheControl().and()
                .authorizeRequests()

                //allow anonymous resource requests
                .antMatchers("/").permitAll()               
                //allow anonymous POSTs to login
                .antMatchers(HttpMethod.POST, "/verifyUser").permitAll()
                .and()
                  .formLogin().loginPage("/signin")
                .permitAll()
                .and()

                .addFilterBefore(new StatelessLoginFilter("/verifyUser", new TokenAuthenticationService("456abc"), new CustomJDBCDaoImpl() , authenticationManager()), UsernamePasswordAuthenticationFilter.class)


                .addFilterBefore(new StatelessAuthenticationFilter(new TokenAuthenticationService("456abc")), UsernamePasswordAuthenticationFilter.class).httpBasic()
                         .and().csrf().disable().addFilterBefore(new CSRFFilter(), CsrfFilter.class);

编辑#1

我也尝试过使用getParameter("email")代替getAttribute("email"),但是,整个参数映射在这一点上也是空的.

I have also tried to use getParameter("email") instead of getAttribute("email") but, whole parameters map was empty at this point as well.

编辑#2:添加请求内容

Remote Address:127.0.0.1:80
Request URL:http://localhost/api/verifyUser/
Request Method:POST
Status Code:502 Bad Gateway
Response Headers
view source
Connection:keep-alive
Content-Length:583
Content-Type:text/html
Date:Sun, 11 Oct 2015 17:23:24 GMT
Server:nginx/1.6.2 (Ubuntu)
Request Headers
view source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:81
Content-Type:application/x-www-form-urlencoded
Cookie:XSRF-TOKEN=f1d88246-28a0-4e64-a988-def4cafa5004
Host:localhost
Origin:http://localhost
Referer:http://localhost/ui/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
X-XSRF-TOKEN:f1d88246-28a0-4e64-a988-def4cafa5004
Form Data
view source
view URL encoded
{"email":"user","password":"user"}:

推荐答案

所需的 email password 数据是参数,而不是属性.ServletRequest中的属性是仅服务器端的数据,您可以在应用程序中使用它们在类之间或JSP之间传递数据.

The email and password data that you want are parameters, not attributes. Attributes in the ServletRequest are server-side only data that you can use in your application to pass data around between classes or to JSPs.

注意:您必须使用内容类型 application/x-www-form-urlencoded ,并确保请求主体的编码格式正确,才能使用 getParameter 在服务器端,例如 email = user& password = user .

Note: You have to use the content type application/x-www-form-urlencoded and make sure that the request body is encoded in the correct format to use getParameter on the server side, e.g. email=user&password=user.

默认情况下,Angular会将对象编码为JSON

By default Angular will encode an object as JSON

转换请求和响应

Angular提供以下默认转换:

Angular provides the following default transformations:

请求转换($ httpProvider.defaults.transformRequest和$ http.defaults.transformRequest):

Request transformations ($httpProvider.defaults.transformRequest and $http.defaults.transformRequest):

如果请求配置对象的data属性包含一个对象,将其序列化为JSON格式.

If the data property of the request configuration object contains an object, serialize it into JSON format.

另请参见如何发布urlencoded在AngularJS中使用$ http生成表单数据?

getAttribute()和getParameter()之间的差异

这篇关于Spring Security吃AngularJS POST请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆