简体   繁体   English

angular 2 使用 spring 安全登录

[英]angular 2 login with spring security

im trying to integrate spring security with a custom angular 2 login, that is a specific endpoint of my app is protected with spring security, trying to access it will redirect to /login that is handled in angular 2. as things stands now i have no clue as to how to perform the login and grant access to the backend API once logged.我正在尝试将 spring 安全性与自定义 angular 2 登录集成,这是我的应用程序的特定端点受到 spring 安全性的保护,尝试访问它将重定向到在 angular 2 中处理的 /login。就目前情况而言,我没有关于如何执行登录并在登录后授予对后端 API 的访问权限的线索。

i am configuring spring security as follows:我正在配置 spring 安全性如下:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .cors().and()
        .authorizeRequests()
        .antMatchers("/api/someEndpoint/**")
        .hasRole(ADMIN_ROLE).and().formLogin()
        .loginPage("/login").and().logout();
}


@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}

as I had the default login everything worked fine, but I have found myself unable to create a working angular 2 login integration.因为我有默认登录,所以一切正常,但我发现自己无法创建有效的 angular 2 登录集成。 I tried the following code in angular 2 to no avail:我在angular 2中尝试了如下代码,无果:

login(loginDetails:Object) {
    console.log(loginDetails)
    const headers = new Headers({ 'Content-Type': 'application/json' });
const options = new RequestOptions({ headers: headers });
const body = JSON.stringify(loginDetails);
    console.log(headers);
    console.log(body);
return this.http.post(this.loginUrl, body, options) 
}

as far as I know spring security defaults for username and password variable names are "username" and "password", which i am sure are being passed in the request body so when passing some invalid user data like {"username":"admin", "password": "pass"} I should be redirected to /login?error or something, and when successfully authenticated I should be redirected to /welcome and stay authenticated据我所知 spring 用户名和密码变量名称的安全默认值是“用户名”和“密码”,我确信它们是在请求正文中传递的,因此在传递一些无效的用户数据时,如{"username":"admin", "password": "pass"}我应该被重定向到 /login?error 什么的,当成功通过身份验证时,我应该被重定向到 /welcome 并保持身份验证

I have the user and pass defined in my db and my custom userDetailsService checks against it any answers, comments or questions are welcome我在我的数据库中定义了用户和密码,我的自定义 userDetailsService 检查它,欢迎任何答案、评论或问题

Once you're working with the API, you've to use either HTTP Basic or token authentication and not Form one. 使用API​​后,您将使用HTTP Basic或令牌身份验证,而不是Form 1。 It's required to use HTTPS when using any of them. 使用任何一个时都需要使用HTTPS。

To auth in HTTP Basic way using Angular 2 the login service may look like this: 要使用Angular 2以HTTP Basic方式进行身份验证,登录服务可能如下所示:

login (loginDetails: any): Observable<LoginResponse> { // custom class, may be empty for now

    let headers = new Headers({ 
          'Authorization': 'Basic ' + btoa(loginDetails.login + ':' + loginDetails.pass),
          'X-Requested-With': 'XMLHttpRequest' // to suppress 401 browser popup
    });

    let options = new RequestOptions({ 
           headers: headers 
    });

    return this
              .http
              .post(this.loginUrl, {}, options)
              .catch(e => this.handleError(e); // handle 401 error - bad credentials
}

... then you can subscribe this in a component: ...然后你可以在一个组件中订阅它:

loginNow() {
   this
     .loginService
     .login(this.loginDetails)
     .subscribe(next => {
        this.router.navigateByUrl("/"); // login succeed
     }, error => {
        this.error = "Bad credentials"; // or extract smth from <error> object
     });
}

Then you can use the loginNow() method inside the component templates like this (click)="loginNow() . 然后你可以在组件模板中使用loginNow()方法,如下所示(click)="loginNow()

Once the server will accept the authorization, JSESSIONID will be stored in your browser automatically because of Spring Security features and you won't be forced to send the credential details each time in order to access private resources. 一旦服务器接受授权,由于Spring Security功能, JSESSIONID将自动存储在您的浏览器中,并且您不会每次都被迫发送凭据详细信息以访问私有资源。

Your login server method may look like this: 您的登录服务器方法可能如下所示:

@PreAuthorize("hasRole('USER')")
@PostMapping("/login")
public ResponseEntity login() {
    return new ResponseEntity<>(HttpStatus.OK);
}

... it will reject with 401 UNAUTHORIZED once the authorization fails or accept with 200 SUCCESS if it won't. ......一旦授权失败,它将以401 UNAUTHORIZED拒绝,如果不能,则接受200 SUCCESS

How to setup the server in the proper way there's a number of Spring Security demo projects - https://github.com/spring-guides/tut-spring-security-and-angular-js 如何以适当的方式设置服务器有许多Spring Security演示项目 - https://github.com/spring-guides/tut-spring-security-and-angular-js

the code isn't tested though :( 代码未经过测试:(

Your spring security config needs to look like this 您的spring security配置需要如下所示

 http!!
     .cors().and()
     .csrf().disable()
    .authorizeRequests()
     .requestMatchers(object: RequestMatcher {
       override fun matches(request: HttpServletRequest?): Boolean {
         return CorsUtils.isCorsRequest(request)
       }
     }).permitAll()
    .antMatchers("/api/**").authenticated()
    .anyRequest().permitAll()
    .and()
    .formLogin().permitAll()

I had a similar issue, but I had to override the successlogout handler as mentioned here .我有一个类似的问题,但我不得不重写此处提到的成功注销处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM