In this article, we will learn about cookie authentication using ASP.NET Core and Angular.
We'll build an ASP.NET Core web API with input, output, and a secured user endpoint for the demo. In Angular, after successful cookie-based authentication, we access the protected user endpoint.
To download the source code for this article you can visit ourGitHub-Repository.
Let us begin.
Was sind HTTP-Cookies
A server transmits asmall amount of dataA so-called HTTP cookie (also known as a web cookie or browser cookie) to the user's web browser. For follow-up requests, the browser can save the cookie andtransfer it backon the same server.
Cookies help to recognize whether the request comes from the same browser. Therefore we use cookies for authentication purposes.
To learn more about cookies see hereArticle.
How to configure cookie authentication in ASP.NET Core
In one of oursprevious articleswe learned how to use different authentication schemes in ASP.NET Core. In this article, we mainly focus on cookie authentication.
First, let's create a new project withASP.NET Core com AngularProject template in Visual Studio.
After that we have to change itprogram.cs
To enable cookie authentication:
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.Events.OnRedirectToLogin = (context) => { context.Response.StatusCode = 401; return Task.CompletedTask; }; });
here theAdd authentication
method adds a default authentication scheme with a built-inCookieAuthenticationDefaults.AuthenticationScheme
Constant. After that theadd cookie
The method adds the necessary services for cookie authentication.
By default, cookie authentication redirects the user to the login URL if authentication fails. So we define the delegate functionoptions.Events.OnRedirectToLogin
with a lambda expression. This expression returns anot entitledHTTP-Statuscode401
.
Once this is done, we need to enable authenticationprogram.cs
:
app.UseAuthentication();app.UseAuthorization();app.MapDefaultControllerRoute();
Make sure you add the methods in the same order. Ouse authentication
euse permission
Methods add what is necessaryMiddlewareto the pipeline to authenticate the user on each request. These middlewares also define thefrom the user
property on the controller.
Now we can start creating the endpoints. Let's create a new controller calledAuthController
comApiControllereRotaAttribute:
[ApiController][Route("/api/auth")] public class AuthController: Controller{}
here theApiController
The attribute enables API specific behavior. WithRota
attribute we specify the root API path/API/auth
for all action methods in this controller.
Let's create the required templates for our endpoints using aregistrationModel:
public registration SignInRequest(string Email, string Password); public registration Response(bool IsSuccess, string Message); public registration UserClaim(String Type, String Value); public registration user (string email, string name, string password);
login terminal
Throughdemonstration purposes, we create a simple user repository with a private field inAuthController
🇧🇷 User information is stored encrypted:
private List<user> user = new(){ new("[email protected]", "User1", "User1"), new("[email protected]", "user2", "user2"),};
Now let's create the endpointapi/auth/login
als HTTP-Post-Methode:
[HttpPost("signin")]public async Task<IActionResult> SignInAsync([FromBody] SignInRequest signInRequest){ var user = users.FirstOrDefault(x => x.Email == signInRequest.Email && x.Password == signInRequest.Password ); if (usuário é nulo) { return BadRequest(new Response(false, "Credenciais inválidas.")); } var Claims = new List<Claim> { new Claim(tipo: ClaimTypes.Email, valor: signInRequest.Email), new Claim(tipo: ClaimTypes.Name,value: user.Name) }; var identidade = new ClaimsIdentity(reivindicações, CookieAuthenticationDefaults.AuthenticationScheme); await HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), new AuthenticationProperties { IsPersistent = true, AllowRefresh = true, ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10), }); return Ok(new Response(true, "Conectado com sucesso"));}
here with thatsignInRequest
parameters we get theEmail
epassword
Values. With these values ​​we check our local user storeuser
whether the specified user exists or not.
If the user's credentials are valid, we createExpectations
and then the HTTP cookie with theHttpContext.SignInAsync
Method.
user terminal
Connected users can access secured endpoints. Let's create a secured GET endpoint/api/auth/user
:
[Authorize][HttpGet("user")]public IActionResult GetUser(){ var userClaims = User.Claims.Select(x => new UserClaim(x.Type, x.Value)).ToList(); RĂĽckgabe Ok (userClaims);}
On this endpoint, we return the claims of the currently logged-in user. OAuthorize
The attribute secures this endpoint. Since we're using cookie authentication, it checks the cookie in the request header and fills in thefrom the user
Object. If the cookie is invalid, it will be returned401
HTTP status code automatically.
output terminal
Finally, let's create an output endpoint/api/auth/sair
to delete cookies:
[Authorize][HttpGet("signout")]public asynchronous task SignOutAsync(){ await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);}
Here the end device clears the user's browser cookies by issuing a new expired cookie with no claims data.
How to authenticate cookies in Angular
In this section we work with theangular partour application.
authentication service
First, let's create the required interfaces for the API responses:
UserClaim Export Interface { type: string; value: string; } export interface response { isSuccess: boolean; message: string;}
Now we can create itAuthService
Class to make all necessary API calls:
@Injectable({ fornecidoIn: 'root',})export class AuthService { constructor(private http: HttpClient) {} public signIn(email: string, password: string) { return this.http.post<Response>('api/ Authentifizierung/Anmeldung, { E-Mail: E-Mail, Passwort: Passwort }); } public signOut() { return this.http.get('api/auth/signout'); } public user() { return this.http.get<UserClaim[]>('api/auth/user'); } public isSignedIn(): Observable<boolean> { return this.user().pipe( map((userClaims) => { const hasClaims = userClaims.length > 0; return !hasClaims ? false : true; }), catchError( (Fehler) => { RĂĽckgabe von (false); })); }}
WithinAuthService
, we createdlog in
,from the user
, zgo out
functions. These functions call the respective API endpoints in the backend.
In addition to these functions, we have created another oneisSignedIn
Occupation. This function calls the user's endpoint and returnsreal
orNOT CORRECT
based on your authentication status.
login component
Now let's create an HTML login component to input the user's credentials:
<div class="d-flex flex-column align-items-center justifica-content-center" *ngIf="!signedIn else assinadoInAlready"> <div>Faça o login para continuar</div> <form class="form w-50" [formGroup]="loginForm" (submit)="signin($event)"> <div class="row m-3"> <label for="name">E-Mail*</label> <input class="col form-field" name="email" formControlName="email" /> </div> <div class="row m-3"> <label for="password">Senha*</label> < input class="col form-field" type="password" name="password" formControlName="password" autocomplete="on" /> </div> <div class="row m-3" *ngIf="authFailed "> <label style="color: red">Credenciais invalidas</label> </div> <div class="row m-3"> <button class="col btn btn-primary" [disabled]="! loginForm.valid" type="submit">Eingabe</button> </div> </form> <div class="alert-info p-2"> Experimente[email protected]/user1 or[email protected]/ user2 </div></div><ng-template #signedInAlready> <h4>Sign in</h4> <div> You are already signed in! </div></ng-template>
After that we create theSignInComponent
Class:
@Component({ selector: 'app-signin-component', templateUrl: './signin.component.html'}) export class SignInComponent implementiert OnInit { loginForm!: FormGroup; authFailed: boolean = falsch; AssinadoIn: booleano = falsch; Konstruktor (privater authService: AuthService, privater formBuilder: FormBuilder, roter oder privater: Router) { this.authService.isSignedIn().subscribe( isSignedIn => { this.signedIn = isSignedIn; }); } ngOnInit(): void { this.authFailed = false; this.loginForm = this.formBuilder.group( { email: ['', [Validators.required, Validators.email]], senha: ['', [Validators.required]] }); } public signIn(event: any) { if (!this.loginForm.valid) { return; } const userName = this.loginForm.get('email')?.value; senha const = this.loginForm.get('senha')?.value; this.authService.signIn(userName, password).subscribe( response => { if (response.isSuccess) { this.router.navigateByUrl('user') } }, error => { if (!error?.error?. isSuccess) { this.authFailed = true; } }); }}
In this component we check if the user is logged in or notconstructor
🇧🇷 Withincom OnInit
We initialize the functionLogin Formular
with two form fieldsdie Email
epassword
.
Each time the form is submitted, thelog in
function is called. In this function, we retrieve the values ​​from the form and pass them to thethis.authService.signIn
Occupation. This function calls the/api/auth/signin
endpoint and returns the result.
If the credentials are valid, the API sets the cookieresponse headerwith the keySet-Cookie
:
Set cookie: .AspNetCore.Cookies=CfDJ8KZELxg4LUBBvlmGEWUFluV ... _w8capcAdZ3fvcL18VNo5fReX1juZAI; expire=Sunday 10 July 2022 06:34:18 GMT; path=/; secure; same side = lax; https only
When we look at the cookie, the user's claims are encrypted. The browser saves it and passes this cookie on the next timeorder headerwith the keycookie
:
Cookie: .AspNetCore.Cookies=CfDJ8KZELxg4LUBBvlmGEWUFluVgrOiEyLK6GfUQIr8qlbJKQBcCANpte0iuC9uBZ-_zfJl-W...
user component
After successful login, we redirect the user to another called componentuser component
:
@Component({ selector: 'app-user', templateUrl: './user.component.html',}) export class UserComponent { userClaims: UserClaim[] = []; Konstruktor (privater authService: AuthService) { this.getUser (); } getUser() { this.authService.user().subscribe( resultado => { this.userClaims = resultado; }); }}
In this component we call the/api/auth/user
Endpoint with thegetUser()
Occupation.
If the cookie is valid, the protected user endpoint returns the200 (ok)Answers. Otherwise, the endpoint is returned401 not authorized).
starting component
Now let's implement theSignOutComponent
🇧🇷 It's as easy as callingthis.authService.signOut()
Function when clicking on an 'Exit' button:
@Component({ selector: 'app-signout-component', templateUrl: './signout.component.html'})export class SignOutComponent { constructor(private authService: AuthService) { this.signout(); } public signout() { this.authService.signOut().subscribe(); }}
As soon/api/auth/sair
Endpoint means Invalidating Cookie. The server does this by issuing expired cookies on the sameSet-Cookie
Response header:
Set-Cookie: .AspNetCore.Cookies=; expire=Thursday 1 January 1970 00:00:00 GMT; path=/; secure; same side = lax; https only
Therefore, when subsequently invoking a protected endpoint, 401 is returned.
Auth interceptor
Until now we haven't dealt with the unauthorized reply. By all means, when the user tries to access the protected endpoints, we need to redirect them to the login page.HttpInterceptor.
Let's create oneAuthInterceptor
Class to intercept the request:
@Injectable() export classe AuthInterceptor implementa HttpInterceptor { constructor(private router: Router) { } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req).pipe (tap(() => { }, (err: any) => { if (err instanceof HttpErrorResponse) { if (err.status !== 401) { return; } this.router.navigate(['signin'] ); } })); }}
Here we intercept the response of all API calls with thecannon
eToque
RxJSOperator. When one of the endpoints returns401, we redirect the user to the login page.
authentication protection
The above solution only works if the page makes requests to the secured API endpoint.
To overcome this and protect any angular route, we can implement oneguardClass:
@Injectable() export classe AuthGuard implementa CanActivate { constructor(private authService: AuthService, remote or privado: Router) { } canActivate(proximo: ActivatedRouteSnapshot, estado: RouterStateSnapshot) { return this.isSignedIn(); } isSignedIn(): Observable<boolean> { return this.authService.isSignedIn().pipe( map((isSignedIn) => { if (!isSignedIn) { this.router.navigate(['signin']); return false ; } gibt wahr zurĂĽck; })); }}
here thecanActivate
The function checks the user's login status. If you are logged in, we allow the user to access the page. If not, redirect them to the login page.
Routes can use oursAuthGuardName
in your statementcanActivate
Key:
RouterModule.forRoot([ { path: 'secured', component: SecuredComponent, pathMatch: 'full', canActivate: [AuthGuard] }])
Provider Registration
We have to register bothAuthInterceptor
eAuthGuardName
noAppModul
Offererbe effective:
Provenores: [ { bereitstellen: HTTP_INTERCEPTORS, useFactory: Funktion (Router: Router) { return new AuthInterceptor (Router); }, multi: true, deps: [Router] }, AuthGuard],
Testing the app
Finally, let's run the app from Visual Studio ordotnet-Run
Command. In the browser we see the "Login" page to enter credentials.
If we try to use invalid credentials, we won't be able to log in. For valid credentials, the server issues cookies to the browser and we redirect to the user's page. On this page we can see the authenticated user claims:
[ { "type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "value": "[email protected]" }, { "type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "value": "User 1" }]
Finally, we can also access the Protected page. After you click the exit button, the server invalidates the cookie. Therefore, after logging out, we cannot access the "Users" and "Protected" pages. At this point, the browser always redirects us to the "Login" page to enter valid credentials.
Conclusion
In this article, we will learn in detail how to use cookie authentication with ASP.NET Core and Angular using a code sample. First, we looked at creating the endpoints. After that we create the angle components, interceptors and guards to correctly authenticate the user.
FAQs
How to implement cookie authentication in ASP.NET Core? ›
- Add the Authentication Middleware services with the AddAuthentication and AddCookie methods.
- Call UseAuthentication and UseAuthorization to set the HttpContext.User property and run the Authorization Middleware for requests.
With the 2-Step Verification process, a user after entering valid credentials needs to enter an additional OTP (One-Time-Password, received via email or SMS) for the authentication to be successful. We have already learned how to implement this feature with the MVC client application.
How to implement JWT authentication in Web API using .NET 6.0 ASP.NET Core? ›- Create a minimal API project in Visual Studio 2022.
- Create an API endpoint in the Program. ...
- Add the Microsoft. ...
- Implement JWT authentication in the Program. ...
- Create a user model class named User to store the login credentials of the user.
- Step 1 - The Login Page. ...
- Step 2 - Creating a JWT-based user Session. ...
- Step 3 - Sending a JWT back to the client. ...
- Step 4 - Storing and using the JWT on the client side. ...
- Step 5 - Sending The JWT back to the server on each request. ...
- Step 6 - Validating User Requests. ...
- Summary and Conclusions.
ASP.NET supports Forms Authentication, Passport Authentication, and Windows authentication providers. The mode is set to one of the authentication modes: Windows, Forms, Passport, or None. The default is Windows. If the mode is None, ASP.NET does not apply any additional authentication to the request.
What is cookie encryption in ASP.NET Core? ›The ASP.NET Core data-protection system is used for exactly this purpose. It encrypts and decrypts sensitive data such as the authentication cookie. By encrypting the authentication cookie before it's returned in the response, the application knows that the cookie has not been tampered with, and can trust its values.
What are the three 3 common identification and authentication methods? ›Common types of biometrics include the following: Fingerprint scanning verifies authentication based on a user's fingerprints. Facial recognition uses the person's facial characteristics for verification. Iris recognition scans the user's eye with infrared to compare patterns against a saved profile.
What is authentication and authorization How do you achieve both in angular? ›When your users need to log in, your Angular application triggers an authentication event, which it handles by redirecting them to a customizable Auth0 login page. Once your users log in successfully, Auth0 redirects them back to your Angular application, returning tokens with their authentication and user information.
What is the difference between two-factor and two-step verification? ›In the past, two-step verification was used to describe processes that used the same authentication factors, while two-factor authentication described processes that involved different factors, such as entering a password on a website and receiving a numerical code on a mobile device.
Can you put a JWT in a cookie? ›Cookies. The server side can send the JWT token to the browser through a cookie, and the browser will automatically bring the JWT token in the cookie header when requesting the server-side interface, and the server side can verify the JWT token in the cookie header to achieve authentication.
How logging works in .NET core and ASP.NET Core? ›
In ASP.NET Core, logging providers store the logs. You can configure multiple logging providers for your application. The default ASP.NET Core configures the following logging providers: Console, Debug, EventSource, and EventLog (on Windows).
How to implement token based authentication in ASP.NET Core Web API? ›- Understanding JWT Authentication Workflow.
- Create Asp.net Core Web API project.
- Install NuGet Package (JwtBearer)
- Asp.net Core JWT appsetting.json configuration.
- Asp.net Core Startup.cs - configure services add JwtBearer.
- Create Models User, Tokens.
To authenticate a user, a client application must send a JSON Web Token (JWT) in the authorization header of the HTTP request to your backend API. API Gateway validates the token on behalf of your API, so you don't have to add any code in your API to process the authentication.
Is JWT good for API authentication? ›Any API that requires authentication can easily switch over to JWT's authorization. With JWT authorization, you get a user-based authentication. Once the user is authenticated, the user gets a secure token that they can use on all systems.
Which authentication is best for Web API? ›OAuth (specifically, OAuth 2.0) is considered a gold standard when it comes to REST API authentication, especially in enterprise scenarios involving sophisticated web and mobile applications. OAuth 2.0 can support dynamic collections of users, permission levels, scope parameters and data types.
Which authentication is best for ASP.NET Core? ›ASP.NET Core Identity also supports two-factor authentication. For authentication scenarios that make use of a local user data store and that persist identity between requests using cookies (as is typical for MVC web applications), ASP.NET Core Identity is a recommended solution.
What are those 4 commonly authentication methods *? ›The most widely available biometric systems use fingerprints, retinal or iris scans, voice recognition, and face detection (as in the latest iPhones). Since no two users have the same exact physical features, biometric authentication is extremely secure.
What are the 3 ways of 2 factor authentication? ›- Something you know (your password)
- Something you have (such as a text with a code sent to your smartphone or other device, or a smartphone authenticator app)
- Something you are (biometrics using your fingerprint, face, or retina)
There are three types of computer cookies: session, persistent, and third-party.
What are the 2 main security concerns with cookie? ›Since the data in cookies doesn't change, cookies themselves aren't harmful. They can't infect computers with viruses or other malware. However, some cyberattacks can hijack cookies and enable access to your browsing sessions. The danger lies in their ability to track individuals' browsing histories.
Which is better PAP or chap? ›
CHAP is a stronger authentication method than PAP, because the secret is not transmitted over the link, and because it provides protection against repeated attacks during the life of the link. As a result, if both PAP and CHAP authentication are enabled, CHAP authentication is always performed first.
Which authentication factor is strongest? ›The Inherence Factor is often said to be the strongest of all authentication factors. The Inherence Factor asks the user to confirm their identity by presenting evidence inherent to their unique features.
What is the most secure authentication method? ›1. Biometric Authentication Methods. Biometric authentication relies on the unique biological traits of a user in order to verify their identity. This makes biometrics one of the most secure authentication methods as of today.
How to use SSO authentication in Angular? ›- Configure Angular in miniOrange. Login to miniOrange Dashboard and click on Apps >> Add an Application. ...
- Configure SSO in Angular. ...
- Test SSO Configuration. ...
- Configure Your User Directory (Optional) ...
- Single Logout (Optional)
The authentication service is used to login & logout of the Angular app, it notifies other components when the user logs in & out, and allows access the currently logged in user. RxJS Subjects and Observables are used to store the current user object and notify other components when the user logs in and out of the app.
What is the strongest form of two factor authenticator? ›Physical Security Key (Hardware Token)
The strongest level of 2FA online account protection and the best phishing attack prevention is a physical security key.
Through a modern attack method called consent phishing, hackers can pose as legitimate OAuth login pages and request whichever level of access they need from a user. If granted these permissions, the hacker can successfully bypass the need for any MFA verification, potentially enabling a full account takeover.
Can hackers bypass two step verification? ›Another social engineering technique that is becoming popular is known as “consent phishing”. This is where hackers present what looks like a legitimate OAuth login page to the user. The hacker will request the level of access they need, and if access is granted, they can bypass MFA verification.
How do you implement cookie based authentication? ›- The client sends a login request to the server.
- On the successful login, the server response includes the Set-Cookie header that contains the cookie name, value, expiry time and some other info. ...
- The client needs to send this cookie in the Cookie header in all subsequent requests to the server.
- Select File > New > Project.
- Select ASP.NET Core Web Application. Name the project WebApp1 to have the same namespace as the project download. Click OK.
- Select an ASP.NET Core Web Application, then select Change Authentication.
- Select Individual User Accounts and click OK.
How would you implement claims based authentication in .NET Core? ›
- What are the claims?
- Implement a Custom Claim. Display all claims. Add user controller. Add view to display claims. Add link for claims. Add custom claims. ...
- Claim based authorization. Implement claim based authorization. Register claim policy in startup class. Apply claim policy to controller action.
- Summary.
- Download Source Code.
- display a clearly visible cookie banner/ notice at the user's first visit (you can read what the banner should contain here);
- provide a link in the banner to a more detailed cookie policy;
- display a command to accept all cookies;
Authentication factors can be classified into three groups: something you know: a password or personal identification number (PIN); something you have: a token, such as bank card; something you are: biometrics, such as fingerprints and voice recognition.
How to create authentication and authorization in ASP.NET Core? ›Add authentication middleware
Add the UseAuthentication middleware after UseRouting in the Configure method in the Startup file. This will enable us to authenticate using ASP.NET Core Identity. With all of this in place, the application Is all set to start using Identity.
- Decouple Authorization Logic and Policy from the Underlying Microservice. ...
- Use Sidecar Enforcement for Security, Performance and Availability. ...
- Enforce JSON Web Token (JWT) Validation. ...
- Use RBAC and ABAC to Control End-User Actions. ...
- Getting Up and Running with Authorization.
The claims-based authorization works by checking if the user has a claim to access an URL. In ASP.NET Core we create policies to implement the Claims-Based Authorization. The policy defines what claims that user must process to satisfy the policy. We apply the policy on the Controller, action method, razor page, etc.
How do I use GDPR cookie consent? ›- Receive users' consent before you use any cookies except strictly necessary cookies.
- Provide accurate and specific information about the data each cookie tracks and its purpose in plain language before consent is received.
- Document and store consent received from users.
- Get user consent before setting any kind of cookie other than necessary cookies. ...
- Make sure check boxes are not pre-checked. ...
- Your website must be accessible during the consent choices (No cookie wall) ...
- Make sure the given consent can be easily changed or withdrawn.