如何将凭据从Angular2前端传递到Spring后端(使用Spring Security进行Basic-Authentification)

时间:2017-03-13 08:12:39

标签: spring security angular spring-security restful-authentication

我正在开发一个应用程序,其中 spring作为后端 angular2作为前端,后端端是安全的(使用 Spring security ),当我运行它时,我有默认的登录表单。我想从客户端登录到服务器端,但是当我尝试传递凭据时,我在浏览器控制台中出现了这些错误。

  

以下是错误:   enter image description here

     

enter image description here

我正在 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);
      });
    });
  }
}

1 个答案:

答案 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标记。