When I have the following key in my web.config, umbraco preview is working fine, showing me the correct content but I can not login to my web site, I can login to umbraco backoffice without any problem.
When I comment out the following key, then I can login to my web site but this time umbraco preview is not showing the correct content.
What should I do to make preview work and at the same time I can login to my front end site? I have already searched for a solution, but I haven't managed to fix this so far. Any help is appreciated.
Umbraco version 7.4.3 assembly: 1.0.5948.18141
The key:
<add key="owin:appStartup" value="UmbracoDefaultOwinStartup" />
My OwinStartup class:
[assembly: OwinStartup(typeof(OwinStartup), "Configuration")]
namespace ABC.XYZ.Site
{
public class OwinStartup : UmbracoDefaultOwinStartup
{
public override void Configuration(IAppBuilder app)
{
base.Configuration(app);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions());
app.Use((context, next) =>
{
var loggedInMarkerCookie = context.Request.Cookies[Settings.CookieLoggedInMarkerName];
var autoLoginAttempt = context.Request.Cookies[Settings.CookieLoggedInMarkerAttemptName];
if (!context.Authentication.User.Identity.IsAuthenticated && !context.Request.Path.Value.StartsWith("/sso/") && (loggedInMarkerCookie != null && autoLoginAttempt == null))
{
context.Response.Cookies.Append(Settings.CookieLoggedInMarkerAttemptName, DateTime.Now.ToString(), new CookieOptions { Expires = DateTime.Now.AddMinutes(30) });
context.Authentication.Challenge();
}
return next.Invoke();
});
}
}
}
Your App Setting needs to be:
<add key="owin:appStartup" value="ABC.XYZ.Site, OwinStartup" />
And looking at the source I think that you need to call base.Configuration(app); after you've added your custom configuration.
Related
I created an ASP.NET Core 2 projects with razor pages and I would like to give the opportunity to the visitor to select a language. The first problem that I had was to change the web application url so that ti will include the current language code. I solved this problem by adding the following code in ConfigureServices.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeFolder("/Account/Manage");
options.Conventions.AuthorizePage("/Account/Logout");
options.Conventions.AddFolderRouteModelConvention("/", model =>
{
foreach (var selector in model.Selectors)
{
var attributeRouteModel = selector.AttributeRouteModel;
attributeRouteModel.Template = AttributeRouteModel.CombineTemplates("{language=el-GR}", attributeRouteModel.Template);
}
});
});
}
}
Now I could visit a page using the following URL:
http://domain/el-GR/MyPage
The last thing that I would like to do is to change the culture of each request. The best solution that I fount which I do not like is to put the following code in my page:
System.Globalization.CultureInfo.CurrentCulture = new System.Globalization.CultureInfo((string)RouteData.Values["language"]);
System.Globalization.CultureInfo.CurrentUICulture = new System.Globalization.CultureInfo((string)RouteData.Values["language"]);
This is not nice because I will have to add these lies in every razor page that I will create in my project.
Is there another way to set the culture for all the requests of my web application?
Refer to this article: https://joonasw.net/view/aspnet-core-localization-deep-dive
There are a few methods, I use the RequestCultureProviders.
NuGet: Microsoft.AspNetCore.Localization
in my Startup.Configure method.
IList<CultureInfo> sc = new List<CultureInfo>();
sc.Add(new CultureInfo("en-US"));
sc.Add(new CultureInfo("zh-TW"));
var lo = new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
SupportedCultures = sc,
SupportedUICultures = sc
};
var cp = lo.RequestCultureProviders.OfType<CookieRequestCultureProvider>().First();
cp.CookieName = "UserCulture"; // Or whatever name that you like
app.UseRequestLocalization(lo);
Set your cookie "UserCulture" to "c=zh-TW|uic=zh-TW" once.
And it works magically.
Authentication fails to authenticate for forms authentication in my MVC 5 application. Page gets redirected correctly, but User.Identity.IsAuthenticated and User.Identity.Name values are empty.
My webconfig,
<system.web>
<authentication mode="Forms">
<forms cookieless="UseCookies" defaultUrl="~/" loginUrl="~/user/signin" name="MYAPPWeb" timeout="21600" slidingExpiration="true"/>
</authentication>
UserController,
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult SignIn(SignInViewModel user)
{
UserDTO userObj;
using (var services = new ServiceFactory())
{
userObj = services.UserManagement.ValidateLoginDetails(ConfigHelper.EnvironmentString, user.TenantName, user.Username, user.Password);
}
string userID = userObj.UserID.ToString();
//FormsAuthentication.RedirectFromLoginPage(userID, user.RememberMe);
FormsAuthentication.SetAuthCookie(userID.ToString(),true);
FormsAuthentication.RedirectFromLoginPage(userID, false); //DO NOT REMEMBER ME
}
HomeController (Default page)
public ActionResult Index()
{
bool x = User.Identity.IsAuthenticated; //false?
string y = User.Identity.Name; //null?
return View();
}
It looks pretty straight forward, am I missing something? Please help!
Note:
When I create the project I selected windows authentication. It created some Owin authenticaiton related configuration cs files (startup.auth.cs). I have removed them and added the above appsetting entry as it is required to stop loading Owin assemblies.
<add key="owin:AutomaticAppStartup" value="false"/>
If your project has Owin authentication by default, it will remove form authentication from the project.
If you see your web config you may see
<remove name="FormsAuthentication" />
configuration.
Simply remove it.
I had the same problem and it solved the issue.
I'm trying to explore how it's possible to add additional claims to a User during the OWIN pipeline.
I know that I can do this at the login stage or at some other points, possibly in the Application_PostAuthenticate section in the Global.asax since I don't have a Login section (it's a Windows Authentication app), but I was wondering if it's possible or even better to do it in the OWIN pipeline.
My idea comes from the fact that OWIN too has a PostAuthenticate stage in the pipeline. So I tried this:
app.Use((context, next) =>
{
var user = context.Authentication.User.Identity as ClaimsIdentity;
if (user != null)
{
user.AddClaim(new Claim(ClaimTypes.Role, "Admin"));
user.AddClaim(new Claim(ClaimTypes.GivenName, "Mr. Tallmaris"));
}
return next.Invoke();
});
With a break point I can see that the user is the correct one and that the claims are added, but in my View I have something like this:
<ul>
#foreach (var claim in ClaimsPrincipal.Current.Claims)
{
<li>#claim.Type - #claim.Value</li>
}
</ul>
But my newly added claims are not showing up. Any ideas?
I know that "some" claims need to be added at Application level anyway (roles coming from DB and other things) but I would like to explore adding certain claims straight from the OWIN pipeline.
I used this principle in my asp.net application for converting groupsid claims to role claims.
app.Use((context, func) => {
var claimsIdentity = context.Authentication.User.Identity as ClaimsIdentity;
if (claimsIdentity != null) {
var claimsToAdd = new List<Claim>();
//check if we have any groupsid claims, add these as role claims
foreach (var claim in claimsIdentity.Claims) {
if (claim.Type == ClaimTypes.GroupSid) {
claimsToAdd.Add(new Claim(ClaimTypes.Role,
new SecurityIdentifier(claim.Value)
.Translate(typeof(NTAccount)).ToString()));
}
}
if (claimsToAdd.Count > 0) {
claimsIdentity.AddClaims(claimsToAdd);
}
}
return func.Invoke();
});
This worked for me using Microsoft.Owin v3.0.0.0
I'm probably not understanding something but I have the issue below:
AppHost.cs
Plugins.Add(new AuthFeature(
() => new AuthUserSession(),
new IAuthProvider[] { new BasicAuthProvider() }) { HtmlRedirect = null });
HomeController.cs
[Authenticate]
public class HomeController : ServiceStackController
The issue
The issue is that when I try to access the HomeController, I am redirected to ~/login?redirect=.....
I would assume that by setting HtmlRedirect to null, would also affect the MVC controllers too, but it doesn't seem to.
Is this expected behaviour? or is am I doing something wrong?
My end goal is to have the browser prompt with a challenge / response basic auth box.
Since this commit you are able to override the default behavior when authentication failed:
[Authenticate]
public class HomeController : ServiceStackController
{
public override ActionResult AuthenticationErrorResult
{
get
{
//return 401 Unauthorized for example
return new HttpStatusCodeResult(401);
}
}
}
ServiceStackController.AuthorizationErrorResult can be modified in the same way.
Setting HtmlRedirect to null doesn't work in this case, because the behavior of the [Authenticate] attribute (and all other ServiceStack attributes) is slightly different when used with ASP.net MVC controllers instead of ServiceStack services.
I have been on the ServiceStack Jabbr chat page and was told that this is a bug and a fix will be put on today!
https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.FluentValidation.Mvc3/Mvc/ExecuteServiceStackFiltersAttribute.cs#L25
After upgrading some of our external websites running on SharePoint 2007 to 2010, we ran a link checker to find problems. We noticed the log showed requests for a file called spsdisco.aspx. Indeed, when examining the source of our web pages, SharePoint is adding the following link element to the page HEAD:
<link href="_vti_bin/spsdisco.aspx" rel="alternate" type="text/xml" />
This is a web service discovery file listing out the names and locations of all of SharePoint's web service endpoints. Even worse, this file is starting to show up in search indexes. At best it is embarrassing; at worst it's a potential vulnerability (these are external websites). Because it's a virtual file, it shows up under every site and subsite, so a manual approach to "hiding" each one is difficult and clumsy.
I can't seem to find any actual documentation about it -- a few references on updating it to include a custom web service, but that's about it. How might we approach a reliable, top-down approach to disabling access to these pages? I think we can find a way to suppress the LINK element in the page, but that's just obscuring the problem.
Is there a location in SharePoint (Site or Central Admin) to turn it off? Would you just add some request filtering to IIS to disallow access to SPSdisco.aspx and the ASMX files?
Update: On Kev's suggestion, I've cross-posted to sharepoint.stackexchange.com.
Update 2: See, I hadn't abandoned this question. We finally had time to get some MS guidance and build a deployable SharePoint solution to address the issue.
As a quick fix I would add a request filtering rule to deny access to SPSDisco.aspx.
But you might want to ask on the new SharePoint Stack Exchange site about a more robust fix:
https://sharepoint.stackexchange.com/
Here is the solution that we arrived at. It was in part based on recommendations by our Microsoft representative, so you might consider this an unofficial, "official" approach.
First, we need keep SharePoint from advertising the disco file to the world (i.e. Google). Simply remove the following line in your master pages:
<SharePoint:SoapDiscoveryLink runat="server"/>
This will suppress the <link href="/_vti_bin/spsdisco.aspx" rel="alternate" type="text/xml"> reference in the HEAD of your pages.
Next, we want to make sure that unauthorized users don't have access to the web services described by the disco file, or anything in _vti_bin for that matter. If your site only runs internal to your firewall (an intranet, for example), then this isn't as important. But if you've got anonymous endpoints that can be accessed externally, you want them locked down.
This is an excellent application for an HttpModule. We'll build one that intercepts any request containing _vti_bin in the path, and if the current user is unauthorized will return a 404 NOT FOUND status code. I chose to return a 404 rather than a 401 UNAUTHORIZED because I don't just want to lock those paths down, I want to hide the fact that anything even exists at those paths.
Our HttpModule looks like this:
using System;
using System.Web;
namespace Custom.SharePoint.HttpModule.SpSecureVtiBin {
public class SpSecureVtiBinModule : IHttpModule {
#region IHttpModule Members
public void Dispose() { }
public void Init( HttpApplication context ) {
context.AuthorizeRequest += new EventHandler( context_AuthorizeRequest );
}
protected virtual void context_AuthorizeRequest( object sender, EventArgs e ) {
HttpApplication app = (HttpApplication)sender;
string requestedPath = app.Request.Path;
if ( requestedPath.ToLowerInvariant().Contains( "_vti_bin" ) ) {
if ( !app.Request.IsAuthenticated ) {
app.Response.StatusCode = 404;
app.Response.StatusDescription = "Not Found";
app.Response.Write( "404 NOT FOUND" );
app.Response.End();
}
}
}
#endregion
}
}
Simple enough. To use the HttpModule, it needs to be registered in the site's web.config file with an entry under \configuration\system.webServer\modules:
<add name="SpSecureVtiBinModule" type="Custom.SharePoint.HttpModule.SpSecureVtiBin.SpSecureVtiBinModule, Custom.SharePoint.HttpModule.SpSecureVtiBin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=[your_public_key_token]" />
Of course, we don't want to modify a SharePoint application's web.config file manually. We'll create an SPFeatureReceiver to do the job:
using System.Collections.ObjectModel;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
namespace Custom.SharePoint.HttpModule.SpSecureVtiBin {
public class ModuleFeatureReceiver : SPFeatureReceiver {
private static string _owner = "SpSecureVtiBinModule";
public override void FeatureActivated( SPFeatureReceiverProperties properties ) {
SPWebApplication app = (SPWebApplication)properties.Feature.Parent;
app.WebConfigModifications.Add( GetModificationForSystemWebServer() );
app.WebService.ApplyWebConfigModifications();
app.Update();
}
public override void FeatureDeactivating( SPFeatureReceiverProperties properties ) {
SPWebApplication app = (SPWebApplication)properties.Feature.Parent;
Collection<SPWebConfigModification> mods = app.WebConfigModifications;
int modCount = mods.Count;
bool modRemoved = false;
for ( int i = modCount - 1; i >= 0; i-- ) {
SPWebConfigModification mod = mods[i];
if ( mod.Owner.Equals( _owner ) || mod.Owner.Equals( "CHK.SharePoint.HttpModule.SpSecureVtiBin.SpSecureVtiBinModule" ) ) {
app.WebConfigModifications.Remove( mod );
modRemoved = true;
}
}
if ( modRemoved ) {
app.WebService.ApplyWebConfigModifications();
app.Update();
}
}
private SPWebConfigModification GetModificationForSystemWebServer() {
return new SPWebConfigModification {
Name = "add[#name='SpSecureVtiBinModule']",
Owner = _owner,
Path = "configuration/system.webServer/modules",
Value = #"<add name=""SpSecureVtiBinModule"" type=""Custom.SharePoint.HttpModule.SpSecureVtiBin.SpSecureVtiBinModule, Custom.SharePoint.HttpModule.SpSecureVtiBin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=[your_public_key_token]"" />",
Sequence = 0
};
}
}
}
Now all that's left is to package up the HttpModule. You'll need to define a Feature in the package and reference the SPFeatureReceiver class. This will cause the web.config entry to be added when the Feature is activated, and the entry to be removed when the Feature is deactivated. Target the Feature for a WebApplication and the assembly deployment target to GlobalAssemblyCache.