banner



How To Pass Windoes User Name From Angular App

I've noticed that my post about Windows Authentication in an AngularJS application has gotten a lot of attention.

With the new HttpClient introduced in Angular 4.3.1, I think it's a good moment to write a little update.

I'm following the same setup as the previous post:

  • Angular project
  • Web Api project
  • Windows Authentication

Let's get started.

Web Api

Little has changed for the Web Api part. The short version is:

  • application.config
    <authentication> 	<anonymousAuthentication enabled="true" userName="" /> 	<basicAuthentication enabled="false" /> 	<clientCertificateMappingAuthentication enabled="false" /> 	<digestAuthentication enabled="false" />  	<iisClientCertificateMappingAuthentication enabled="false"> 	</iisClientCertificateMappingAuthentication>  	<windowsAuthentication enabled="true"> 		<providers> 			<add value="Negotiate" /> 			<add value="NTLM" /> 		</providers> 	</windowsAuthentication> </authentication>            
  • Web API
    • Add CORS
    • Configure CORS
      var cors = new EnableCorsAttribute("http://localhost:30033", "*", "*") { SupportsCredentials = true };                
    • Configure for json instead of XML
      config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));                
    • Web.config settings
      <authentication mode="Windows"/> <authorization>   <allow users="?"/> </authorization>                

You can find the in-detail version here.

Some points of interest in the Web API setup:

  • In the CORS configuration we need to set which url's are can contact our api. I'm developing an angular project with the angular-cli. The default is http://localhost:4200
var cors = new EnableCorsAttribute("http://localhost:30033,http://localhost:4200", "*", "*") { SupportsCredentials = true };        
  • I've noticed that while setting up a project, as described in my previous post, works as expected if you start from scratch. Starting from the github repo of my sample, sometimes you keep getting a 401 unauthorized on the post request.
    If that's the case, you can easily solve this by selecting the web api project in visual studio and open up the properties. Make sure to set Anonymous Authentication to Enabled.
    howto-ng4-winauth-01

Setting up our Angular application

I'm using the angular-cli. If you don't know how to use it, check out their getting started information before continuing.

After setting up the application, we include the new HttpClientModule in the app.module:

import { HttpClientModule } from '@angular/common/http';  @NgModule({   declarations: [     AppComponent   ],   imports: [     BrowserModule,     HttpClientModule   ],   providers: [  ],   bootstrap: [AppComponent] }) export class AppModule { }        

Note: take special note of the fact that I'm using the new http import from @angular/common/http and not the old(er) one from @angular/http which still exists and works as before. I want to make use of newer functionality so I'm going for the new http implementation.

Next, add 2 services to the application.

  • AuthenticationService
          getUser(): Observable<string> {     console.log('Calling getUser');     let serviceUrl: string = `${environment.serviceBaseUrl}auth/getuser`;     return this.http.get(serviceUrl, {responseType: 'text'})       .map((rslt: string) =>{         return rslt;       });   }        
  • DataServices
          save(data: models.IPostDataModel): Observable<string> {     console.log('Calling getUser');     let serviceUrl: string = `${environment.serviceBaseUrl}data/save`;      return this.http.post(serviceUrl, data, {responseType: 'text'})       .map((rslt: string) => {         return rslt;       });   }        

Note: the new http client uses json by default. And tries to parse what is returned by a request as json. In our sample web api we return a string, so we need to specify another responseType. Which in our case will be text. More about this can be found here .

Import and provide those services in the app module :

          import * as svcs from './services/';  	providers: [ 	svcs.AuthenticationServiceService, 	svcs.DataServiceService 	],        

Create the necessary data model for our server side PostData object.

export interface IPostDataModel {     Id: number;     Name: string;     IsTrue: boolean;     CreatedOn: Date; }  export class PostDataModel implements IPostDataModel {      public Id: number;     public Name: string;     public IsTrue: boolean;     public CreatedOn: Date;      constructor(obj?: IPostDataModel) {         if (obj != null) {             Object.assign(this, obj);         }     } }        


I'm using the AppComponent for demonstrating the windows authentication by adding 2 buttons to it.

<div style="text-align:center">   <div class="row">     <div class="col-lg-12">         <button type="button" (click)="testAuthentication()">Authentication</button>         <pre style="border:solid 1px;min-height:21px;" [ngClass]="[authBack]">{{authRslt}}</pre>     </div>     <div class="col-lg-12">         <button type="button" (click)="testPostData()">Post Data</button>         <pre style="border:solid 1px;min-height:21px;" [ngClass]="[postBack]">{{postRslt}}</pre>     </div>   </div> </div>        

And of course the functions that will be executed when clicking the buttons.

          testAuthentication(): void {     this.authSvc.getUser()       .subscribe(         r => {this.authRslt = r; this.authBack = 'success';},         e => {console.log(e); this.authBack = 'error';}       );   }    testPostData(): void {     this.dataSvc.save(new models.PostDataModel({Id: 1, Name: 'DeBiese', IsTrue: false, CreatedOn: new Date()}))       .subscribe(         r => {this.postRslt = r; this.postBack = 'success';},         e => {console.log(e); this.postBack = 'error';}       );   }        

HttpInterceptor

In the new http client module, intercepting a request and/or response is very easy. Writing an interceptor is like writing an angular service that implements the HttpInterceptor interface.

An example of an interceptor is the following:

import { Injectable } from '@angular/core'; import {   HttpRequest,   HttpHandler,   HttpInterceptor,   HttpEvent } from '@angular/common/http'; import { Observable } from 'rxjs/Observable';   @Injectable() export class WinAuthInterceptor implements HttpInterceptor{   constructor(){}    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {     return next.handle(req);   } }        

This interceptor is doing nothing now. It intercepts a request and passes it on without change.

In our case, we want to make sure that every request adds the current user's windows credentials. The intercept method changes to this:

          intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {     req = req.clone({       withCredentials: true     });     return next.handle(req);   }        

The request (response) object needs to be immutable, so we need to clone the original request before we return it. We set the withCredentials parameter to true so that every outgoing request adds those credentials.

Lastly, we need to make sure that this interceptor is being used. So we need to register it in the app module.

          providers: [     {       provide: HTTP_INTERCEPTORS,       useClass: int.WinAuthInterceptor,       multi: true     },     svcs.AuthenticationServiceService,     svcs.DataServiceService   ],        

Testing the application

Let's fire up both the Web API and the angular application:

howto-ng4-winauth-02

After clicking the buttons:

howto-ng4-winauth-03

Both requests are successful, meaning the windows authentication is working the way we want it to work.

Conclusion

Using windows authentication with the new HttpClientModule in Angular 4.3.1 (or higher) is fairly easy. Just write an interceptor and make sure it is being used by providing it in your app module.

I hope this post provides you with enough information to set this up yourself.

The full code base of this test project can be found on github.

Feel free to comment below!

Ruben Biesemans

Ruben Biesemans

Analyst Developer @ Spikes

How To Pass Windoes User Name From Angular App

Source: https://spikesapps.wordpress.com/2017/08/04/how-to-implement-windows-authentication-in-an-angular-4-3-1-application-with-a-stand-alone-web-api/

Posted by: walkeryety1964.blogspot.com

0 Response to "How To Pass Windoes User Name From Angular App"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel