Nov
8
Written by:
Michael Washington
11/8/2016 12:21 PM

Note: This tutorial is part of a series of articles that create a complete Angular 2 application using OData 4 and ASP.NET 4:
- Hello World! in Angular 2 using Visual Studio 2015 and ASP.NET 4
- Implement ASP.NET 4 MVC Application Security in Angular 2 Using OData 4 (this article)
- Tutorial: Creating An Angular 2 CRUD Application Using MVC 5 and OData 4
- Tutorial: An End-To-End Angular 2 Application Using MVC 5 and OData 4
You can implement ASP.NET 4 MVC Application security in your Angular 2 applications.
This is important because ultimately your data must be secured on the server side. The Angular 2 application is only provided data that the server side methods expose to it.

The server side methods make these decisions based on the security established when the user logs into the ASP.NET 4 MVC website.
Note: to log a user in directly through the Angular application, see: Angular 2+ Logging Into An ASP.NET 4.5 Application.
Creating The Application

For this demonstration, we start with the application created in Hello World! in Angular 2 using Visual Studio 2015 and ASP.NET 4.

First, go to Tools, NuGet Package Manager / Manage NuGet Packages for Solution…

Select Updates, Select all packages, then click Update.
Answer yes to any screens that appear.
A restart may be required.
We now need to install OData 4.

We go to the NuGet package Manager Console …

… click to the right of the PM> symbol and paste the entire list:
Install-Package Microsoft.AspNet.WebApi.WebHost
Install-Package Microsoft.AspNet.OData
It will take some time, but it will install all the packages.
(note: You will usually have to press return when it gets to the last package to install it).
(note: If the OData Client does not install (it throws an error), it is not an issue).

Add a file to the App_Start folder called WebApiConfig.cs using the following code:
using Angular2QuickStart.Models;
using Microsoft.OData.Edm;
using System.Web.Http;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
namespace Angular2QuickStart
{
class WebApiConfig
{
#region Register
public static void Register(HttpConfiguration config)
{
// OData routes
// These must be configured before the WebAPI routes
config.MapHttpAttributeRoutes();
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: GenerateEntityDataModel());
// Web API routes
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
#endregion
#region GenerateEntityDataModel
private static IEdmModel GenerateEntityDataModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
// CurrentUser function
var CurrentUserFunction = builder.Function("CurrentUser");
CurrentUserFunction.Returns<User>();
return builder.GetEdmModel();
}
#endregion
}
}
This creates the routes needed to enable OData.
Note, all the code has not been added yet, so the code will not compile at this point.

Open the Global.asax.cs file and add the following using statement:
using System.Web.Http;
In that file, replace the Application_Start() method with the following code:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
This configures the application to call the WebApiConfig class that was just added.

Add a User.cs file in the Models folder using the following code:
using System.ComponentModel.DataAnnotations;
namespace Angular2QuickStart.Models
{
public class User
{
[Key]
public string UserName { get; set; }
}
}
Note, the project should build at this point.

Create a OData4Controllers folder in the Controllers folder and add a OData4Controller.cs file using the following code:
using Angular2QuickStart.Models;
using System;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.OData;
using System.Web.OData.Routing;
namespace Angular2QuickStart.Controllers
{
public class OData4Controller : ODataController
{
#region public IHttpActionResult CurrentUser()
// odata/CurrentUser() - must be a Post call
[ODataRoute("CurrentUser()")]
public IHttpActionResult CurrentUser()
{
// User to return
User objUser = new User();
// See if the user is logged in
if (this.User.Identity.IsAuthenticated)
{
// They are logged in
objUser.UserName = this.User.Identity.Name;
}
else
{
// They are not logged in
objUser.UserName = "[Not Logged in]";
}
// Return the result
return Ok(objUser);
}
#endregion
}
}
This will provides the OData method that was configured in the WebApiConfig class.
This method will be called by the Angular code.
Add the Angular Code

Create a user folder under the app folder and create a user.ts file using the following code:
/* Defines the user entity */
export interface IUser {
UserName: string;
}
This interface will define the class that will be used to display the user.

