Auth0 Home Blog Docs

Angular app sending authorized request to spring boot rest api, but im getting 401 code

I have 2 problems.
First one
Basically i have my application divided to Angular frontend and Spring-boot backend. I can login to Auth0 by my angular app, and im getting access token which i keep in localstorage. My goal is to make request to my backend and get resources based on my scopes in my access token. Im sending request by http with bearer token in authorization header. But when im doing these requests by angular im getting 401 unauthorized code in response. Its strange because while im making api calls by soapUI “public” path works and im getting the message.

I have tried to find some answers in the net but i found only solutions for regular web app where login logic is written in spring-boot but in my projects all login logic is in angular with help of auth0. What i need to do? I think the problem is my spring-boot app is not reading these authorization tokens despite i did some configuration.

Its my authconfig class

    @Configuration
    @EnableWebSecurity
    public class AuthConfig extends WebSecurityConfigurerAdapter {

    @Value(value = "${auth0.apiAudience}")
    private String apiAudience;
    @Value(value = "${auth0.issuer}")
    private String issuer;


    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        configuration.setAllowCredentials(true);
        configuration.addAllowedHeader("Authorization");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        JwtWebSecurityConfigurer
                .forRS256(apiAudience, issuer)
                .configure(http)
                .cors()
                .and()
                .csrf().disable()
                .authorizeRequests()
                .antMatchers(HttpMethod.GET,"/api/public").permitAll()
                .antMatchers(HttpMethod.GET,"/api/private").authenticated();


    }



My controller: 

@CrossOrigin(origins = "*", allowedHeaders = "*")
@RestController
@RequestMapping("/api")
public class ApiController {

@RequestMapping(value = "/public", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public String publicEndpoint() {
return new JSONObject()
        .put("message", "Hello from a public endpoint! You don\'t need to be authenticated to see this.")
        .toString();
}

 @RequestMapping(value = "/private", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public String privateEndpoint() {
return new JSONObject()
        .put("message", "Hello from a private endpoint! You need to be authenticated to see this.")
        .toString();
}

@RequestMapping(value = "/private-scoped", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public String privateScopedEndpoint() {
return new JSONObject()
        .put("message", "Hello from a private endpoint! You need to be authenticated and have a scope of read:messages to see this.")
        .toString();
}

   }

my request headers

![image|690x319](upload://bzFeZKtqA8MxC1JBW1L7biaftB2.png) 

-------------------------------------------------------------------------------------------------------------------------
My second problem is in my Angular application. Because when im logging using auth0 and after im redirected to my application after succed authentication i need to refresh the page to get my user-profile informations. And because its simple page application refreshing the page is rare. Maybe i need to use some kind of async function?

auth.service


    userProfile: any;

      public  auth0 = new auth0.WebAuth({
        clientID: environment.clientID,
        domain: environment.domain,
        responseType: environment.responseType,
        audience: environment.audience,
        redirectUri: environment.redirectUri,
        scope: environment.requestedScopes
      });


      constructor(private router: Router) {
      }

      public getProfile(cb): void {
        const accessToken = localStorage.getItem('access_token');
        if (!accessToken) {
          throw new Error('Access Token must exist to fetch profile');
        }

        const self = this;
        this.auth0.client.userInfo(accessToken, (err, profile) => {
          if (profile) {
            self.userProfile = profile;
            console.log(self.userProfile)
          }
          cb(err, profile);
        });
      }

      public login() {
        this.auth0.authorize();
      }

      public handleAuthentication(): void {
        this.auth0.parseHash((err, authResult) => {
          if (authResult && authResult.accessToken && authResult.idToken) {
            window.location.hash = '';
            this.setSession(authResult);
            this.router.navigate(['/home']);
          } else if (err) {
            this.router.navigate(['/error']);
            console.log(err);
            alert('Error: ${err.error}. Check the console for further details.');
          }
        });
      }

      private setSession(authResult): void {
        const expiresAt = JSON.stringify(authResult.expiresIn * 1000 + new Date().getTime());
        const scopes = authResult.scope || environment.requestedScopes || '';

        localStorage.setItem('access_token', authResult.accessToken);
        localStorage.setItem('id_token', authResult.idToken);
        localStorage.setItem('expires_at', expiresAt);
        localStorage.setItem('scopes', JSON.stringify(scopes));
      }




      public logout(): void {
        localStorage.removeItem('access_token');
        localStorage.removeItem('id_token');
        localStorage.removeItem('expires_at');
        localStorage.removeItem('scopes');
        this.router.navigate(['/']);
      }

      public isAuthenticated(): boolean {
        const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
        return new Date().getTime() < expiresAt;
      }

      public userHasScopes(scopes: Array<string>): boolean {
        const grantedScopes = JSON.parse(localStorage.getItem('scopes')).split(',');
        return scopes.every(scope => grantedScopes.includes(scope));
      }

      public renewToken() {
        this.auth0.checkSession((err,result) => {
          if(!err){
            this.setSession(result);
          }
        })
      }

And im calling it in onInit in app compoent

    export class AppComponent implements OnInit {
     title = 'SchoolGit';

      constructor(public auth: AuthService, private postService: 
     PostServiceService) {
        auth.handleAuthentication();
       }

       ngOnInit() {
        this.postService.getMessage();
      }
     }
And this is my app module.

    import { JwtModule } from '@auth0/angular-jwt';
    import { AuthService } from './services/auth.service';
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    import { NavbarComponent } from './components/navbar/navbar.component';
    import { FooterComponent } from './components/footer/footer.component';
    import { SubjectComponent } from './components/subject/subject.component';
    import { SidemenuComponent } from './components/sidemenu/sidemenu.component';
    import { HomeComponent } from './components/home/home.component';
    import { ProfileComponent } from './components/profile/profile.component';
    import { CallbackComponent } from './components/callback/callback.component';
    import { HttpClientModule } from '@angular/common/http';
    import { NotfoundComponent } from './components/notfound/notfound.component';
    import { CreatePostComponent } from './components/create-post/create-post.component';

    export function tokenGetter(){
      return localStorage.getItem('access_token');
    }

    @NgModule({
      declarations: [
        AppComponent,
        NavbarComponent,
        FooterComponent,
        SidemenuComponent,
        SubjectComponent,
        HomeComponent,
        ProfileComponent,
        CallbackComponent,
        NotfoundComponent,
        CreatePostComponent
      ],
      imports: [
        BrowserModule,
        AppRoutingModule,
        HttpClientModule,
        JwtModule.forRoot({
          config: {
            tokenGetter: tokenGetter,
            whitelistedDomains: ['localhost:8080']
          }
        })
      ],
      providers: [AuthService],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

And my post-service
    export class PostServiceService {

      constructor(public http: HttpClient) { }

      getMessage() {
        return this.http.get(environment.api_endpoint + '/api/public').subscribe(data => console.log(data), err => console.log(err));
      }
    }


If you need i can give you a link to my repository.

Where is code to pass token in authorization header in the angular app?
You need to pass accessToken in the authorization header in the angular app.

  .get<Deal[]>(environment.api_endpoint + '/api/public', {
        headers: new HttpHeaders().set('Authorization', `Bearer ${this.authService.accessToken}`)
      })
      .pipe(
        catchError(this.handleError)
      );

Here is my GitHub code