Asp.net core identity external providers only - asp.net-core

I want my Asp.net core application to be configured to use external providers only, let's say Facebook only. In other words I don't want my users to have the ability to create an account with a password etc.
How can I modify the default Asp.net core with individual accounts template that is generated by Visual Studio to safely remove such capability of creating local user accounts?
Thanks.

I'm using the .UseRewriter() middleware to allow me to redirect to /Error for the Identity pages that don't apply to my application (I only allow Github authentication and no local registration)
public static class IisRewriterConfigurationExtensions
{
public static IApplicationBuilder UseIisRewriter(this IApplicationBuilder applicationBuilder)
{
using (var iisUrlRewriteStreamReader = File.OpenText("iis-application-route-rewrites.xml"))
{
var options = new RewriteOptions()
.AddIISUrlRewrite(iisUrlRewriteStreamReader);
applicationBuilder.UseRewriter(options);
}
return applicationBuilder;
}
}
Then I call app.UseIisRewriter(); in Startup.Configure().
My iis-application-route-rewrites.xml looks like this
<?xml version="1.0" encoding="utf-8" ?>
<rewrite>
<rules>
<rule name="Redirect from Identity Forgot Password">
<match url="^Identity/Account/ForgotPassword" />
<action type="Redirect" url="Error?id=404" redirectType="Permanent" />
</rule>
<rule name="Redirect from Identity Reset Password">
<match url="^Identity/Account/ResetPasswordConfirmation" />
<action type="Redirect" url="Error?id=404" redirectType="Permanent" />
</rule>
<!-- More rules -->
</rules>
</rewrites>
In my Login.cshtml.cs I removed all the request handlers that I no longer wanted users to have access to.

Related

Remove response Server header on Azure Web App from the first redirect request to HTTPS

I’m trying to remove the response Server header from an Azure Web App ( with an ASP Net core application )
After many tries of changing the web.config and removing the header in app code using a middleware, Microsoft doesn’t give up and set the response header to Server: Microsoft-IIS/10.0 :)
The problem appears only when I’m trying to access the server on http (not https). Response code from the server is 301, and this is the only response that has the Server header.
Checking the logs I was not able to find any request to http://, and perhaps this is why I’m not able to remove header, because the request is not process in my application code.
A solution that I’m thinking is to disable the azure HTTPS only and do the redirect to https in my code (I tested and is working - server header is removed)
Is there another workaround without disabling the HTTPS only option?
Here is what I tried
Startup.cs
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
context.Response.Headers.Add("server", string.Empty)
}
app.UseHttpsRedirection();
}
web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<httpRuntime enableVersionHeader="false" />
<!-- Removes ASP.NET version header. -->
</system.web>
<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="Server" />
<remove name="X-Powered-By" />
</customHeaders>
<redirectHeaders>
<clear />
</redirectHeaders>
</httpProtocol>
<security>
<requestFiltering removeServerHeader="true" />
<!-- Removes Server header in IIS10 or later and also in Azure Web Apps -->
</security>
<rewrite>
<outboundRules>
<rule name="Change Server Header"> <!-- if you're not removing it completely -->
<match serverVariable="RESPONSE_Server" pattern=".+" />
<action type="Rewrite" value="Unknown" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
UPDATE
When the URL of http:// is requested, IIS will process it, this time without code. So we can't control it by the code, we can only set it on the server, such as some scripts or tools. But on Azure, we have no way to directly operate as a physical server, so after exploration, I suggest that Front Door can be used to deal with this problem. Hiding server information through proxy should be a better way.
After my test, the server information is hidden, you can refer to this document . We can see from the picture that there is no 301 redirect request, and no server information in other requests.
PREVIOUS
You need to modify Global.asax.cs and Web.config file in your program.
In Global.asax.cs.
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
MvcHandler.DisableMvcResponseHeader = true;
PreSendRequestHeaders += Application_PreSendRequestHeaders;
}
protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
{
//HttpContext.Current.Response.Headers.Remove("Server");
HttpContext.Current.Response.Headers.Set("Server","N/A");
}
}
And In Web.config.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" >
</modules>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
</system.webServer>
Then u can deploy your app. After the above code modification, access to the interface or static resources can see that the server information is modified, of course, it can also be deleted by Remove.
You also can handle special event by http status code.
protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
{
//HttpContext.Current.Response.Headers.Remove("Server");
int StatusCode= HttpContext.Current.Response.StatusCode;
// handle like http status code 301
HttpContext.Current.Response.Headers.Set("Server","N/A");
}

