Posted on

Token based authentication in ASP.NET Web API

Token based authentication

Nella “Token based authentication”, l’applicazione client invia prima una richiesta all’endpoint del server di autenticazione con le credenziali dell’utente; se il nome utente e la password sono corretti, il server di autenticazione invia un token al client come risposta. Questo token contiene dati sufficienti per identificare un determinato utente e un tempo di scadenza. L’applicazione client utilizza quindi il token per accedere alle risorse nelle richieste successive fino a quando il token risulta ancora valido (non scaduto).

Classe per validare le richieste del client

Aggiungete una classe come questa :

using Microsoft.Owin.Security.OAuth;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity.Owin;


namespace Mysite.Helpers
{
    public class MysiteAuthorizationServerProvider : OAuthAuthorizationServerProvider
    {
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated(); // 
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
            var user = await userManager.FindAsync(context.UserName, context.Password);
            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }
            ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
            OAuthDefaults.AuthenticationType);

            context.Validated(oAuthIdentity);
        }
    }
}

Per attivare questa classe andate nel file App_Start/Startup.Auth.cs e aggiungete alla fine del metodo ConfigureAuth questo codice

var myProvider = new  MysiteAuthorizationServerProvider();
            OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions
            {
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = myProvider
            };
            app.UseOAuthAuthorizationServer(options);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

In cui si definisce il link http://mysite/token che restituisce un token di durata 1 giorno.

Dovrete aggiungere nel file il riferimento

using Microsoft.Owin.Security.OAuth;

E’ necessario aggiungere un metodo all’autenticazione. Andate nel file IdentityModel.cs e aggiungete questo metodo :

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager,
            string authenticationType)
        {
           var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
           return userIdentity;
        }

TEST CON POSTMAN

Per testare il tutto facilmente potete usare Postman .

Dovrete creare con Postman una chiamata post sul vostro link http://mysite/token. Nell’headers inserite la dicitura che vedete in figura :

Nel Body inserite il tipo di autneticazione (password) il vostro username e la vostra password.

Spingete “Send”. Se tutto ha funzionato riceverete il token

Utilizzo del Token

Una volta che il client ha ricevuto il token lo può utilizzare per tutte le successive operazioni senza dover passare lo username e la password: va passato solo il token che contiene queste informazioni. Facciamo una prova, creando un metodo che richiede autenticazione all’interno di un controller :

using System;
using System.Web.Http;

namespace MySite.Controllers
{
    public class SampleController : ApiController
    {
       [Authorize]
        [HttpGet]
        public IHttpActionResult GetForAuthenticate()
        {
            var identity = (ClaimsIdentity)User.Identity;
            return Ok("Hello " + identity.Name);
        }
   }
}

Usando postman, fate una chiamata GET al link : http://MySite/api/Sample/GetForAuhenticate

Dovrete passare al link il token che avete ottenuto qualche istante prima (nel nostro esempio è valido per 1 giorno). Per farlo in postman aggiungete la chiave Authorization con valore la parola Bearer seguita dal token.

THE END

Posted on

add Web API to an asp.net mvc site

Install the Web API Client Libraries

Use NuGet Package Manager to install the Web API Client Libraries package :

  • Microsoft.AspNet.WebApi.Client
  • Microsoft.AspNet.WebApi.Core
  • Microsoft.AspNet.WebApi.WebHost

Define a Web API Routing Configuration

Add App_Start\WebApiConfig.cs

using System.Web.Http;

class WebApiConfig
{
    public static void Register(HttpConfiguration configuration)
    {
        config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
    }
}

Register the WebAPI Routing Configuration

If you added a new WebApiConfig.cs file, you need to register that on your Web Application’s main configuration class.

Import namespace System.Web.Http in Global.asax.cs.

Add this line before the registration of your classic routing

//api routing (before)
GlobalConfiguration.Configure(WebApiConfig.Register);
//existing normal route
RouteConfig.RegisterRoutes(RouteTable.Routes);

Create a sample Web API Controller

Create a new controller

using System;
using System.Web.Http;

namespace MySite.Controllers
{
    public class SampleController : ApiController
    {
       [HttpGet]
       public String Test()
       {
         return "Hello World!";
       }
   }
}

Based on the api routing you should call this method in your browser using

http://MySite/api/Sample/Test

with this result

<string xmlns=”http://schemas.microsoft.com/2003/10/Serialization/”>Hello World!</string>

Posted on

Android java app with notification from asp.net mvc using firebase cloud messaging – part 3

Notification service in Android

Now we need to create in Android the service able to manage the notification incoming from firebase and to show these to user. Follow this usefull article Working easily with FCM push notifications in Android. You’ll have a class like this.

package com.mycompany.myfirstapp;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import androidx.core.app.NotificationCompat;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import androidx.core.app.NotificationManagerCompat;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;

//is the class that we can find in the manifest as a service

public class MyFirebaseMessagingService extends FirebaseMessagingService {

public static final String TAG = "MsgFirebaseServ";

@Override


public void onMessageReceived(RemoteMessage remoteMessage) {
  super.onMessageReceived(remoteMessage);

  String title = "";
  String body = "";
  String objectId = "";
  String objectType = "";

  if (remoteMessage.getData() != null) {
  title = remoteMessage.getData().get("title");
  body = remoteMessage.getData().get("body");
  objectId = remoteMessage.getData().get("object_id");
  objectType = remoteMessage.getData().get("objectType");
  }

 Notification notification = new NotificationCompat.Builder(this)
   .setContentTitle(title)
   .setContentText(body)
   .build();
   NotificationManagerCompat 
manager = NotificationManagerCompat.from(getApplicationContext()); manager.notify(/*notification id*/0, notification); } }

Run your app on your device

Follow this instruction : https://developer.android.com/training/basics/firstapp/running-app

First test using your app in your device

  • Run the app on your device or emulator. The app should had created a new register id for the device and send it to asp.net mvc site. Now the device is registered.
  • Open Firebase console, go down in the menu on the left. Open Cloud Messaging session : you should find the possibility to send notification to your device starting from this page. So you can test correct developing of above class.

Send notification from asp.net mvc to firebase

For backend developers. You should create a class to manage notification to firebase. Follow the article Firebase push notifications using a .NET Backend to prepare a class to manage the notification to Firebase.

Then prepare your notification test task in a controller. Something like this :

public Task<bool> NoteAsync()
{
 var device = db.RegisteredDevices.Where(d => d.ENABLED == true);
 string[] da = new string[device.Count()];
 int i = 0;
 foreach (RegDevice r in device)
 {
  da[i] = r.ID;
  i++;     
 }
  string serverkey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
return FCMPushNotification.SendPushNotification(da,serverkey,
"Title","body"); }

Firebase messaging, where to get Server Key?

Click the Settings (Cog wheel) icon next to your project name at the top of the new Firebase Console, as per screenshot below:

  1. Click Project settings.
  2. Click on the Cloud Messaging tab.

 


Final test

Call the asp.net mvc method created. You should see a notification in your device.


Android java app with notification from asp.net mvc using firebase cloud messaging – part 1

Android java app with notification from asp.net mvc using firebase cloud messaging – part 2

Links



Posted on

ASP.NET MVC: PUBBLICAZIONE DI UN SITO

Visual Studio ci consente di pubblicare il nostro sito web su un web server interno (intranet) o su un web server esterno, per esempio ospitato su Azure.

Nel caso di un server in lan, su un web server avete creato tramite IIS un sito che risiede su una certa directory per adesso vuota. Altrimenti avete già pronto un sito esterno.

In Visual Studio, nel pannello a destra chiamato “Solution Explorer” facciamo click con il tasto destro del mouse sul nostro progetto e selezioniamo l’opzione “Publish“. Si apre la finestra “Publish” che riporta a sinistra i 4 step da fare per la pubblicazione.

Profile

Andate sul menu a tendina in alto al centro  e scegliete “New Custom Profile”. Inventatevi il nome di questo profilo. Una volta inserito, passerete direttamente allo step successivo.

Connection con il metodo “Web Deploy”

Publish Metod : scegliere Web Deploy sia che si pubblichi il sito in un server in lan, sia in un server esterno.

Server (web server in lan) : http://myserver

Server (esterno, per esempio Azure): mysite.azurewebsites.net:443

Site name (web server in lan) : nome della directory in cui deve risiedere il sito

Site name (esterno, per esempio Azure) : nome che avete dato al sito (mysite)

User Name e Password (web server in lan) : mettere uno username amministratore della macchina server. Se la macchina è in dominio usare un Amministratore locale.

User Name e Password (esterno) : ftp user

Destination Url : indirizzo del sito web. es : http://……………..

Settings

