0

I am having trouble with implementing IdentityServer3 token authorization in my WebApi. My solution has a .NET Core Angular 4 client side project and a separate .NET Framework 4.5.2 WebApi project. The WebApi has been tested and is working before adding the token authorization. The IdentityServer3 login and authentication is working as well. I am using the angular-auth-oidc-client node module. I have verified that the Request Header is getting the designated properties set for Content-Type, Accept and Authorization. Here is the code for some of the key files.

user-list.component.ts

import { Component, OnInit } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import { Subject } from 'rxjs/Rx';
import { OidcSecurityService } from 'angular-auth-oidc-client';

import 'rxjs/add/operator/map';

class User {
    userId: number;
    firstName: string;
    middleName: string;
    lastName: string;
    email: string;
}

@Component({
    selector: 'user-list',
    templateUrl: './user-list.html',
    styleUrls: ['./user-list.css']
})
export class UserListComponent implements OnInit {
    dtOptions: DataTables.Settings = {};
    users: User[] = [];

    dtTrigger: Subject<User> = new Subject();

    constructor(private http: Http, private securityService: OidcSecurityService) { }

    ngOnInit(): void {
        this.dtOptions = {
            searching: true,
            pagingType: 'full_numbers',
            pageLength: 5,
            info: false,
            lengthChange: false
        };

        let headers = new Headers();
        headers.append('Content-Type', 'application/json');
        headers.append('Accept', 'application/json');
        headers.append('Authorization', 'Bearer ' + this.securityService.getToken());

        //this.dtOptions = this.http.get('api/settings/datatables')
        //    .toPromise()
        //    .then(response => response.json());

        this.http.get('/api/home', { headers })
            .map((response: Response) => response.json())
            .subscribe(users => {
                this.users = users;
                this.dtTrigger.next();
            });
    }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { AppRoutingModule } from './app.routes';
import { DataTablesModule } from 'angular-datatables';

import { AppComponent } from './app.component';
import { UserListComponent } from './user-list/user-list.component';
import { PostalCodeComponent } from './postal-code/postal-code.component';

import { AuthModule, OidcSecurityService, OpenIDImplicitFlowConfiguration } from 'angular-auth-oidc-client';

@NgModule({
    declarations: [
        AppComponent,
        UserListComponent,
        PostalCodeComponent
    ],
    imports: [
        BrowserModule,
        AppRoutingModule,
        HttpModule,
        DataTablesModule,
        AuthModule.forRoot()
    ],
    providers: [OidcSecurityService],
    bootstrap: [AppComponent]
})
export class AppModule {
    constructor(public oidcSecurityService: OidcSecurityService) {
        let settings = new OpenIDImplicitFlowConfiguration();
        settings.stsServer = 'https://identitydev.company.com/oidc/core';
        settings.redirect_url = 'http://localhost:4200';
        settings.client_id = '802523112846585';
        settings.response_type = 'id_token token';
        settings.scope = 'openid app_profile app_client_api';
        settings.post_logout_redirect_uri = 'http://localhost:4200';
        settings.startup_route = '/';
        //settings.forbidden_route = '/Forbidden';
        //settings.unauthorized_route = '/Unauthorized';
        settings.log_console_warning_active = true;
        settings.log_console_debug_active = true;
        //settings.max_id_token_iat_offset_allowed_in_seconds = 10;
        //settings.override_well_known_configuration = true;
        //settings.override_well_known_configuration_url = 'https://localhost:44386/wellknownconfiguration.json';

        // this.oidcSecurityService.setStorage(localStorage);
        this.oidcSecurityService.setupModule(settings);
    }
}

Startup.cs

using Microsoft.Owin;
using Owin;
using System.Web.Http;
using IdentityServer3.AccessTokenValidation;
using System.Net.Http.Headers;
using Microsoft.Owin.Security.OAuth;

[assembly: OwinStartup(typeof(App.API.Test.Startup))]
namespace App.API.Test
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = "https://identitydev.company.com/oidc/core",
                //RequiredScopes = new[] { "app_client_api" },
                ValidationMode = ValidationMode.ValidationEndpoint
            });

            // configure web api
            var config = new HttpConfiguration();
            config.MapHttpAttributeRoutes();
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            app.UseWebApi(config);
        }
    }
}

HomeController.cs

using System.Collections.Generic;
using System.Security.Claims;
using System.Web.Http;
using TRAX.Models;

namespace App.API.Test.Controllers
{
    [Authorize]
    [Route("api/home")]
    public class HomeController : ApiController
    {
        [HttpGet]
        public IEnumerable<User> Get()
        {
            UserList list = new UserList();
            return list.GetAll;
        }

        //// GET api/home/{firstname}
        //[HttpGet("{FirstName}")]
        //public List<User> GetByFirstName(string FirstName)
        //{
        //    UserList list = new UserList();
        //    return list.GetUserByFirstName(FirstName);
        //}
    }
}

** Note: There is a model that goes with this controller to return the data but you can trust that it is returning the correct list.

1 Answer 1

1

Apparently the solution was to remove the Global.ascx file that Microsoft created in the template project. I then updated the Startup.cs file as such.

using Microsoft.Owin;
using Owin;
using System.Web.Http;
using IdentityServer3.AccessTokenValidation;

[assembly: OwinStartup(typeof(App.API.Test.Startup))]
namespace App.API.Test
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();

            app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = "https://identitydev.company.com/oidc/core",
                RequiredScopes = new[] { "app_client_api" },
                ValidationMode = ValidationMode.ValidationEndpoint
            });

            WebApiConfig.Register(config);
            app.UseWebApi(config);
        }
    }
}

I also did not need to include the Content-Type or Accept header overrides from the client side API call. I return JSON by default from the WebApi.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.