Java Spring安全性和angularjs POST请求
使用spring security自定义登录表单时,我从UI传递的参数在HttpServletRequest中无法访问Java Spring安全性和angularjs POST请求,java,angularjs,spring,spring-mvc,spring-security,Java,Angularjs,Spring,Spring Mvc,Spring Security,使用spring security自定义登录表单时,我从UI传递的参数在HttpServletRequest中无法访问 class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter { private final TokenAuthenticationService tokenAuthenticationService; private final CustomJDBCDaoImpl user
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 method中,请求未使用我使用以下代码从POST请求传递的属性:
var request = $http.post('/verifyUser',
{email: 'user', password: 'user',_csrf: $cookies['XSRF-TOKEN']})
我尝试使用调试器控制台跟踪它,发现负载中填充了我转发的元素
{“电子邮件”:“用户”、“密码”:“用户”、“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”),但此时整个参数映射也是空的
编辑#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"}:
所需的
电子邮件
和密码
数据是参数,而不是属性。ServletRequest中的属性是仅服务器端的数据,您可以在应用程序中使用它们在类之间传递数据或将数据传递给JSP
注意:您必须使用内容类型application/x-www-form-urlencoded
,并确保请求正文的编码格式正确,以便在服务器端使用getParameter
,例如email=user&password=user
默认情况下,Angular将对象编码为JSON
角度变换提供以下默认变换:
请求转换($httpProvider.defaults.transformRequest和
$http.defaults.transformRequest):
如果请求配置对象的数据属性包含
对象,将其序列化为JSON格式
也看到
Hmm,请求的内容类型是什么?如果它不是像
application/x-www-form-urlencoded
这样的“表单”类型,那么您需要读取请求主体并对其进行解析。请参阅或我已在POST之前显式设置表单类型。当我检查request.getHeader(“内容类型”)时,它返回给我application/x-www-form-urlencoded。或者我仍然需要解析请求inputstream吗?您不必这样做。我没有使用过AbstractAuthenticationProcessingFilter
,但我知道getParameter
在过滤器和端点的这种情况下工作。您能否在服务器看到请求正文时发布其内容?可能angular做了一些奇怪的事情,服务器没有以正确的格式获取数据。啊,我想我看到了问题所在。尽管您的请求内容类型是application/x-www-form-urlencoded
,但您的请求正文实际上是JSON格式的(最后一行)。格式应为email=user&password=user
,类似于查询字符串。我将编辑我的答案。