Net core api, get parameter with special character

I am trying to receive a parameter by URL, but if this parameter has a '+' I do not receive it, for example:
www.domain.com/api/controller/Demo?guid=123+456
[HttpPost("Demo")]
public IActionResult PostData([FromQuery]string guid, Model model)
{
Inside the function, the guid value is 123 456
if this parameter has a '+' I do not receive it, for example: www.domain.com/api/controller/Demo?guid=123+456. Inside the function, the guid value is 123 456
To achieve your requirement, you can try following approaches:
Approach 1: manually replace the + sign to %2B while client make request to your API action.
Approach 2: encode query string guid=123+456 by using URL Rewriting Middleware, like below.
In Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//...
using (StreamReader iisUrlRewriteStreamReader =
File.OpenText("IISUrlRewrite.xml"))
{
var options = new RewriteOptions()
.AddIISUrlRewrite(iisUrlRewriteStreamReader);
app.UseRewriter(options);
}
//...
}
In IISUrlRewrite.xml
<?xml version="1.0" encoding="utf-8" ?>
<rewrite>
<rules>
<rule name="TESTURL">
<match url="api/your_controller_name/Demo" />
<conditions>
<add input="{QUERY_STRING}" pattern="guid=([0-9]+\+[0-9]+)" />
</conditions>
<action type="Rewrite" url="api/your_controller_name/Demo?guid={UrlEncode:{C:1}}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
Test Result

ASP.NET Core url rewrite only domain

I am trying to change my old domain to new one and I have huge data on my website. I need to change only my domain by url rewriting.
When I request:
www.myolddomain.net/article/seo-friendly-url-for-this-article
I need to have a permanent (301) redirect to:
www.mynewdomain.com/article/seo-friendly-url-for-this-article
How ca I do this in asp.net core?
Have you considered URL Rewriting Middleware?
It's pretty simple.
Drop a IISUrlRewrite.xml file in the root of your application folder. Mark it as "Content" and "Copy to output directory" set to true, looks like this in your csproj
<ItemGroup>
<Content Include="IISUrlRewrite.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
Add following content in the file
<rewrite>
<rules>
<rule name="Host replace - Old to new" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern="www\.myolddomain\.net" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://www.mynewdomain.com{REQUEST_URI}" redirectType="Permanent" appendQueryString="true" />
</rule>
</rules>
</rewrite>
Register the URL rewrite module in the Configure method of your Startup.cs file
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Irrelevant code omitted
using (var iisUrlRewriteStreamReader = File.OpenText(Path.Combine(env.ContentRootPath, "IISUrlRewrite.xml")))
{
var options = new RewriteOptions().AddIISUrlRewrite(iisUrlRewriteStreamReader);
app.UseRewriter(options);
}
// Irrelevant code omitted
}

How to manage url routing in mvc4?

