Angular MVC Web API 2 Deploy to remote IIS issue - angularjs

I have an application that uses MVC 5, Web API 2, and Angular and I'm having some trouble getting it to work properly. I am using the default MVC routing to initially load the shared layout page, and I'm then using the angular routing to essentially have a single page application. The error I'm getting is the identity impersonate error. (below)
HTTP Error 500.24 - Internal Server Error
An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode.
Most likely causes:
system.web/identity#impersonate is set to true.
I have set the identity impersonate to false, still did not work. I also added the line below to the config file, still did not work.
<validation validateIntegratedModeConfiguration="false" />
Here is my Application Start method:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Here is my route config
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
There is a second part to my question that may be related to the issues I'm facing. I have the application under the default web site in a subfolder (I navigate to server.com/appName). I can get to the home page, but clicking on any links presents the error mentioned above.
Any ideas? Let me know if more code is needed.

I have the application under the default web site in a subfolder (I navigate to server.com/appName).
You need to run ASP.NET (or MVC) inside of an IIS application for it to function. It won't function correctly from a subdirectory of an application.
In Internet Information Services Manager, navigate to the virtual directory, right click it and choose "Add Application". Enter a name, application pool, and the physical path, then click on "OK".

Related

Connecting Blazor Wasm to Identity Server 4 - Register and account management links not working

Hopefully someone can guide me in the right direction, because I've been working on this for a while now.
I've create a Blazor WASM hosted in .Net Core. However instead of using the identity in the Server (API) project, I wanted to use for authentication an Identity Server hosted in a different project (so that I can use a standalone Identity Server).
I've create an Identity Server 4 project and also scaffold-ed the Identity Razor pages (so that I have the full flow with registration, account management, password recovery etc.) instead of the basic 3 or so pages that Identity Server generates.
In my Blazor Client project I've added the following inside the Main method:
{
// Bind to the oidc section in the appsettings.
builder.Configuration.Bind("oidc", options.ProviderOptions);
options.UserOptions.RoleClaim = JwtClaimTypes.Role;
})
Also, in my appsettings file I have the following oidc section:
"oidc": {
"Authority": "https://localhost:5001",
"ClientId": "ProjectAllocation.Client",
"DefaultScopes": [
"openid",
"profile",
"roles",
"offline_access"
],
"PostLogoutRedirectUri": "/",
"ResponseType": "code"
}
}
In Identity Server, in the Startup ConfigureServices I am redirecting the Login \ Logout to use the pages in the scaffolded Identity Area:
var builder = services.AddIdentityServer(options =>
{
...
options.UserInteraction.LoginUrl = "/Identity/Account/Login";
options.UserInteraction.LogoutUrl = "/Identity/Account/Logout";
options.Authentication = new IdentityServer4.Configuration.AuthenticationOptions
{
CookieLifetime = TimeSpan.FromHours(10), // ID server cookie timeout set to 10 hours
CookieSlidingExpiration = true
};
})
Now the login and logout work and it seems I am getting the right token data in the client; I haven't implemented the API on the server side yet.
My problem is that the register and the account management links from the Client project are not working. If you would use the template from the VS with integrated identity server then you would be able to click on the register link inside the client app and be taken to the Account\Register page in the Identity area; also once you logged in you can click on the "Hello ...." link and be taken to the Account management in the Identity area.
However this doesn't work in my case. If I navigate from the browser directly to those areas then it works (i.e.: browse to https://localhost:5001/Identity/Account/Register: it works).
When I click on Register button in the Client app it just reloads the app with the following link:
https://localhost:44395/?returnUrl=%2Fauthentication%2Flogin : it looks as if the app is being asked to login, even though the Register page in the Identity Server is marked to allow anonymous access.
I am really puzzled as to why this doesn't work. I can't figure out which settings in the Blazor project sets the links to navigate to via the RemoteAuthenticatorView. I am considering replacing the register button so that it doesn't navigate via the RemoteAuthenticatorView anymore and instead it uses a regular link directly to the Identity Server Register page, but I am not sure what the implications are; also it's really annoying that I cannot get this to work properly.
I've even tried to change the path to the register page so that instead of Identity/Account/Register is Account/Register via the ConfigureServices in the Startup file in the Identity Server 4:
services.AddRazorPages(options => {
options.Conventions.AddAreaPageRoute("Identity", "/Account/Register", "Account/Register");
});
which works from the browser (https://localhost:5001/Account/Register), but it still didn't work from the WASM Blazor Client.
Any ideas?
Thanks,
Raz
I am leaving this here in case someone else stumbles upon this.
I've looked through the Blazor WASM code and for registration and account management it uses the NavigationManager to navigate to the paths supplied in RemoteRegisterPath and RemoteProfilePath properties of the AuthenticationPaths.
For some strange reason though it looks like you cannot navigate to an outside url: the NavigationManager will ignore the supplied base address and use the base address of the project. So even though I've tried to provide an address like https://localhost:5001/Identity/Account/Register, the application actually navigates to https://localhost:44395/Identity/Account/Register.
As a workaround I've created a controller called Account with two methods Register and Manage which will redirect to the address of the Identity Server. So the Blazor client will call the corresponding method in the Account controller in the Blazor API server project which will redirect to the corresponding Identity Server page.
I've modified the call to AddOidcAuthentication() in the Main method inside the Blazor Client project:
builder.Services.AddOidcAuthentication(options =>
{
// Bind to the oidc section in the appsettings.
builder.Configuration.Bind("oidc", options.ProviderOptions);
options.AuthenticationPaths.RemoteRegisterPath = "Account/Register";
options.AuthenticationPaths.RemoteProfilePath = "Account/Manage";
options.UserOptions.RoleClaim = JwtClaimTypes.Role;
})
I've also created an AccountController in the Controllers folder in the Blazor API server project:
[Route("[controller]")]
[ApiController]
public class AccountController : ControllerBase
{
[AllowAnonymous]
[HttpGet("Register")]
public IActionResult Register(string returnUrl)
{
return Redirect(#"https://localhost:5001/Identity/Account/Register?returnUrl=https://localhost:44395/" + returnUrl);
}
[AllowAnonymous]
[HttpGet("Manage")]
public IActionResult Manage(string returnUrl)
{
return Redirect(#"https://localhost:5001/Identity/Account/Manage?returnUrl=https://localhost:44395/" + returnUrl);
}
}
Might be a good idea to authorize the Manage method. Also the returnUrl would probably need some additional parameters (at least for the login \ logout there are more parameters).
In addition, I needed to make some small changes in the Identity files scaffolded in the Identity Server project to allow redirection to non-local paths.
There are certain things that can be improved and it does feel like a hack, but the solution works for now and I couldn't find any better alternatives.
The standard IdentityServer4 project templates does not include any pages for registering users, these page you have to develop your self inside IdentityServer4. To get user registration pages you can try one of these projects/products:
An ASP.NET Core IdentityServer4 Identity Template with Bootstrap 4 and Localization
AdminUI

Identity server registration doesn't redirect back to React app

I have an ASP.NET Core backend with a React frontend hosted in different origins.
The ASP.NET core backend is configured to use the inbuilt identity server:
// Startup
public void ConfigureServices(IServiceCollection services)
{
...
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
...
}
I have added the OidcConfigurationController that the identity server expects:
public class OidcConfigurationController : Controller
{
public OidcConfigurationController(IClientRequestParametersProvider clientRequestParametersProvider)
{
ClientRequestParametersProvider = clientRequestParametersProvider;
}
public IClientRequestParametersProvider ClientRequestParametersProvider { get; }
[HttpGet("_configuration/{clientId}")]
public IActionResult GetClientRequestParameters([FromRoute]string clientId)
{
var parameters = ClientRequestParametersProvider.GetClientParameters(HttpContext, clientId);
return Ok(parameters);
}
}
I have also added the following settings in appsettings.json that the identity server reads:
...
"IdentityServer": {
"Clients": {
"WebApplication1": {
"Profile": "SPA",
"RedirectUri": "http://localhost:3000/authentication/login-callback",
"LogoutUri": "http://localhost:3000/authentication/logout-callback"
}
}
},
...
The React app is hosted at http://localhost:3000 and uses oidc-client to interact with the ASP.NET Core server. The frontend code appears to correctly request a sign in passing the correct return url:
The ASP.NET Core authentication pages are successfully shown:
But if you post a new registration, ASP.NET Core redirects to its root rather than http://localhost:3000:
Is there anything I've missed or does the inbuilt ASP.NET identity only work if the client is hosted in the same origin?
Any help appreciated.
You just miss your return url during roundtrip to Account/Register. That has nothing to do with origins. Check with a pure signin -- that should work out of the box.
New account registration is not what Identityserver is responsible for. You have to handle that yourself. You need to pass through your return url each time you redirect, starting from the "Register" button on your login form and ending at your [HttpPost]Register action. Most likely you would like to keep that url even when you user cancels the registration in the middle and decides to signin with an existing account.
See this question/answer for the reference.

Spring Boot application gives "405 method not supported" exception for only Angular/HTML/JSP resources

I have an application written with Spring Boot and AngularJS. When I try to hit a REST service as part of this application, I am able to hit it with POST method wherever POST is configured for request mapping.
But if I try to request AngularJS bind pages, I get a "405 method not supported" exception. So I try to create HTML and JSP pages too, which are not bound to Angular but still, I am getting the same exception.
Where can I start debugging this, and what is the likely reason?
i am sharing here furthere details about issue.
Basically this existing application created/developed with Jhipster, angularjs, Spring boot and spring security does not allow to access html/angularjs related resources with POST from outside. I will explain here what different scenarios work and what is not not working. 1.Postman trying to access base url trying to fetch index.html from same application- Give 405 Post method not allowed.2.Created an independent Test.html in same application and trying to access it from postman- Gives 405 Post method not allowed.3.Created a service which allows POST access in same application- Able to hit service from WSO2 IS IDP and also from Postman.4.Created a separate application on tomcat and provided as callback in WSO2 IDP with starting point for SSO from base url of existing application- Able to hit callback URL on tomcat server. Firefox shows that a POST request was generated for callback URL from WSO2 IS IDP to tomcat based application 5.Created a separate application with Angular js and Spring boot and provided as callback in WSO2 IDP with starting point for SSO from base url of existing application- Able to hit callback URL on tomcat server. Firefox shows that a POST request was generated for callback URL from WSO2 IS IDP to new application with Spring boot and Angularjs. This took me down to conclusion that one of three is causing this issue
1. Spring security generated from JHipster
2. Angularjs
3. Some CORS or other filter from Spring Security is causing this issue.
Till now we have tried to different debugging methods like
1. disable CORS,
2. in angularjs-resource.js enable POST for get operation,
3. In SecurityCOnfigurer, try to permit POST method for base URL or resolve it to GET in httpsercurity authorizerequest etc.
4. Also ignoring resources in websecurity.
Application stack for existing application which we are trying to implement SSO is as below
1. Angularjs 1.5.8
2. Springboot 1.5.9.release
3. WSO2IS 5.4.1
4. WSO2AM 2.1.0
5. JHipster
Let me know if any particular area which we might have missed to analyze or different methods to try.
Thanks,
Sandeep
Try to disable CSRF in security config
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
...
}
...
}
#SpringBootApplication
#Import({
...
SecurityConfig.class
...
})
public class SpringBootApp {
...
}

ASP.net core server side redirect issue on Azure

I have a react.js application built utilizing react-router, calling ASP.NET core 2.0 restful services for data. I would like any server-side 404 error to just route to "/". I have app.UseStatusCodePagesWithReExecute("/") in my startup.
When putting an explicit path in my localhost (iis express), it redirects to root when an illegal path is entered (as expected), and actually displays the appropriate page if a legal path is entered.
However when this same app is deployed on Azure, putting an illegal path or a legal path outside of root gives me this page:
The resource you are looking for has been removed, had its name changed,
or is temporarily unavailable.
I'm not sure if there needs to be additional Azure configuration to make this work like localhost. Any ideas or suggestions would be appreciated.
I just deployed this and I had no problems so I assume you have your middleware in the wrong order and it should be like this. Verify that is in this order
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStatusCodePagesWithRedirects("/");
app.UseDefaultFiles(); //also add this
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
app.UseStatusCodePagesWithReExecute("/");
This should be first before any piece of middleware. Just a side note, this piece of middleware does not cause a browser to redirect, it just rewrites the path. So in your browser, it looks like you can visit /sfsdf/sdfsdfsdgfs. This might be a problem for you because you are using React. /sfsdf/sdfsdfsdgfs will be picked up by the react-router and will lead nowhere if you dont have something to handle that. If you want to cause a redirect, replace app.UseStatusCodePagesWithReExecute("/") and use
app.UseStatusCodePagesWithRedirects("/");
Again, this should be the first piece of middleware that you add and would play more nicely with your react-router.
Add this piece of middleware after your redirect middleware.
app.UseDefaultFiles();
All this middleware does is that it looks for index.html (it does not have to be index.html, it also tries matching other files) in your site/wwwroot folder and serves that whenever a request for / comes in. So have an index.html page in the site/wwwroot which holds you react app. You probably already have this.
You don't need any virtual directories to point to /api and one for the the react app. So you can remove them both
The react application will live in an index.html file in your site/wwwroot
Your apis will live in mvc controllers. I know you have it already set up like this.
The reason why you don't need any virtual directories is ASP.Net core will handle all that for you. When you make a request to /
It will be picked up by
app.UseDefaultFiles();
This will internally rewrite the path to be /index.html
This will be then be picked up by static middleware and will return the index.html page which holds your react app and end the request.
Now say you make a request to /blah/blah. This will skip the first two pieces of middleware and hit MVC. MVC will look for a path /blah/blah. If it exists it will return something. If it does not it will be picked up by the redirect middleware that you have at the top. This will cause a redirect to / and the whole process will start again. You do not need any virtual directories to achieve this so you can remove them.

Owin OpenIdConnect Active Directory HttpContext.GetOwinContext doesn't open microsoftonlin login page

I'm trying to use Owin and OpenIdConnect to authenticate users via active directory (office 365 online). I've followed this example and I managed to create a new MVC test project and get it all working. (Settings for AD app id, tenant, Web config etc all fine).
I'm now trying to add that functionality into my existing ASP.net mvc application and I can't get the dang thing to work.
This is what I have: An Account Controller with a "void" action like this (from the example that works in my PoC but not in my actual application):
public void SignIn()
{
// Send an OpenID Connect sign-in request.
if (!Request.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
When this action is invoked, I expect the browser to be directed to: login.microsoftonline.com..., but instead it opens this page: https://localhost:44301/Account/Login?ReturnUrl=%2fAccount%2fSignIn
It's like it's calling some sort of redirect somewhere and I can't see where.
Help!
I found the answer. I had to do 2 things:
Remove the WebMatrix dll's from the references (apparently nuget package for mvc put it there, so it might come back)
Remove authentication mode="Forms" from web.config
Thanks.

Resources