In questa tab il programma legge dal we.config le stringhe di connessione al database. Se nel vostro sito di destinazione il database è diverso, dovete specificare la giusta connessione. La pubblicazione sostituira le stringhe di destinazione alle stringhe di origine. Vedremo in seguito che esiste un metodo per inserire nel web.config ulteriori variazioni rispetto al web.config di origine.

Preview

Qui potete vedere i file che saranno inviati alla destinazione cioè i nuovi o  i modificati dopo l’ultimo invio. E potete pubblicare!


Configurazione del web.config

Il nostro sito web di destinazione può avere altre caratteristiche particolari, specificate nel web.config, diverse dal sito di partenza, oltre alle stringhe di connessione al database.
Ci possiamo creare un web.config specifico per ogni deploy.

Andate sul progetto. Nelle “Proprietà”, trovate la directory “PublishProfiles” che contiene i dati salvati precedentemente. Trovate un file .pubxml per ognuno dei deploy che avete creato. Andate su file che vi interessa, spingete il tasto destro del mouse e selezionate “Add Config Transform”.

Se andate nel web.config vedrete che esiste un file aggiuntivo che si chiama come il vostro deploy.  Vediamo alcuni esempi di quello che potete fare con tag che inserirete all’interno di <configuration>

<connectionStrings>
 <add name="MyDB"
 connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
 xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
 </connectionStrings>

Questa stringa sostituisce (xdt:Transform=”SetAttributes”) gli attributi del tag che si chiama (xdt:Locator=”Match(name)) “MyDB” con quelli che trova qui.

<appSettings><add key="myemail" value="info@contoso.com" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/></appSettings>

Questa stringa sostituisce gli attributi (xdt:Transform=”SetAttributes”) del tag che ha come key (xdt:Locator=”Match(key)) “myemai” con quelli che trova qui.

<system.net>
 <mailSettings xdt:Transform="Replace">
 <smtp deliveryMethod="Network" ........................
 </smtp>
 </mailSettings>
 </system.net>

Questa stringa trasforma (xdt:Transform=”Replace”) tutto il tag mailSettings ed il suo contenuto.

Posted on

ASP.NET MVC EMAIL DA SITO E PASSWORD DIMENTICATA

Il nostro sito ha necessità di inviare email ai suoi utenti, per esempio quando l’utente si dimentica la password di accesso. Per fare questo ci viene in soccorso la classe System.Net.Mail.SmtpClient.

Questa classe usa in automatico le impostazioni del smtp server memorizzate nel file Web.config. E’ sufficiente aggiungere a questo file i seguenti tag all’interno del configuration :

<system.net>
 <mailSettings>
 <smtp deliveryMethod="Network" from="mail_from">
 <network host="my_smtp_server" port="my_smtp_server_port" userName="user_name_smtp" password="password" clientDomain="my_domain" />
 </smtp>
 </mailSettings>
 </system.net>

PASSWORD DIMENTICATA

Nella view Account/Login , vedete in basso a sinistra il link a Account/ForgotPassword che è la pagina che permette all’utente il reset della password

Andate nel controller Account, nell’action post chiamata “ForgotPassword” e rendete operative, rimuovendole come commento, le linee di codice dedicate al recupero password.

Andate nel file IdentityConfig.cs, nella funzione

public Task SendAsync(IdentityMessage message)

e sostituite alla riga

return Task.FromResult(0);

le seguenti righe di codice

var sentFrom = "myemail@mydomain.com"
 //
 System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
 //
 client.EnableSsl = false;

// Create the message:
 var mail =
 new System.Net.Mail.MailMessage(sentFrom, message.Destination);

mail.Subject = message.Subject;
 mail.Body = message.Body;
 mail.IsBodyHtml = true;

// Send:
 return client.SendMailAsync(mail);

Avete attivato il recupero password

Posted on Lascia un commento

ASP.NET MVC LINQ MIGLIORATO

Linq è un elemento introdotto nel Framework 3.5. Attraverso di esso è possibile fare interrogazioni su liste, collezioni, tabella di database, file xml usando una notazione molto simile al linguaggio SQL.

Ritorniamo per esempio alla nostro modello Student.

[Table("STUDENTS")]
 public class Student
 {
 public int ID { get; set; }
 public string NAME { get; set; }
 public string SURNAME { get; set; }
 public int AGE {get;set;}
 }

Nel nostro context abbiamo l’istanza alla tabella

public DbSet<Student> Students { get; set; }

