使用Spring Security在Angular.js上开发应用程序。我无法从UI发送用户名和密码到spring security。获取空指针异常。经过调试发现,用户名为null。在谷歌搜索了很多,但无法解决它。当我单击登录按钮时,调试器将我带到userdetailserviceimpl.java类,发现username是null。在正常情况下,如果我使用spring security登录表单,如果我提交的表单包含错误的凭据,则用户名不会为null,但是从UI调用ajax后它将变为空。
SecurityConfig.java
@Autowired
public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(userDetailServiceImpl);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/app/**").permitAll()
.antMatchers("/login.html").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(unauthorisedHandler)
.accessDeniedHandler(accessDenied)
.and()
.formLogin()
.loginProcessingUrl("/authenticate")
.successHandler(authSuccess)
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout().logoutSuccessHandler(logoutSuccess).permitAll()
.and()
.csrf().disable();
}
UserDetailServiceImpl.java
@Service
public class UserDetailServiceImpl implements UserDetailsService {
@Autowired
private LoginDao loginDao;
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
UserInfo userInfo = loginDao.loadUserByUsername(username);
System.out.println(userInfo.getUserName() + "" + userInfo.getRole());
GrantedAuthority authority = new SimpleGrantedAuthority(userInfo.getRole());
UserDetails userDetails = (UserDetails)new User(userInfo.getUserName(), userInfo.getPassword(), Arrays.asList(authority));
return userDetails;
}
}
login.controller.js
var vm = this;
vm.credentials = {};
vm.login = function(){
var config = {
params: {
username: vm.credentials.username,
password: vm.credentials.password,
}
};
loginService.login(config);
};
login.service.js
this.login = function(config){
return ajaxService.login("../authenticate",config);
};
常见的ajax服务
this.login = function (url, dataObj) {
var res = $http({
url: url,
method: 'POST',
data: dataObj,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest'
}
});
res.success(function(data, status, headers, config) {
});
res.error(function(data, status, headers, config) {
});
return res;
};
的login.html
<div ng-controller='LoginController as lc'>
<form>
<div class="form-group"
ng-class="{'has-error is-focused' : authenticationError}">
<input id="login" ng-model="lc.credentials.username" type="text" class="form-control"
required="required" placeholder="login"/>
<span ng-show="authenticationError" class="help-block">
Please check your credentials and try again.
</span>
</div>
<div class="form-group">
<input id="password" ng-model="lc.credentials.password" type="password" class="form-control"
required="required" placeholder="password"/>
</div>
<input type="checkbox" ng-model="rememberMe"/><span> Remember me</span>
<button ng-click="lc.login()" >Login</button>
</form>
</div>
堆栈跟踪更新
Nov 22, 2016 12:47:16 AM org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter doFilter
SEVERE: An internal error occurred while trying to authenticate the user.
org.springframework.security.authentication.InternalAuthenticationServiceException
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:110)
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:132)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:177)
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:958)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:452)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1087)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at com.er4u.core.login.service.impl.UserDetailServiceImpl.loadUserByUsername(UserDetailServiceImpl.java:30)
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:102)
... 37 more
答案 0 :(得分:0)
您正在使用包装器对象,而Spring只是期望对象中的username
和password
。更改
var config = { params: { username: vm.credentials.username, password: vm.credentials.password}};
到var config = {username: vm.credentials.username, password: vm.credentials.password
。此外,还有一个教程可以简单地向您展示如何执行此操作:
https://spring.io/guides/tutorials/spring-security-and-angular-js/
答案 1 :(得分:0)
最后,我通过更改
解决了这个问题var config = {
params: {
username: vm.credentials.username,
password: vm.credentials.password,
}
};
到
vm.user = "username="+vm.credentials.username+"&password="+vm.credentials.password;
感谢大家的帮助。希望这个答案将来会帮助别人。 :)