Install the .NET Core Hosting Bundle on Windows Server
The .NET Core Hosting bundle is an installer for the .NET Core Runtime and the ASP.NET Core Module. The bundle allows ASP.NET Core apps to run with IIS.
(for this test we installed version .Net Core 8 on win 2012r2)
Visual Studio : Publish on Folder
After creating the ASP.NET Core application in Visual Studio, we can use the Visual Studio Publish Tool to deploy and run our app. For this project, choose to publish to a folder. Choose the folder and hit “Finish”.
In the next screen, where you see the settings for this deploy, click on “More Actions” and then on “Edit”.
Select :
Deployment Mode : Complete
Target Runtime : win-x64 (for our server)
File Publish Options : Delete all existing files prior to publish (flagged)
Database : Default Connection edit (if yuu need it)
Save this configuration, control it an Publish.
Copy the contents of the folder on the IIS server to the folder dedicated to the new site.
IIS and new site
Create the site on IIS. For the Application Pool you have to use default .NET CLR Version : v4.0.
Open your browser and call up the site. You receive the “page not found” error (404).
Remember that a site that hosts only calls web api. To verify that it works you can use the controller that Visual Studio sets by default when creating a site. Then type:
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.
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
In this scenario we looking to send the device registration id to a server with user data to save it in our database.
Token based authentication in ASP.NET Web API
For backend developers. ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients. Follow the following article in order to implement Token based authentication using ASP.NET Web API 2. (Part 1 : Token based authentication in ASP.NET Web API)
To register the device you need a method like this
For frontend developers. To authenticated in a asp.net mvc site, first of all you have to generate the token using the username and the password. The token will conserve all the user’s data more the validation time. We will use this token to talk to our server.
Getting a token is not a goal per se. It’s a necessary step to call a protected API. The token needs to be used to access a Web API. The way to do it is by setting the Authorization header to be “Bearer”, followed by a space, followed by the access token.
To generate the token you should use something like this :
Important steps : Add Firebase using the Firebase console. After you have a Firebase project, you can add your Android app to it. Enter your app’s package name in the Android package name field. Click Download google-services.json to obtain your Firebase Android config file google-services.json)
Make sure that your app meets the following requirements:
Targets API level 16 (Jelly Bean) or later
Uses Gradle 4.1 or later
In Android Studio create a new android app using java as language. To enable Firebase products in your app, pass to Project visualization (on the left of android studio) in your root-level Gradle file (build.gradle), add rules to include the Google Services Gradle plugin. Check that you have Google’s Maven repository, as well.
buildscript {
repositories {
// Check that you have the following line (if not, add it):
google() // Google's Maven repository
}
dependencies {
// ...
// Add the following line:
classpath 'com.google.gms:google-services:4.3.3' // Google Services plugin
}
}
allprojects {
// ...
repositories {
// Check that you have the following line (if not, add it):
google() // Google's Maven repository
// ...
}
}
In your module (app-level) Gradle file (usually app/build.gradle), apply the Google Services Gradle plugin:
apply plugin: 'com.android.application'
// Add the following line:
apply plugin: 'com.google.gms.google-services' // Google Services plugin
android {
// ...
}
To your module (app-level) Gradle file (usually app/build.gradle), add the dependencies for the Firebase products that you want to use in your app.
dependencies {
// ...
// Add the SDKs for the Firebase products you want to use in your app
// For example, to use Firebase Authentication and Cloud Firestore
implementation 'com.google.firebase:firebase-analytics:17.2.0'
implementation 'com.google.firebase:firebase-messaging:20.1.0'
// Getting a "Could not find" error? Make sure that you've added
// Google's Maven repository to your root-level build.gradle file
}
Sync your app (at the top on the right of Android Studio) to ensure that all dependencies have the necessary versions.
Set up a Firebase Cloud Messaging client app on Android
Edit your app manifest. A service that extends FirebaseMessagingService. This is required if you want to do any message handling beyond receiving notifications
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mycompany.myfirstapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
tools:ignore="GoogleAppIndexingWarning">
<!-- [START fcm_default_icon] -->
<!-- Set custom default icon. This is used when no icon is set for incoming notification messages. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming notification message. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
<!-- [END fcm_default_icon] -->
<!-- [START fcm_disable_auto_init] -->
<meta-data
android:name="firebase_messaging_auto_init_enabled"
android:value="false" />
<meta-data
android:name="firebase_analytics_collection_enabled"
android:value="false" />
<!-- [END fcm_disable_auto_init] -->
<activity
android:name=".EntryChoiceActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- [START firebase_service] -->
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- [END firebase_service] -->
</application>
</manifest>
Access the device registration token
On initial startup of your app, the FCM SDK generates a registration token for the client app instance.
private void GetRegistrationToken()
{
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
@Override
public void onComplete(@NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w(TAG, "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String token = task.getResult().getToken();
regToken = token;
System.out.println("***************");
System.out.println(token);
//
// Log and toast
String msg = getString(R.string.msg_token_fmt, token);
Log.d(TAG, msg);
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
//
new Thread(){
public void run(){
try {
//SEND REGISTRATION TOKEN TO BACKEND SERVER
catch (Exception e) {
e.printStackTrace();
}
}
}.start();
//
}
});
}
As you can see above, after get the registration id you need to pass this to your backend server. In this way you will be able to save this data linking it to your user to permit, in the future, to send message only to selected users.
You may need to access your developing site with Visual Studio from another device, for example if you want to test if the site is really responsive. You just need to make some changes.
When you open your site by visual studio, the address displayed is
http://localhost:port_number
, where port_number is the port number assigned to the project by Visual studio / IISExpress.
In your project directory you find the .vs directory. Open the file
Now you can see the IISExpress website from any networked device using
http://192.168.1.142:60132/
Unfortunately, with this operation you’ll no more control the site using http://localhost:60132 because you need administrator privilege to use the port 60132. So you have two possibilities : first open Visual Studio with Administrator privileges; second, delete this acl: