# 9.3 Agregando seguridad a nuestros servicios

Para generar los tokens necesitamos una llave secreta, y los datos del Issuer (quien genera el token) y las urls de las cuales vamos a aceptar la conexión a nuestros servicios.

Vamos a agregar la configuración para generar los tokens en nuestro archivo appsettings.json, de esta forma si luego queremos cambiar los datos para generar los tokens solo debemos reiniciar el servicio. Si lo agregamos en nuestro código por ejemplo en nuestro archivo de constantes debemos de generar la dll y luego reemplazarla en el servidor. Si usas azure devops para generar los deploys automáticamente, puedes agregar constantes en tu código para registrar estos datos. r versión.

{% code title="appsettings.json" %}

```javascript
{
    "Tokens": {
        "Key": "tullavesecreta",
        "Issuer": "http://www.midominio.com/",
        "Audience": "http://sistema.midominio.com/",
        "AceptedURL": [ "http://www.midominio.com/", 
                        "http://midominio.com/" ]
     }
 }

```

{% endcode %}

En nuestro archivo **startup.cs** en el método **ConfigureServices** indicamos que nuestros servicios requieren de seguridad (services.AddAuthentication), en nuestra variable Configuration tenemos acceso a los valores de nuestro archivo appsettings, entre \[] indicamos cuál nodo deseamos y con : nos vamos al siguiente nivel de cada nodo, así si deseamos obtener el valor del valor key, sería Tokens:Key.

Con la opción **TokenValidationParameters**, indicamos cuales validaciones queremos realizar a nuestros tokens, en este caso validamos:

* Que el Issuer y la audiencia sean los valores del archivo appsettings
* Que la llave de cifrado sea la misma de nuestro archivo appsettings&#x20;
* La fecha de caducidad del token.

{% code title="startup.cs" %}

```csharp
public void ConfigureServices(IServiceCollection services)
{
    //Código
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(cfg => 
            {
               cfg.Audience = Configuration["Tokens:Issuer"];
               cfg.Authority = Configuration["Tokens:Audience"];
               cfg.TokenValidationParameters = new           
                                         TokenValidationParameters()
               {
                   //Se va a validar el issuer (Quien genera el token)
                   ValidIssuer = Configuration["Tokens:Issuer"],
                   ValidateAudience = true,
                   //Se va a validar la audiencia que puede usar el token
                   ValidAudience = Configuration["Tokens:Audience"],
                   //Se valida la llave de cifrado
                   ValidateIssuerSigningKey = true,
                   IssuerSigningKey = new SymmetricSecurityKey(
                           Encoding.UTF8.GetBytes(
                                       Configuration["Tokens:Key"]));   
                   //Se validara el tiempo de vida del token
                   ValidateLifetime = true                       
               });
}
```

{% endcode %}

Indicamos a swagger que nuestros servicios requieren token

{% code title="startup.cs" %}

```csharp
public void ConfigureServices(IServiceCollection services)
{
    //Codigo
    services.AddSwaggerGen(c =>
        {
            //Código de swagger
            //Incluimos que vamos a utilizar tokens
            c.AddSecurityDefinition("Bearer", 
                new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization (bearer)",
                    Type = SecuritySchemeType.Http,
                    Scheme = "bearer" 
                });

            c.AddSecurityRequirement(new OpenApiSecurityRequirement{
                    {
                        new OpenApiSecurityScheme{
                            Reference = new OpenApiReference{
                                Id = "Bearer", 
                                Type = ReferenceType.SecurityScheme
                            }
                        },new List<string>()
                    }
                });
     });
```

{% endcode %}

En el servicio de MVC indicaremos que todos nuestros servicios no se van a poder accesar si el usuario no ha iniciado sesión

{% code title="startup.cs" %}

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers(options =>
        {
            options.EnableEndpointRouting = false;
                //Agregamos una politica para indicar que nuestros servicios 
                //requieren que los usuarios hayan iniciado sesión
                var policy = new AuthorizationPolicyBuilder()
                                .RequireAuthenticatedUser()
                                .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
         })
```

{% endcode %}

En el método configure agregamos la autenticación y la autorización

{% code title="startup.cs" %}

```csharp
public void Configure(IApplicationBuilder app)        
{ 
    app.UseAuthentication();
    app.UseAuthorization();
    //Código
}
```

{% endcode %}

Si queremos consultar cualquiera de nuestros servicios recibiremos el estatus 401 Unauthorized


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://abi.gitbook.io/net-core/7.-seguridad/7.7-agregando-seguridad-a-nuestros-servicios.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
