我正在开发一个应用程序,其中 spring作为后端, angular2作为前端,后端端是安全的(使用 Spring security ),当我运行它时,我有默认的登录表单。我想从客户端登录到服务器端,但是当我尝试传递凭据时,我在浏览器控制台中出现了这些错误。
我正在 Wildfly服务器部署我的angular2应用程序(与后端部分相同的端口)。
配置类
@Configuration
@EnableWebSecurity
@ComponentScan(basePackages = { "tn.com.kmf.springdemo.config" })
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private RESTAuthenticationFailureHandler authenticationFailureHandler;
@Autowired
private RESTAuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN", "USER").and().withUser("user")
.password("user").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class)
.authorizeRequests()
.antMatchers("/etudiant/list").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.permitAll()
.and()
.httpBasic();
}
}
CorsFilter:
public class CORSFilter implements Filter{
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() { }
}
web.xml中的安全过滤器:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
angular2方面的登录表单:
<div class="login jumbotron center-block">
<h1>Login</h1>
<form role="form" (submit)="login(username.value, password.value)">
<div class="form-group">
<label for="username">Username</label>
<input type="text" #username class="form-control" id="username" placeholder="Username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" #password class="form-control" id="password" placeholder="Password">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
服务代码:(login.service.ts)
import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
@Injectable()
export class LoginService {
isAuthenticated = false;
constructor(private http: Http) {
}
login(username: string, password: string) {
const headers = new Headers();
const creds = 'username=' + username + '&password=' + password;
// headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Basic ' +
btoa(username+':'+password));
headers.append('Content-Type', 'application/x-www-form-urlencoded');
return new Promise((resolve) => {
this.http.post('http://localhost:8080/StudentManager/login', creds, { headers: headers }).subscribe((data) => {
console.log(creds);
if (data.json().success) {
// window.localStorage.setItem('auth_key', data.json().token);
// this.userId = data.json().userId;
this.isAuthenticated = true;
}
resolve(this.isAuthenticated);
});
});
}
}
答案 0 :(得分:-1)
当您声明:
.and().formLogin()
默认登录端点应为:“yourAppContextPath / login?user = myUser&amp; password = myPassword”;
当你宣布:
.and().httpBasic();
表示您想使用spring“基本访问身份验证”
所以登录后你应该每次都发送一个标题值“Basic:”
var authenticate = function(credentials, callback) {
var headers = credentials ? {
authorization : "Basic "
+ btoa(credentials.username + ":"
+ credentials.password)
} : {};
$http.get('user', {
headers : headers
}).then(function(response) {
if (response.data.name) {
$rootScope.authenticated = true;
} else {
$rootScope.authenticated = false;
}
callback && callback($rootScope.authenticated);
}, function() {
$rootScope.authenticated = false;
callback && callback(false);
});
}
有完整的样本可能会帮助您: https://github.com/spring-guides/tut-spring-security-and-angular-js/blob/master/single/src/main/resources/static/js/hello.js
你正在使用CORS!所以你必须在你的登录页面添加一个_cors标记。