Attraverso Linq, possiamo chiedere :

var list = context.Studens.Where(s => s.NAME.StartsWith("M") and s.AGE > 18).OrderBy(s => s.SURNAME)

Il linguaggio Linq è lo strumento con cui il context, base dell’ASP.NET MVC, interroga il nostro database. Però Linq, a nostro avviso, proprio quando si lavora con le tabelle di un database ha dei limiti rispetto a SQL. Come vedete, la query sopra è preimpostata : cioè esiste un filtro sulla proprietà NAME e uno sulla AGE e un ordinamento sulla proprietà SURNAME. Questa base di dati sarà sempre ordinata così e al massimo potremo variare la query agendo sulla stringa “M”  e sul numero 18.

Le nostre query però sono variabili in genere. Immaginate di avere una griglia con colonne riordinabili. Usando linq dovreste gestire una query diversa per ognuna delle proprietà che possono essere ordinate ed inoltre dovreste gestire il verso. E se voleste mettere dei filtri ? Dovreste creare delle query in sequenza che, piano piano, filtrano i dati : una per la prima proprietà, uno per la seconda, etc.

Un pò scomodo.

A questo proposito ci viene in soccorso la libreria System.Linq.Dynamic https://github.com/kahanu/System.Linq.Dynamic

che ci permette di fare domande come :

var list = context.Studens.Where("NAME = \"JOHN\" and AGE >= 18 and  AGE <= 34").OrderBy(SURNAME asc, NAME)

Addio Linq , Grazie SQL.

Posted on Lascia un commento

ASP.NET MVC: Risolvere i problemi di jQuery UI per Datapicker

In questo articolo spiegheremo come risolvere i problemi nell’utilizzo del Datapicker di jQuery UI all’interno dell’ambiente ASP.NET MVC (Model-View-Controller).

MVC effettua le chiamate ai vari file .js di  jQuery tramite il file BundleConfig.cs, presente all’interno della direcoty “App_Start“, questa modalità, configurata di default alla creazione di un progetto ASP.NET MVC, presenta purtroppo una limitazione nell’integrazione di tutte le funzionalità offerte da jQuery e jQuery UI, utili ad esempio per l’utilizzo del Datapicker (un comodo calendario per la selezione delle date, utile soprattutto in quanto ad oggi non tutti i browser – vedi Firefox – utilizzano l’imput type date secondo gli standard HTML 5).

Se con l’aggiunta di jQuery UI tramite lo strumento NuGet offerto da Visual Studio non dovessero funzionare tutte le funzionalità di jQuery UI potete procedere in questo modo:

dalla pagina _Layout.cshtml commentare la riga

@Scripts.Render("~/bundles/jquery")

che serve a caricare i file jQuery trmite il file BundleConfig.cs.
La nostra riga apparirà di conseguenza in questo modo

@*@Scripts.Render("~/bundles/jquery")*@

Ora posizionamoci all’interno del tag <head> ed effettuiamo le chiamate ai nostri file .js emplicemente trascinandoli dall’esplora soluzioni di VisualStudio.

Otteremo cosi gli include degli script necessari al corretto funzionamento di jQuery e jQuery UI:

<script src="~/Scripts/jquery-1.12.4.js"></script>
 <script src="~/Scripts/jquery-ui.js"></script>
 <link href="~/Content/jquery-ui.css" rel="stylesheet" />
 <script src="~/Scripts/datepicker-it.js"></script> @*Localizzazione per jquery ui*@

Ora possiamo utilizzare il nostro Datapicker senza problemi su tutti i browser in questo modo:

<input type="text" id="datepicker">

<script>
 $( function() {
 $( "#datepicker" ).datepicker();
 } );
 </script>
 </script>

Et voilà! Come per magia ora funziona tutto!

Posted on Lascia un commento

ASP.NET MVC: PERMESSI E RUOLI

Mediante i ruoli, posso decidere cosa può essere o meno fatto da un utente. Per esempio possiamo decidere di far vedere un pezzo di menu solo agli utenti con un certo ruolo. Nel file _Layout.cshtml, nella parte di menu, avremo una voce visibile solo se l’utente ha un ruolo “Admin” :

