# DS Server: Authorizing Angular Client Components

> The DS Server Angular components implement an integrated, implicit OAuth security handling. In case, the client ID and client secret is passed as a property to the view, the component takes care of the rest. This article shows how to use the component only using an access token.

- **Author:** Bjoern Meyer
- **Published:** 2021-03-08
- **Modified:** 2026-07-17
- **Description:** The DS Server Angular components implement an integrated, implicit OAuth security handling. In case, the client ID and client secret is passed as a property to the view, the component takes care of the rest. This article shows how to use the component only using an access token.
- **3 min read** (464 words)
- **Tags:**
  - Angular
  - ASP.NET
  - DS Server
  - OAuth
  - Security
- **Web URL:** https://www.textcontrol.com/blog/2021/03/08/ds-server-authorizing-angular-client-components/
- **LLMs URL:** https://www.textcontrol.com/blog/2021/03/08/ds-server-authorizing-angular-client-components/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2021/03/08/ds-server-authorizing-angular-client-components/llms-full.txt
- **GitHub Repository:** https://github.com/TextControl/dsserver.angular.accesstoken

---

### Implicit OAuth Workflow

The DS Server Angular components implement an integrated, implicit OAuth security handling. In case, the client ID and client secret is passed as a property to the view, the component takes care of the complete OAuth workflow to request a valid access token.

```
<tx-ds-document-editor
    width="1024px"
    height="1024px"
    serviceURL="https://trial.dsserver.io"
    oauthClientID="dsserver.u5NQQHkgjmCRAOeChUVc19zNFJ9aivKz"
    oauthClientSecret="tPGgkutg8oYuSHPbfuRfE5DMf9arUCEg"
</tx-ds-document-editor>
```

The following diagram shows the *client credentials* workflow that connects the client DocumentEditor directly with DS Server by sending the client credentials to DS Server to retrieve a valid access token:

![Security workflow](https://s1-www.textcontrol.com/assets/dist/blog/2021/03/08/a/assets/security_1.webp "Security workflow")

### Using Access Tokens

The disadvantage of the above method is that the client credentials are exposed client-side. To avoid that, the components can be authorized directly with an access token:

```
<tx-ds-document-editor 
  width="500px"
  height="500px"
  serviceURL="https://trial.dsserver.io"
  accessToken="Ghgf6376722GGJHFFJGHDOOIGD56657665">
</tx-ds-document-editor>
```

The next diagram shows the authorization with an access token that has been acquired by a server application in between:

![Security workflow](https://s1-www.textcontrol.com/assets/dist/blog/2021/03/08/a/assets/security_2.webp "Security workflow")

In order to retrieve the access token from the DS Server [Web API](https://docs.textcontrol.com/textcontrol/ds-server/webref.oauth.htm) endpoints, a server-side process is required. In this case, the credentials are securely stored on the server and the client will only see the used access token.

### Web API

To demonstrate this process, an ASP.NET Core web application is used to provide a Web API that requests the OAuth access tokens from DS Server in order to return a valid access token. This endpoint is then called by Angular before the view component is rendered.

The following code shows the implementation of the Web API method *AccessToken*:

```
[HttpGet]
[Route("AccessToken")]
public async System.Threading.Tasks.Task<ActionResult> AccessTokenAsync() {

  // security credentials
  string clientId = "";
  string clientSecret = "";

  string serviceUrl = "https://trial.dsserver.io";

  string ClientCredentials = "client_credentials";

  AccessTokenResponse token;
  HttpClient m_client = new HttpClient();

  // generate the payload
  var payload = new Dictionary<string, string> {
    ["grant_type"] = ClientCredentials,
  };

  // token endpoint
  string requestUri = $"{serviceUrl}/oauth/token";

  // create the request message
  var tokenRequest = new HttpRequestMessage(HttpMethod.Post, requestUri) {
    Content = new StringContent(
      UrlEncode(payload),
      Encoding.UTF8,
      "application/x-www-form-urlencoded")
  };

  // Add basic auth header containing client id and secret
  string credentials = $"{clientId}:{clientSecret}";
  byte[] credentialsUtf8 = Encoding.UTF8.GetBytes(credentials);
  string credentialsB64 = Convert.ToBase64String(credentialsUtf8);
  tokenRequest.Headers.Authorization = 
    new AuthenticationHeaderValue("Basic", credentialsB64);

  // send the request
  var tokenResponse = await m_client.SendAsync(tokenRequest);

  // retrieve and return the token
  var tokenResponseStream = await tokenResponse.Content.ReadAsStringAsync();
  token = JsonConvert.DeserializeObject<AccessTokenResponse>(tokenResponseStream);

  return Ok(token);
}

public string UrlEncode(Dictionary<string, string> dict) {
  return string.Join("&", dict.Keys.Select(k => $"{k}={WebUtility.UrlEncode(dict[k])}"));
}
```

### Injectable Service

In the Angular application, a service is implemented to call the Web API and to return the access token:

```
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { Resolve } from '@angular/router';

@Injectable({
  providedIn: 'root'
})

export class OauthService implements Resolve<any> {

  public _http: HttpClient;
  public _baseUrl: string;

  constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    this._http = http;
    this._baseUrl = baseUrl;
  }

  resolve() {
    return this._http.get<any>(this._baseUrl + 'oauth/accesstoken');
  }
}
```

The service implements a resolve() method that is invoked when the navigation starts. The router waits for the data to be resolved before the route is finally activated. This must be defined in the imports section of the *app.module.ts*:

```
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { RouterModule, Routes } from '@angular/router';

import { AppComponent } from './app.component';
import { NavMenuComponent } from './nav-menu/nav-menu.component';
import { HomeComponent } from './home/home.component';
import { DocumentEditorModule } from '@txtextcontrol/tx-ng-ds-document-editor';
import { OauthService } from './oauth.service';

@NgModule({
  declarations: [
    AppComponent,
    NavMenuComponent,
    HomeComponent,
  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
    HttpClientModule,
    FormsModule,
    RouterModule.forRoot([
      { 
        path: '',
        component: HomeComponent, 
        pathMatch: 'full', 
        resolve: { token: OauthService } },
    ]),
    DocumentEditorModule
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule { }
```

In the *home.component.ts*, the result of this attached service is passed to the property *\_accessToken*:

```
import { ApplicationInitStatus, Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html'
})

export class HomeComponent implements OnInit {
  
  _accessToken: string = "";

  constructor(private _routes: ActivatedRoute) { }

  ngOnInit(): void {
    this._routes.data.subscribe((response: any) => {
      this._accessToken = response.token.accessToken;
    })
  }
}
```

This *\_accessToken* is then used directly in the *home.component.html*:

```
<tx-ds-document-editor
  width="500px"
  height="500px"
  serviceURL="https://trial.dsserver.io"
  accessToken="{{ _accessToken }}">
</tx-ds-document-editor>
```

### Is this Safe?

The positive of the above method is that the client credentials are not exposed client-side. But the security problem is now shifted to the server as the Web API is exposed and could be accessed by other requests. In order to avoid that, the Web API should be secured. For example by using one of the following concepts:

- **CORS**: Enable only specific hosts.
- **Security Middleware**: Filter requests (used in this demo).
- **Another Authorization**: Use second authorization (login) for the Web API.

![Security workflow](https://s1-www.textcontrol.com/assets/dist/blog/2021/03/08/a/assets/security_3.webp "Security workflow")

You can test this method by downloading the sample from our GitHub repository. Let us know, if you have any questions.

---

## About Bjoern Meyer

As CEO, Bjoern is the visionary behind our strategic direction and business development, bridging the gap between our customers and engineering teams. His deep passion for coding and web technologies drives the creation of innovative products. If you're at a tech conference, be sure to stop by our booth - you'll most likely meet Bjoern in person. With an advanced graduate degree (Dipl. Inf.) in Computer Science, specializing in AI, from the University of Bremen, Bjoern brings significant expertise to his role. In his spare time, Bjoern enjoys running, paragliding, mountain biking, and playing the piano.

- [LinkedIn](https://www.linkedin.com/in/bjoernmeyer/)
- [X](https://x.com/txbjoern)
- [GitHub](https://github.com/bjoerntx)

---

## Related Posts

- [Implementing a Security Middleware for Angular Document Editor Applications in C#](https://www.textcontrol.com/blog/2024/10/14/implementing-a-security-middleware-for-angular-document-editor-applications/llms.txt)
- [Impressions from Web Developer Conference WDC 2023 in Hamburg, Germany](https://www.textcontrol.com/blog/2023/09/21/impressions-from-web-developer-conference-wdc-2023-in-hamburg-germany/llms.txt)
- [Impressions from NDC London 2023](https://www.textcontrol.com/blog/2023/01/30/impressions-from-ndc-london-2023/llms.txt)
- [See Text Control at DEVintersection Fall 2022 in Las Vegas](https://www.textcontrol.com/blog/2022/11/15/see-text-control-at-devintersection-fall-2022-in-las-vegas/llms.txt)
- [Impressions from NDC Oslo 2022](https://www.textcontrol.com/blog/2022/10/04/impressions-from-ndc-oslo-2022/llms.txt)
- [JavaScript: Avoid Flickering and Visual Updates by Grouping Undo Steps](https://www.textcontrol.com/blog/2022/07/25/javascript-avoid-flickering-and-visual-updates-by-grouping-undo-steps/llms.txt)
- [Reusing TXTextControl Instances in Bootstrap Tabs](https://www.textcontrol.com/blog/2022/06/07/reusing-txtextcontrol-instances-in-bootstrap-tabs/llms.txt)
- [Document Viewer: Uploading Signatures](https://www.textcontrol.com/blog/2022/02/24/document-viewer-uploading-signatures/llms.txt)
- [Impressions from BASTA! Spring 2022](https://www.textcontrol.com/blog/2022/02/24/impressions-from-basta-spring-2022/llms.txt)
- [See Text Control at DEVintersection in Las Vegas](https://www.textcontrol.com/blog/2022/02/23/see-text-control-at-devintersection-in-las-vegas/llms.txt)
- [Version 30.0 Live Preview](https://www.textcontrol.com/blog/2021/09/22/version-30-live-preview/llms.txt)
- [TX Text Control 30.0 Preview: Improved Online Document Editor Ribbon Design](https://www.textcontrol.com/blog/2021/09/17/tx-text-control-30-preview-improved-online-document-editor-ribbon-design/llms.txt)
- [DocumentViewer: Deploying Forms](https://www.textcontrol.com/blog/2021/07/02/document-viewer-deploying-forms/llms.txt)
- [DocumentViewer Annotations: Highlight Text](https://www.textcontrol.com/blog/2021/06/18/document-viewer-annotations-highlight-text/llms.txt)
- [Creation of Custom Electronic Signature Boxes](https://www.textcontrol.com/blog/2021/06/15/creation-of-custom-electronic-signature-boxes/llms.txt)
- [Don't Print Your Documents! Streamlined Document Processes in Your Applications](https://www.textcontrol.com/blog/2021/06/09/dont-print-your-documents/llms.txt)
- [Advantages of a Modern Contract Lifecycle Management](https://www.textcontrol.com/blog/2021/05/07/advantages-of-a-modern-contract-lifecycle-management/llms.txt)
- [eSign Online Demo: Contract Collaboration Workflows](https://www.textcontrol.com/blog/2021/04/23/esign-online-demo-contract-collaboration-workflows/llms.txt)
- [Electronic Signature Legality Guide](https://www.textcontrol.com/blog/2021/03/10/electronic-signature-legality-guide/llms.txt)
- [Find the Text Control Product for your Web Application](https://www.textcontrol.com/blog/2021/02/23/find-the-text-control-product-for-your-web-application/llms.txt)
- [Adding Electronic and Digital Signatures to Documents in C# and Angular](https://www.textcontrol.com/blog/2021/02/19/adding-electronic-and-digital-signatures-to-documents-in-csharp-and-angular/llms.txt)
- [Track Changes: Show 'Original' and 'No Markup'](https://www.textcontrol.com/blog/2021/02/18/track-changes-show-original-and-no-markup/llms.txt)
- [Creating Adobe PDF Forms in C#](https://www.textcontrol.com/blog/2021/02/10/creating-adobe-pdf-forms-in-csharp/llms.txt)
- [.NET Microsoft Word Document API: Creating DOCX Documents with C#](https://www.textcontrol.com/blog/2021/02/08/dotnet-microsoft-word-api-creating-docs-documents/llms.txt)
- [Differences between DS Server and TX Text Control: Low-Code Service vs. Full Integration](https://www.textcontrol.com/blog/2021/02/05/document-processing-with-low-code-applications/llms.txt)