Create a user.service.ts file using the following code:
import { Injectable } from '@angular/core';
import { Http, Response, RequestOptions, Request, RequestMethod, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import { IUser } from './user';
@Injectable()
export class UserService {
private _userUrl = 'odata/CurrentUser';
constructor(private _http: Http) { }
getCurrentUser(): Observable<IUser> {
// This is a Post so we have to pass Headers
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
// Make the Angular 2 Post
// In this case we are not passing any parameters
// so the { } has nothing inside
return this._http.post(this._userUrl, { }, options)
.map((response: Response) => <IUser[]>response.json())
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
private handleError(error: Response) {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
This is a service that will be consumed by the component that will be shown next.
Note that that OData method being called requires a http Post rather than the usual http Get.

Create a user.component.ts file using the following code:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
import { IUser } from './user';
import { UserService } from './user.service';
@Component({
selector: 'user-detail',
templateUrl: 'app/user/user.component.html'
})
export class UserComponent implements OnInit {
pageTitle: string = 'Current User';
user: IUser;
errorMessage: string;
// Register the service
constructor(private _userService: UserService) {
}
ngOnInit(): void {
// Call the method that will call the service
this.getCurrentUser();
}
getCurrentUser() {
// Call the service
this._userService.getCurrentUser().subscribe(
user => this.user = user,
error => this.errorMessage = <any>error);
}
}
This is the Angular 2 component that will be consumed in the application’s main component.

Now, create a user.component.html file using the following code:
<div class='panel panel-primary' *ngIf='user'>
<div class='panel-heading' style='font-size:large'>
{{pageTitle + ': ' + user.UserName}}
</div>
</div>
This is the template that the component needs to display the data.
Note, that *ngIf=’user is used so that the Div does not display until the user object contains data.

We created new components and services and their dependencies, and they need to registered in the main module.
Open the app.module.ts file and replace all the code with the following code:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { UserService } from './user/user.service';
import { AppComponent } from './app.component';
import { UserComponent } from './user/user.component';
@NgModule({
imports: [
BrowserModule,
HttpModule
],
declarations: [
AppComponent,
UserComponent
],
providers: [
UserService
],
bootstrap: [
AppComponent
]
})
export class AppModule { }

Finally, open the app.component.ts file and add the following code to the end of the template:
<user-detail>Loading...</user-detail>
So that the complete code for the file reads as follows:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>Hello World!</h1>
<h2>{{DynamicValue}}</h2>
<user-detail>Loading...</user-detail>
`
})
export class AppComponent {
DynamicValue: string =
"Running on IIS with ASP.NET 4.5 in Visual Studio 2015";
}
Links
Angular 2+ Logging Into An ASP.NET 4.5 Application
Implement ASP.NET 4 MVC Application Security in Angular 2 Using OData 4
Angular 2 Visual Studio 2015 QuickStart
Download Visual Studio 2015 Community Edition (Free)
Resources to Learn Angular 2
Angular 2: Getting Started (Pluralsight – Paid)
Introduction to Angular 2.0 (Microsoft Virtual Academy – Free)
Download
The project is available at http://lightswitchhelpwebsite.com/Downloads.aspx
You must have Visual Studio 2015 Update 3 (or higher) and TypeScript 2.0 (or higher) installed to run the code.
2 comment(s) so far...
Dear,
im using cookies based authentication my asp api & angular application is separate and this is my mvc authentication
FormsAuthentication.SetAuthCookie(ls_user, false); var authTicket = new FormsAuthenticationTicket(1, ls_user, DateTime.Now, DateTime.Now.AddMinutes(20), false, "Admin"); string encryptedTicket = FormsAuthentication.Encrypt(authTicket); var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);
-------------------------------------
after login i get a Cookie: .ASPXAUTH=AC9....... how do i set this cookie in my http request header ? Please give me the sample syntax for setting header with ASPXAUTH or is there any way to use same session for all http requests for angular ?
By shijil on
11/4/2017 7:29 AM
|
@shijil - Sorry I have no examples.
By Michael Washington on
11/4/2017 7:30 AM
|