Angular 2 login with spring security

im trying to integrate spring security with angular 2 custom name, that is, my application endpoint secured with spring security, trying to access it will be redirected to / login which is handled in angular 2. Currently i don't know how sign in and provide access to the API after registration.

I am configuring spring security like this:

@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);
}

      

since I had a default login, everything worked fine, but I found I could not create a working angular 2 login integration. I tried the following code in angular 2 to no avail:

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 defaults for username and password names "username" and "password" which I am pretty sure are passed in the request body, so passing some invalid user data like {"username":"admin", "password" : "pass"}

I have to be redirected to / login ? Error or whatever, and on successful authentication I should be redirected to / welcome and remain authenticated

I have user and password defined in my db and my custom UserDetailsService checks against it any answers, comments or questions are welcome

+5


source to share


3 answers


Once you work with the API, you should be using HTTP Basic or an authentication token, not Form one. HTTPS is required when using any of these.

For HTTP Basic authorization using Angular 2, the login service might look like this:

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 to this in the 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 method loginNow()

inside component templates like (click)="loginNow()

.



Once the server accepts authorization, it JSESSIONID

will be automatically saved in your browser due to Spring Security features, and you don't have to send credentials every time to access private resources.

Your server login method might look like this:

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

      

... it will be rejected with 401 UNAUTHORIZED

if authorization fails, or accepted with 200 SUCCESS

if it doesn't.

How to properly configure the server in a number of Spring Security demo projects - https://github.com/spring-guides/tut-spring-security-and-angular-js

code untested though :(

+7


source


Your spring security config should look like this



 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()

      

0


source


I had a similar problem but had to override the successlogout handler as mentioned here .

0


source







All Articles