Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows Authentication In Angular 2 Application and ASP.Net Web API

I'm trying to implement Windows authentication for my Angular 4 application which is accessing an ASP.Net Web API for all its data needs. I have a controller in my Web API named AuthenticationController with a method named Authenticate that returns the Domain\Username if the authentication is successful. The code for the AuthenticationController is as follows:

namespace MyAppWebAPI.Controllers
{
    [Authorize]
    public class AuthenticationController : ApiController
    {
        [HttpGet]
        public LoginModels Authenticate()
        {
            Debug.Write($"AuthenticationType: {User.Identity.AuthenticationType}");
            Debug.Write($"IsAuthenticated: {User.Identity.IsAuthenticated}");
            Debug.Write($"Name: {User.Identity.Name}");

            if (User.Identity.IsAuthenticated)
            {
                //return Ok($"Authenticated: {User.Identity.Name}");
                return new LoginModels { DomainName = User.Identity.Name, Role = "Admin" };
            }
            else
            {
                throw new Exception ("Not authenticated");
            }
        }
    }
}

Where LoginModels is a model as follows:

public class LoginModels
{
    public string DomainName { get; set; }
    public string Role { get; set; }
}

I have enabled CORS in my WebApiConfig.cs under AppStart folder and the code for that is as follows:

namespace MyAppWebAPI
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

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

            //Resolve CORS Issue
            var cors = new EnableCorsAttribute("http://MyAngularApplicationIP:port", "*", "*") { SupportsCredentials = true };
            config.EnableCors(cors);
        }
    }
}

Also, I have enabled Windows authentication in my Web.config:

<authentication mode="Windows"/>
    <authorization>
        <deny users="?" />
    </authorization>
</system.web>

Now in my Angular Application I have a service named AuthenticationHelperService as follows:

@Injectable()
export class AuthenticationHelperService {

    constructor(
        private _httpHelperService: HttpHelperService,
        private _http: Http,
        private _requestOptions: RequestOptions,
    ) { }

    public authenticateUser(): Observable<any> {
        console.log('Calling GetUser');
        let headers = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: headers, withCredentials: true });
        return this._http
            .get('WebApiURL:port/api/Authentication/Authenticate', options)
            .map(this._httpHelperService.extractData)
            .catch(this._httpHelperService.handleError);
    }
}

Notice that I have enabled the withCredentials: true in the request option. Also, here _httpHelperService.extractData simply converts my response into JSON and _httpHelperService.handleError logs the error (if any) on the console. Now, I am calling this service method from a component on page load in a ngOnInit method as follows:

export class MasterComponent implements OnInit {

    constructor(
        private _userLoginService : UserLoginService,
        private _authenticationHelperService: AuthenticationHelperService
    ) { }

    private userName: any;

    ngOnInit() {
        this._authenticationHelperService.authenticateUser().subscribe(
            data => this.userName = data,
            error => console.log('Authentication Error :: ' + error),
            () => console.log('Current User :: ' + this.userName));
    }
}

When I run the application then the browser asks me to enter the credentials - Please See the image After entering the credentials it takes me to the homepage but the _authenticationHelperService.authenticateUser() method doesn't return the Username. I am getting an error on the console as follows:

XMLHttpRequest cannot load "MyWebApiURL/api/Authentication/Authenticate". Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin "MyAngularAppUrl" is therefore not allowed access. The response had HTTP status code 401.

When I simply call the Authenticate method of the Web API from the browser like http://MyWebApiIP:port/api/Authentication/Authenticate then I get my Username successfully but not from the Angular Application.

like image 426
Amit Anand Avatar asked Jun 20 '26 02:06

Amit Anand


1 Answers

In addition to

WindowsAuthentication

you also need to enable

AnonymousAuthentication

since the OPTIONS Pre-flight request does not carry Auth headers, and will fail if it's not enabled.

just remember to [Authorize] all of your controllers.

like image 91
Paw Ormstrup Madsen Avatar answered Jun 22 '26 17:06

Paw Ormstrup Madsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!