如何使用Angular+Spring+JSON自定义登录/身份验证



我有一个棱角分明的7前端和Spring后端。

我的目标是使用JSON形式进行自定义登录。计划:以JSON形式将用户名/密码从前端发送到后端。在后端进行身份验证,并将结果发送回前端。我的问题是:从前端发送数据后,我在后端看不到数据(用户名和密码为空((在我的CustomAuthenticationProvider.java中(

我的登录页面功能:

let credential = {username: this.loginForm.value.username, password: this.loginForm.value.password};
if(this.loginForm.value.username != null && this.loginForm.value.password != null) {
this.http.post("auth", JSON.stringify(credential)).subscribe(
response => {
if(response.status == 200 && response.ok == true) {
this.globals.loggeduser = this.loginForm.value.username;
//and routing
} else {
alert("Bad credential");
} 
);
}
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
public CustomAuthenticationProvider() {
super();
}
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
final String username = authentication.getName();
final String password = authentication.getCredentials().toString();
//THE PROBLEM: username and password are empty here
if (/* some custom auth here */) {
final List<GrantedAuthority> grantedAuths = new ArrayList<>();
grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
final UserDetails principal = new User(username, password, grantedAuths);
final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths);

return auth;
}
return null;
}
@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.GET,"/login", "/index*", "/static/**", "/*.js", 
"/*.json", "/*.ico", "/*.sccs", "/*.woff2", "/*.css").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/")
.loginProcessingUrl("/auth")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(successHandler())
.failureHandler(failureHandler())
.permitAll()
.and()
.logout()
.permitAll();
}
private AuthenticationSuccessHandler successHandler() {
...
}
private AuthenticationFailureHandler failureHandler() {
...
}
}

当我在用户名和密码中添加值后打印出authentication时,我会得到以下信息(主体和凭据为空(:

org.springframework.security.authentication.UsernamePasswordAuthenticationToken@b37b: Principal: ; Credentials: [PROTECTED];
Authenticated: false; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364:
RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Not granted any authorities

不使用JSON格式很好,但我需要使用JSON格式。我读了这个和这个(我尝试了这些解决方案,但没有成功(。这些有点过时而且不好(太复杂和/或xml格式(我读到我必须使用Beans编写一个自定义的UsernamePasswordAuthenticationFilter/,但我想做一个漂亮干净的java解决方案,而不需要重新设计整个东西/使用xml。我能得到一些帮助/提示吗?

编辑:使用这种格式(而不是let credential = ...(,它正在工作(但不幸的是,它不是JSON(:

let urlSearchParams = new URLSearchParams();
urlSearchParams.append('username', this.loginForm.value.username );
urlSearchParams.append('password', this.loginForm.value.password );

我找到了一个解决方案。

我添加了一个CustomAuthenticationFilter,学分转到@oe.elvik在这个问题中的答案。(注意:LoginRequest是一个包含2个变量的类:用户名和密码(之后,我将其添加到我的安全配置中,一切都正常:

@Bean
public CustomAuthenticationFilter customAuthenticationFilter() throws Exception{
CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter();
customAuthenticationFilter.setAuthenticationManager(authenticationManager());
customAuthenticationFilter.setFilterProcessesUrl("/auth");
customAuthenticationFilter.setAuthenticationSuccessHandler(successHandler());
customAuthenticationFilter.setAuthenticationFailureHandler(failureHandler());
return customAuthenticationFilter;
}

最新更新