I’m working on url routing
I want to redirect page without change url.
When type url www.example.com/Default.aspx that time url show as same but return page Home/Index (Controller/Action)
I want to redirect page with actual url.
And second require is when type www.example.com/Default.aspx that time show url in address bar Home/Index and return this page
How to possible please describe in details.
Thank you in advance.
I think that the cleanest way of doing this is to use the URL Rewrite module in IIS. However, as you asked about doing it in MVC I'll cover that first:
To achieve 1 (when /default.aspx is requested return /home/index.
Add the following to your route table:
routes.MapRoute("HomepageDefault", "default.aspx", new { controller = "Home", action = "Index" });
To achieve 2, you need to redirect the request - easiest way to do this will be to set a route up to an actionresult, and then redirect it:
routes.MapRoute("RedirectRoute", "default.aspx", new { controller = "Home", action = "Redirect" });
And then in the ActionResult:
public ActionResult Redirect()
{
return RedirectToAction("Index", "Home");
}
The alternative is to do this with the URL Rewrite Module in IIS.
To achieve 1:
<rewrite>
<rules>
<rule name="Rewrite rule">
<match url="^default.aspx$" />
<action type="Rewrite" url="/home/index" />
</rule>
</rules>
</rewrite>
To achieve 2:
<rewrite>
<rules>
<rule name="redirect">
<match url="^default.aspx$" />
<action type="Redirect" url="/home/index" />
</rule>
</rules>
</rewrite>

IIS Virtual Directory/Application & Forms authentication

I've setup and deployed a simple forms authentication website with membership using .NET 4.
I've created a virtual directory (now converted to "Application") in IIS7 and setup the web.config file in the virtual directory as follows:
<configuration>
<system.web>
<authorization>
<deny users="?">
</authorization>
</system.web>
<system.webServer>
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
Great! I browse to the virtual directory: ../mydomain/books/
and I'm automatically redirected to the login page specified by web.config in my root directory and the url path is placed as follows:
../Account/Login.aspx?ReturnUrl=%2fbooks
At this point, I login succesfully, but I am not redirected anywhere, and when I manually return to the directory, ../books, I'm sent back to the login page, where I'm already logged in?
So I'm confused about what my problem is! I should be successfully authenticated, and than redirected back to the directory, or at the very least be able to view it manually after I log in right?
Since I had to solve this myself, I thought I may as well post it for others in case their search brings them here.
This is everything you'll need to use Forms Authentication, allow your formatting to be exposed to anonymous users, pass credentials between an existing .Net (.aspx) web site and an MVC web application and redirect to a given url after login.
Use whatever pieces you are looking for.
Make sure your Virtual Directory/Virtual Application path for your .Net web application (.aspx) is outside of the Views directory. Also make sure you set up your Virtual Directory/Application in IIS.
I used Entity Framework and Identity with a SQLServer database to validate my users.
Your Virtual Application/Directory .Net (.aspx) web.config file needs to contain this:
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<!-- other stuff -->
<system.web>
<authentication mode="Forms">
<forms
loginUrl="login.aspx"
name=".AUTHCOOKIE"
protection="All"
path="/"
domain="your_domain.com"
enableCrossAppRedirects="true"
timeout="60">
</forms>
</authentication>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
<machineKey
validationKey="your validation key"
decryptionKey="your decryption key"
validation="SHA1"
decryption="AES"
/>
<!-- other stuff -->
</system.web>
<location path="/path/to/your/site.css">
<system.web>
<authorization>
<allow users="?"></allow>
</authorization>
</system.web>
</location>
<!-- other stuff -->
</configuration>
Then, in the code behind your login.aspx page you'll need something like this:
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
string username = Login1.UserName;
string pwd = Login1.Password;
/* do your authentication here
connect to user store
get user identity
validate your user
etc
*/
if (user != null)
{
FormsAuthentication.SetAuthCookie(username, Login1.RememberMeSet);
System.Web.HttpCookie MyCookie = System.Web.Security.FormsAuthentication.GetAuthCookie(User.Identity.Name.ToString(), false);
MyCookie.Domain = "your_domain.com";
Response.AppendCookie(MyCookie);
Response.Redirect("~/path/to/your/index.aspx");
}
else
{
StatusText.Text = "Invalid username or password.";
LoginStatus.Visible = true;
}
}
Now, in your MVC applications web.config file add this:
<configuration>
<!-- other stuff -->
<system.web>
<authentication mode="Forms">
<forms
loginUrl="Account/Login"
name=".AUTHCOOKIE"
protection="All"
path="/"
domain="your_domain.com"
enableCrossAppRedirects="true"
timeout="30"/>
</authentication>
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
<machineKey
validationKey="your validation key"
decryptionKey="your decryption key"
validation="SHA1"
decryption="AES"
/>
<!-- other stuff -->
</system.web>
<location path="/path/to/your/site.css">
<system.web>
<authorization>
<allow users="?"></allow>
</authorization>
</system.web>
</location>
<!-- other stuff -->
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="FormsAuthenticationModule"/>
<add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule"/>
<remove name="UrlAuthorization"/>
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/>
</modules>
</system.webServer>
<!-- other stuff -->
</configuration>
In your MVC AccountController Login method should look something like this:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
/* do your authentication here
connect to user store
get user identity
validate your user
etc
*/
if (user != null)
{
await SignInAsync(user, model.RememberMe);
FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
System.Web.HttpCookie MyCookie = System.Web.Security.FormsAuthentication.GetAuthCookie(User.Identity.Name.ToString(), false);
MyCookie.Domain = "your_domain.com";
Response.AppendCookie(MyCookie);
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Finally, your MVC AccountController log off method is this:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
AuthenticationManager.SignOut();
FormsAuthentication.SignOut();
return RedirectToAction("Login", "Account");
}
You need to add code to redirect to the "ReturnUrl" URL noted in the query string from within your Login page after you login.