如何使用 Angular + Spring + JSON 自定义登录/身份验证
Posted
技术标签:
【中文标题】如何使用 Angular + Spring + JSON 自定义登录/身份验证【英文标题】:How to custom Login / authenticate with Angular + Spring + JSON 【发布时间】:2020-11-23 14:22:05 【问题描述】:我有一个 Angular 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 格式。我阅读了this 和this(我尝试了这些解决方案,但没有用)。这些有点过时而且不好(太复杂和/或 xml 格式) 我读到我必须编写一个自定义的 UsernamePasswordAuthenticationFilter / 使用 Beans,但我想做一个漂亮而干净的 java 解决方案,而不需要重新处理整个事情 / 使用 xml。请问我可以得到一些帮助/提示吗?
编辑:使用这种格式(而不是let credential = ...
),它可以工作(但不幸的是它不是 JSON):
let urlSearchParams = new URLSearchParams();
urlSearchParams.append('username', this.loginForm.value.username );
urlSearchParams.append('password', this.loginForm.value.password );
【问题讨论】:
【参考方案1】:我找到了解决办法。
我添加了一个 CustomAuthenticationFilter,学分转到@oe.elvik 在this 问题中的回答。 (注意:LoginRequest 是一个有 2 个变量的类:用户名和密码) 之后,我将其添加到我的 securityConfig 中,一切正常:
@Bean
public CustomAuthenticationFilter customAuthenticationFilter() throws Exception
CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter();
customAuthenticationFilter.setAuthenticationManager(authenticationManager());
customAuthenticationFilter.setFilterProcessesUrl("/auth");
customAuthenticationFilter.setAuthenticationSuccessHandler(successHandler());
customAuthenticationFilter.setAuthenticationFailureHandler(failureHandler());
return customAuthenticationFilter;
【讨论】:
以上是关于如何使用 Angular + Spring + JSON 自定义登录/身份验证的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 keycloak 保护 angular/spring 应用程序?
如何使用 Spring Security + Angular 登录/验证
如何使用 Angular + Spring + JSON 自定义登录/身份验证
如何在 Grails 和 AngularJS 上使用 Spring Security 进行 Ajax 登录