@if (User.IsInRole("Admin"))
 {
 <li>@Html.ActionLink("General Manag., "Index", "DB")</li> }

In questo modo l’utente non si trova il menu che porta alla Action “Index” del Controller “DB”. Però potrebbe sempre conoscere l’indirizzo e digitarlo (http://mysite.com/DB/Index)

Per evitare che l’utente acceda a contenuti protetti, possiamo agire direttamente sul Controller. Per esempio possiamo impedire l’accesso a chi non ha effettuato il login al sito

[Authorize]
 public class AccountController : Controller
 {

Oppure, deve aver effettuato l’accesso ed avere un certo Ruolo :

[Authorize(Roles = "Admin")]
 public class AccountController : Controller
 {

Per altre informazioni sui permessi, vedi il manuale Microsoft

 

Posted on Lascia un commento

ASP.NET MVC: APPSETTINGS

Vogliamo introdurre nel nostro sito alcune variabili che dovranno essere utilizzate in diversi punti del codice. Per esempio il nome del sito.

Andiamo nel web.config nella sezione

<configuration> <appSettings>

e inseriamo un nuovo tag, per esempio :

<add key="SiteName" value="My First Site in ASP" />

A questo, punto per esempio nel file

_Layout.cshtml, al posto della voce che mostra il titolo del sito

 @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })

potete mettere,

 @Html.ActionLink(System.Configuration.ConfigurationManager.AppSettings["SiteName"].ToString(), "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })

In cui vedete proprio l’uso della classe/funzione necessaria a recuperare i dati dal web.ConfigSystem.Configuration.ConfigurationManager.AppSettings

 

 

 

Posted on Lascia un commento

ASP.NET MVC : GESTIONE UTENTE E RUOLI E ACCESSO

Nelle lezioni precedenti abbiamo visto le tabelle create dall’Entity Framework per gestire utenti e ruoli. Avete registrato un utente ed eseguito un login. Facciamo qualche personalizzazione.

Regole delle password.

Potete cambiare tali regole nel file IdentityConfig.cs nella directory App_Start. Nella funzione Create della classe ApplicationUserManager, trovate :

//REGOLE DI COSTRUZIONE PASSWORD
 manager.PasswordValidator = new PasswordValidator
 {
     RequiredLength = 6,
     RequireNonLetterOrDigit = false,    //RequireNonLetterOrDigit = true,
     RequireDigit = false, 
//RequireDigit = true,
     RequireLowercase = false, 
//RequireLowercase = true,
     RequireUppercase = false, 
//RequireUppercase = true,
 };

Potete vedere un impostazione meno restrittiva delle password. Commentati vi vedete i valori di sicurezza di default.


Inserimento di Ruoli e Utenti via codice.

Il nostro obbiettivo e quello che il programma crei per noi i ruoli che andremo a gestire nel database e anche un utente “nostro”, senza dover effettuare una prima registrazione.:un nostro utente amministratore creato in automatico.

Nel file Startup.cs troviamo una classe eseguita alla partenza dell’applicazione.

public partial class Startup
 {
    public void Configuration(IAppBuilder app)
   {
        ConfigureAuth(app);
   }
 }

In questa funzione, inseriamo anche la chiamata ad una nostra funzione createRolesandUsers();

private void createRolesandUsers()
 {
 ApplicationDbContext context = new ApplicationDbContext();
 
 var roleManager = new RoleManager<IdentityRole>(new     RoleStore<IdentityRole>(context));
 var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));

// In Startup iam creating first Admin Role and creating a default Admin User
 if (!roleManager.RoleExists("Admin"))
 {

// first we create Admin rool
 var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
 role.Name = "Admin";
 roleManager.Create(role);

//Here we create a Admin super user who will maintain the website 
 var user = new ApplicationUser();
 user.UserName = "myUser";
 user.Email = "myuser@mcontoso.com";

string userPWD = "123456789";
 var chkUser = UserManager.Create(user, userPWD);

//Add default User to Role Admin
 if (chkUser.Succeeded)
 {
 var result1 = UserManager.AddToRole(user.Id, "Admin");
 }
 }
 // creating Creating Manager role
 if (!roleManager.RoleExists("Teacher"))
 {
    var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
   role.Name = "Teacher";
 roleManager.Create(role);
 }

// creating Creating Employee role
 if (!roleManager.RoleExists("Student"))
 {
 var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
 role.Name = "Student";
 roleManager.Create(role);
 }
 }

Lanciate l’applicazione e vedrete che potrete loggarvi con l’utente creato via codice.

Per una trattazione molto più dettagliata consiglio l’ottimo articolo di Syed Shanu su Code Project