I have created a simple application. I have AD windows authentication web api which is on different domain so I have enabled cors. I have created a spike of api and returning 401 when not authorized.
app.service.ts
authenticateUser(): Observable<any> {
return this.http.get("http://localhost:36655/", { withCredentials: true })
.map(this.extractData)
.catch(this.handleError);
}
appponent.ts
@Component({
moduleId: module.id,
selector: 'app-root',
templateUrl: 'appponent.html',
styleUrls: ['appponent.css']
})
export class AppComponent {
constructor(appService: AppService) {
appService.authenticateUser()
.subscribe(response => {
//do something here because its not 401
},
error => {
if (error.indexOf("401") >= 0)
console.log("Redirect to contact page")
else {
}
});
}
}
There are 2 things I am struggling with
- how do I hide Router-Outlet (reason is I don't want to show my main page/links)
- I can hide it using [hidden] on the main div but then how do I redirect? because
<router-outlet></router-outlet>
will be invisible
appponent.html
<div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<a class="navbar-brand" [routerLink]="['']">Home</a>
<ul class="nav navbar-nav">
<li><a [routerLink]="['/factory']" id="factory" name="factory">Factory</a></li>
<li><a [routerLink]="['/supplier']" id="supplier" name="supplier">Supplier</a></li>
<li><a [routerLink]="['/businessarea']" id="businessArea" name="businessArea">Business Area</a></li>
</ul>
</div>
</nav>
<router-outlet></router-outlet>
</div>
I have access all or no-access authentication that's why I dont want to show anything. Is there something like
router.navigate('../shared/contact.html')
?
Edit 1:
appponent.ts
@Component({
moduleId: module.id,
selector: 'app-root',
templateUrl: 'appponent.html',
styleUrls: ['appponent.css']
})
export class AppComponent {
private isAuthenticated: boolean = false;
constructor(private authService: AuthService) {
this.authService.authenticateUser()
.subscribe(response => {
if (response.status == 200)
this.isAuthenticated = true;
},
error => {
if (error.indexOf("401") >= 0)
this.isAuthenticated = false;
});
}
}
authguard.ts
@Injectable()
export class AuthGuard implements CanActivate {
private isActive: boolean = true;
constructor(private authService: AuthService, private router: Router) {
}
canActivate(): boolean {
this.authService.authenticateUser()
.subscribe(() => {},
error => {
if (error.indexOf("401") >= 0) {
let link = ['contactus'];
this.router.navigate(link);
this.isActive = false;
}
});
return this.isActive;
}
}
auth.service.ts
@Injectable()
export class AuthService {
constructor(private http: Http) {
}
authenticateUser(): Observable<any> {
return this.http.get("http://localhost:5002/api/v1/authenticate", { withCredentials: true })
.map(this.extractData)
.catch(this.handleError);
}
private extractData(response: Response) {
let body = response;
return body || {};
}
private handleError(error: Response) {
let errMsg: string;
if (error instanceof Response) {
errMsg = `${error.status} - ${error.statusText || ''}`;
} else {
errMsg = error.toString();
}
return Observable.throw(errMsg);
}
}
appponent.html
<div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<a class="navbar-brand" [routerLink]="['']">Ethos</a>
<ul class="nav navbar-nav" *ngIf="isAuthenticated">
<li><a [routerLink]="['/factory']" id="factory" name="factory">Factory</a></li>
<li><a [routerLink]="['/supplier']" id="supplier" name="supplier">Supplier</a></li>
<li><a [routerLink]="['/businessarea']" id="businessArea" name="businessArea">Business Area</a></li>
</ul>
</div>
</nav>
<div>
<router-outlet></router-outlet>
</div>
</div>
app.routes.ts
const routes: Routes = [
{
path: '', ponent: HomeComponent, pathMatch: 'full', canActivate: [AuthGuard]
},
{ path: 'factory', ponent: FactoryFormComponent, canActivate: [AuthGuard]},
//...some other
{ path: 'contactus', ponent: ContactUsComponent }
];
AuthenticateController.cs
public HttpResponseMessage Get()
{
return User.Identity.IsAuthenticated ? new HttpResponseMessage(HttpStatusCode.OK) : new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
I can hide the menu fine but homeComponent which is search textbox renders before authentication, I want to hide everything and just want to show Logo. this search for factory textbox should not be displayed and there is data like gridview at the bottom which i am not showing in this picture.
It does not redirect until Cancel is clicked...another solution is just like I hid the menu I do it on homeComponent but there are many authService calls going around which is not elegant i guess
I have created a simple application. I have AD windows authentication web api which is on different domain so I have enabled cors. I have created a spike of api and returning 401 when not authorized.
app.service.ts
authenticateUser(): Observable<any> {
return this.http.get("http://localhost:36655/", { withCredentials: true })
.map(this.extractData)
.catch(this.handleError);
}
app.ponent.ts
@Component({
moduleId: module.id,
selector: 'app-root',
templateUrl: 'app.ponent.html',
styleUrls: ['app.ponent.css']
})
export class AppComponent {
constructor(appService: AppService) {
appService.authenticateUser()
.subscribe(response => {
//do something here because its not 401
},
error => {
if (error.indexOf("401") >= 0)
console.log("Redirect to contact page")
else {
}
});
}
}
There are 2 things I am struggling with
- how do I hide Router-Outlet (reason is I don't want to show my main page/links)
- I can hide it using [hidden] on the main div but then how do I redirect? because
<router-outlet></router-outlet>
will be invisible
app.ponent.html
<div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<a class="navbar-brand" [routerLink]="['']">Home</a>
<ul class="nav navbar-nav">
<li><a [routerLink]="['/factory']" id="factory" name="factory">Factory</a></li>
<li><a [routerLink]="['/supplier']" id="supplier" name="supplier">Supplier</a></li>
<li><a [routerLink]="['/businessarea']" id="businessArea" name="businessArea">Business Area</a></li>
</ul>
</div>
</nav>
<router-outlet></router-outlet>
</div>
I have access all or no-access authentication that's why I dont want to show anything. Is there something like
router.navigate('../shared/contact.html')
?
Edit 1:
app.ponent.ts
@Component({
moduleId: module.id,
selector: 'app-root',
templateUrl: 'app.ponent.html',
styleUrls: ['app.ponent.css']
})
export class AppComponent {
private isAuthenticated: boolean = false;
constructor(private authService: AuthService) {
this.authService.authenticateUser()
.subscribe(response => {
if (response.status == 200)
this.isAuthenticated = true;
},
error => {
if (error.indexOf("401") >= 0)
this.isAuthenticated = false;
});
}
}
authguard.ts
@Injectable()
export class AuthGuard implements CanActivate {
private isActive: boolean = true;
constructor(private authService: AuthService, private router: Router) {
}
canActivate(): boolean {
this.authService.authenticateUser()
.subscribe(() => {},
error => {
if (error.indexOf("401") >= 0) {
let link = ['contactus'];
this.router.navigate(link);
this.isActive = false;
}
});
return this.isActive;
}
}
auth.service.ts
@Injectable()
export class AuthService {
constructor(private http: Http) {
}
authenticateUser(): Observable<any> {
return this.http.get("http://localhost:5002/api/v1/authenticate", { withCredentials: true })
.map(this.extractData)
.catch(this.handleError);
}
private extractData(response: Response) {
let body = response;
return body || {};
}
private handleError(error: Response) {
let errMsg: string;
if (error instanceof Response) {
errMsg = `${error.status} - ${error.statusText || ''}`;
} else {
errMsg = error.toString();
}
return Observable.throw(errMsg);
}
}
app.ponent.html
<div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<a class="navbar-brand" [routerLink]="['']">Ethos</a>
<ul class="nav navbar-nav" *ngIf="isAuthenticated">
<li><a [routerLink]="['/factory']" id="factory" name="factory">Factory</a></li>
<li><a [routerLink]="['/supplier']" id="supplier" name="supplier">Supplier</a></li>
<li><a [routerLink]="['/businessarea']" id="businessArea" name="businessArea">Business Area</a></li>
</ul>
</div>
</nav>
<div>
<router-outlet></router-outlet>
</div>
</div>
app.routes.ts
const routes: Routes = [
{
path: '', ponent: HomeComponent, pathMatch: 'full', canActivate: [AuthGuard]
},
{ path: 'factory', ponent: FactoryFormComponent, canActivate: [AuthGuard]},
//...some other
{ path: 'contactus', ponent: ContactUsComponent }
];
AuthenticateController.cs
public HttpResponseMessage Get()
{
return User.Identity.IsAuthenticated ? new HttpResponseMessage(HttpStatusCode.OK) : new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
I can hide the menu fine but homeComponent which is search textbox renders before authentication, I want to hide everything and just want to show Logo. this search for factory textbox should not be displayed and there is data like gridview at the bottom which i am not showing in this picture.
It does not redirect until Cancel is clicked...another solution is just like I hid the menu I do it on homeComponent but there are many authService calls going around which is not elegant i guess
Share Improve this question edited Nov 30, 2016 at 16:19 Kamran Pervaiz asked Nov 28, 2016 at 15:34 Kamran PervaizKamran Pervaiz 1,9415 gold badges24 silver badges44 bronze badges1 Answer
Reset to default 3In Angular 2 Routes you have 'CanActivate' and 'CanActivateChild' property. This can be used for authorization before rendering the ponent.
You can find the usage here: https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard
In your case, you do not have to remove the router-outlet.
Instead:
- Add only
<router-outlet></router-outlet>
in your app.ponent.html. Provide 2 routes
- Default route for your main ponent which requires authorization.
A separate route(/contact) for your contact ponent which is linked with the contact.html.
Import RouterModule in app module to add routes.
example:RouterModule.forRoot([ { path: '', canActivate: [AuthGuard] //provide the Injectable class here to authenticate. ponent: MainComponent }, { path: 'contact', ponent: ContentComponent } ])
Create an @Injectable class as a guard to authenticate the user. This will call the app service to authenticate the user and redirect to contact ponent if unauthorized. You can use
this.router.navigate(['contact']);
import Router from "@angular/router"- Add this new @Injectable class as the CanActivate property for your default route.