Making authentication with Okta.
Tags: csharp, aspdotnet, okta, auth0
Published: 2023-08-19 12:47:03

In this article, I want to tell you how you can make authentication by using third-party service authentication such as Okta. Actually, it's super easy, and I'll show a detailed tutorial.

##Preconditions
It would be fine if you create a new ASP.NET Core MVC project. Anything else no need from your side.
```bash
dotnet new mvc -n OktaAuthSample 
```

##Registration application
Before using Okta, you need to register an account if you don't have it, otherwise log in. For people who don't have an account go to this link [https://developer.okta.com/signup/](https://developer.okta.com/signup/).
After you go by the link, you'll see different plans, you need a free plan.

![plans](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y8vdtjvvp0vpc1wxdmm6.png)

I prefer GitHub authentication, but you can choose a different way.

![register](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxsehb8c5bxasyfqchql.png)

Further, you need to select Other, which means the individual using.

![other](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1vsj330q1sywz7izwety.png)

Next step, you'll be redirected to the main page where you need to create a new application.

You need to select the type of application. We created ASP.NET MVC project, which means we need to select Regular Web Applications.

![projects](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v77hlg7z4z9dtxpfs9u2.png)

Here just select ASP.NET Core

![asp](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i2jsjwdonwki52glqo7p.png)

You'll be redirected to the Application page and you need to go to the Settings tab. You'll see the secret data of your application.

![application](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7jx8ju7gxhgyfcksy70i.png)

##Implementation
Here we'll begin implementing the application and create login and logout endpoints and also an endpoint for checking authenticated users.
For the next work, you need to install this package:

![nuget](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b7n75sgix640vpehlkoe.png)

Next, go to the `appsettings.json` file an paste this code, where you need replace to your ClientId and Domain values.

```json
"Auth0": {
    "Domain": "*********************.auth0.com",
    "ClientId": "******************************"
  },
```

And now go to the `Program.cs` and paste this code:
```C#
builder.Services.AddAuth0WebAppAuthentication(options =>
{
    options.Domain = builder.Configuration["Auth0:Domain"];
    options.ClientId = builder.Configuration["Auth0:ClientId"];
});
```
And don't forget to add use authentication:
```C#
app.UseAuthentication();
```

Further you need to create a new controller in the Controllers folder:

```C#
public class AccountController : Controller
{
    public async Task Login(string returnUrl = "/")
    {
        var authenticationProperties = new LoginAuthenticationPropertiesBuilder()
            .WithRedirectUri(returnUrl)
            .Build();

        await HttpContext.ChallengeAsync(Auth0Constants.AuthenticationScheme, authenticationProperties);
        var usr = User.Claims.FirstOrDefault(c => c.Type == "name");
    }
    
    [Authorize]
    public IActionResult Profile()
    {
        return View(new
        {
            Name = User.Identity.Name,
            EmailAddress = !string.IsNullOrEmpty(User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)
                ?.Value)
                ? User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)
                    ?.Value
                : User.Claims.FirstOrDefault(c => c.Type == "nickname")
                    ?.Value,
            ProfileImage = User.Claims.FirstOrDefault(c => c.Type == "picture")?.Value
        });
    }
    
    [Authorize]
    public async Task Logout()
    {
        var authenticationProperties = new LogoutAuthenticationPropertiesBuilder()
            .WithRedirectUri(Url.Action("Index", "Home"))
            .Build();

        await HttpContext.SignOutAsync(Auth0Constants.AuthenticationScheme, authenticationProperties);
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    }
}
```

As you are able to see, we created one opened endpoint for login and two closed for enter to the profile and logout. The Profile action will highlight the error that the view doesn't exist. You need to go to the Views folder, create the Account folder, and create the `Profile.cshtml` file.
```html
@{
    ViewData["Title"] = "Profile Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome @Model.Name</h1>
    <img style="align-content: center" src="@Model.ProfileImage"/>
    <p style="text-align: center">@Model.EmailAddress</p>
</div>
```

Actually, we do not need to write code anymore, but I don't want to use a REST client and I decided to implement a login layout. Go to the Views => Shared and create `_LoginPatrial.cshtml` file:

```html
<ul class="navbar-nav">
    @if (User.Claims.FirstOrDefault(c => c.Type == "name") != null)
    {
        <li class="nav-item">
            <img style="width: 30px; height: 30px; margin-top: 5px" src="@User.Claims.FirstOrDefault(c => c.Type == "picture").Value"/>
        </li>
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Profile">Hello @User.Identity?.Name!</a>
        </li>
        <li class="nav-item">
            <form class="form-inline" asp-area="" asp-controller="Account" asp-action="Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">
                <button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
            </form>
        </li>
    }
    else
    {
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Login">Login</a>
        </li>
    }
</ul>
```

And don't forget update `_Layout.cshtml`:
```html
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                <ul class="navbar-nav flex-grow-1">
                    <li class="nav-item">
                        <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                    </li>
                </ul>
                <partial name="_LoginPartial"/>
            </div>
```

##Running and settings
If everything is made correct, your application will run. However if you'll click to log in, you'll get an error like this:

![error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h97rn59li4hl0fgimzw3.png)

It is caused by reason security protection. You need to set a callback that returns after successful authentication. However, there are some pitfalls. In the settings of your application, you should find the Application URIs block and Allowed Callback URLs area. You need to set a URL that ends with the callback key:

![callback](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hbck3xeto2q3mjrqlj5c.png)

For logout set base URL:

![logout](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qecehheydxx1rwyxqnzt.png)

As a bonus, if you decided to change Application Login URI and want to test it locally, you need the necessary set the real IP address of localhost, since Okta doesn't know anything about localhost and it is replaced automatically on your PC form 127.0.0.1 to localhost. For this reason, you need set IP.
And now let's check this out. Run the application and you'll see the start page:

![start](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7v6fffjfj47c8ao9swhn.png)

Try to log in and you'll be redirected to the login page:

![login](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwctsrtt2dcf299exn3h.png)

I entered with a Google account, you can choose different ways. If everything is OK, you'll see this:

![logged](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2h8ni66cn68bfacfcbi2.png)

If you click by name you'll go to the profile page.

![profile](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/94s7k0pwydpwtf59f112.png)

And let's check out the logout, you'll be redirected to the main page and the profile won't be accessible.

![redirected](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ycdlcelqts2npsbovi9f.png)

If you'll try to get to the "Account/Profile" URI, you'll be suggested log in:

![login](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mbggagfk37twavsae5ol.png)

The source code you can find by [link](https://github.com/SergKorol/OktaAuthSample) and sure make subscribes and thank you for reading. I hope it'll be useful for you. Happy coding and see you the next week.

<a href="https://www.buymeacoffee.com/b9z99kntvtQ" target="_blank"><img src="http://dartfordwaffler.co.uk/wp-content/uploads/2021/03/buy-me-a-beer.jpg" alt="Buy Me A Beer" style="height: 60px !important;width: 317px !important;" ></a>