0

I have Angular5 application and Web API2 as the service layer.I am using Identity Framework OAuth Owin token based authentication.The CORS code works for token generation request but for subsequent GET requests it is not working and I am getting 401 Not Authorized error.

The header for token generation from Angular is as follows:

 this._httpHeader = {
        headers: {         
          'Content-Type': 'application/x-www-form-urlencoded'
        }

The service for token generation is as follows:

getCurrentUserLogin(): Observable<any> {    
    if (sessionStorage.getItem('AccessToken') == null || sessionStorage.getItem('AccessToken') == 'undefined') {


      let requestOptions = new RequestOptions({ headers: this._httpHeader, withCredentials:  true  }); 
      return this._http.get(this._baseURL + "Authentication", requestOptions)

        .map(res => {
          if (res != null) {
            return res.json();
          }
        })        
        .do(data => console.log('Token: ' + JSON.stringify(data)))
        .catch(this.handleError);

    }

Following is the CORS code at Web API: Global.asax.cs:

protected void Application_BeginRequest()
        {
            if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
            {
                Response.Headers.Add("Access-Control-Allow-Origin", ConfigurationManager.AppSettings["AllowAccessToDomain"]);                
                Response.Headers.Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization,headers");
                Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
                Response.Headers.Add("Access-Control-Allow-Credentials", "true");
                Response.Headers.Add("Access-Control-Max-Age", "1728000");
                Response.End();
            }
        }

WebAPIConfig.cs

public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            EnableCorsAttribute cors = new EnableCorsAttribute(ConfigurationManager.AppSettings["AllowAccessToDomain"], "*", "*") { SupportsCredentials = true };
            config.EnableCors(cors);

            config.Formatters.Clear();
            config.Formatters.Add(new JsonMediaTypeFormatter());


            // Web API configuration and services
            // Configure Web API to use only bearer token authentication.
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

I am able to generate the token successfully with the above CORS code. But for the below service call from Angular it is giving 'Not Authorized' error:

Header for normal GET request from Angular:

this._httpHeader = {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Authorization': 'Bearer ' + sessionStorage.getItem('AccessToken')
        }

Normal service call from Angular:

getHomeAccountTemplates(): Observable<HomeAccountTemplate[]> {

      let requestOptions = new RequestOptions({ headers: this._httpHeader, withCredentials: true });
    return this._http.get(this._baseURL + "Account/AccountTemplates", requestOptions)

        .map(res => {          
          if (res != null) {
            return res.json();
          }
        })        
        .catch(this.handleError);
  }

Web API controller for the above service call:

[Authorize]
    public class AccountController : ApiController
    {
private readonly IAccountService _AccntServices;

        #region Constructors

        public AccountController()
        {
            _AccntServices = new AccountService();
        }

        #endregion

        [HttpGet]
        [Route("api/Account/AccountTemplates")]
        public List<HomeAccountTemplate> GetAccountTemplates()
        {
            //int InstanceID = Convert.ToInt32(((ClaimsIdentity)User.Identity).Claims.FirstOrDefault(c => c.Type.Contains("InstanceId")).Value);
            int InstanceID = 1;
            return _AccntServices.GetAccountTemplates(InstanceID);
        }
}

The above controller is not getting hit and the execution is getting stopped at Global.asax. I am getting 'Not Authorized' error. Please help as to how to fix this.

Sormita Chakraborty
  • 1,015
  • 2
  • 19
  • 36
  • CORS should not affect GET requests. It looks like your web server (IIS?) reject requests with this `Authorization` header. For example, if you disable anonimous access and enable windows auth in IIS, you can't get through with bearer token. – vasily.sib Jun 15 '18 at 02:47
  • I have not yet deployed it, but in Web config I have enabled Windows authentication because I am taking windows logged in user's name to authenticate the user against the user table in Application database. – Sormita Chakraborty Jun 15 '18 at 02:51
  • When I faced this issue, I found a solution in googling for something like "IIS enable windows auth for single route" and enable windows auth for single route of application ('/login') – vasily.sib Jun 15 '18 at 03:01
  • Can you please provide me the link that you followed? As I said, I have not yet deployed the application so how do I enable windows authentication for a single route in Web Config? – Sormita Chakraborty Jun 15 '18 at 03:04
  • https://stackoverflow.com/questions/25511208/how-to-enable-windows-authentication-for-specific-controller-in-asp-net-web-api see dragon753 answer – vasily.sib Jun 15 '18 at 03:39
  • So you have Anonymous authentication enabled in your application? – Sormita Chakraborty Jun 15 '18 at 03:41
  • 1
    Not Authorized is not CORS issue. Have you checked your Request Header in Chrome Dev Tools to make sure your proper headers are being sent with the Request? – Chau Tran Jun 15 '18 at 08:10
  • Headers passed are correct, I even tried to access Web Api service from Postman using the same header and it worked. – Sormita Chakraborty Jun 15 '18 at 09:18

0 Answers0