How to configure custom security token handler? - wcf

I have implemented custom Saml2SecurityTokenHandler as shown here http://leastprivilege.com/2015/07/02/give-your-wcf-security-architecture-a-makeover-with-identityserver3/.
The constructor of this handler accepts two custom parameters - authority and requiredScopes. In the example this handler is registered in the code. However, I want to do this in web.config file.
<system.identityModel>
<identityConfiguration saveBootstrapContext="true">
<securityTokenHandlers>
<clear />
<add type="MyNamespace.MyCustomSaml2SecurityTokenHandler, MyAssembly" />
</securityTokenHandlers>
</identityConfiguration>
</system.identityModel>
Is it possible to pass somehow from the configuration (web.config), these two constructor parameters?

give your class MyCustomSaml2SecurityTokenHandler a zero-parameter constructor.
Get those details at run time from your local config on the server side.

Related

WebAPI AttributeRouting with version number as parameter

I am trying to set up a route to my MVC controller action with the following template:
[Route("app/{appId:length(20)}/validate/{version}")]
The idea is that the resulting URL would then look something like this:
(I'm adding a space to make the localhost url try not resolve...)
http:/ /localhost:2642/api/update/v1/app/6A6EE0B355C34DBFB381/validate/1.0.0.0
The problem I have is that this would give me a 404 error.
If I remove the Route attribute and use the built-in MVC routing, it works. The url then is:
http:/ /localhost:2642/api/external/CheckForUpdate?appId=6A6EE0B355C34DBFB381&version=1.0.0.0
This should work since I know Nuget has got versions in their URL's, but I think they use the built-in MVC router.
I also tried to add the :regex() markup in the template for the route so validate the string format, but that didn't work. If I pass in a normal string or a value such as 1_0_0_0 it works. Thing is I don't want to go through the effort to manipulate the version string before sending it to the api and then in the api itself.
Any ideas on what I am doing wrong?
If you make your routing attribute
[Route("app/{appId:length(20)}/validate/{version:regex(^([1-9]\\d+|[0-7])(\\.\\d{1,3}){0,3}$)}")]
and make sure you accept the parameters in the method
public Task<IHttpActionResult> Get(string appId, string version)
{
//magic
}
then in the web.config, system.webServer > handlers section change the *. to *
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
to
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
and also make sure
<modules runAllManagedModulesForAllRequests="true">
exists in <system.webServer>

Authentication with Azure Active Directory : WIF10201 Error

I'm trying to add Azure Authentication to an existing website with Visual Studio 2013. It looks like this used to be a bit easier in 2012 but seems the recommended path for 2013 is to set this up when creating the project.
I created a new project with AAD (which works) to compare to the changes being made to the project I need to add authentication to. I copied the authentication classes and config settings but it still seems like there is something wrong in web.config:
For AppSettings I have:
<add key="ida:FederationMetadataLocation" value="https://login.windows.net/_____/FederationMetadata/2007-06/FederationMetadata.xml" />
<add key="ida:Realm" value="https://AADPath/Application" />
<add key="ida:AudienceUri" value="https://AADPath/Application" />
For System.identityModel I have:
<system.identityModel>
<identityConfiguration>
<issuerNameRegistry type="RegistryClassPath, ProjectName" />
<audienceUris>
<add value="https://AADPath/Application"/>
</audienceUris>
<securityTokenHandlers>
For system.identityModel.services I have:
<federationConfiguration>
<cookieHandler requireSsl="true" />
<wsFederation passiveRedirectEnabled="true"
issuer="https://login.windows.net/AADPath/wsfed"
realm="https://AADPath/Application"
requireHttps="true" />
When I run the site, I'm redirected to the login page as I expect but after logging in I'm presented with the WIF10201: No valid key mapping found for securityToken error.
It was not the configuration but rather I didn't copy the data from the embedded database to the existing project. All seems to be working now.

ASP.NET MVC4 routing ignored for static files

I have an ASP.NET MVC3 application .NET4 in which a routing exists for content files, which are served from a resource inside a class library.
Routing is configured as follows
routes.MapRoute("Resources", "Default{Content}/{*contentpath}", new {controller = "Resource", action="GetResource"});
So if there is a request DefaultMvcScripts/test.js, the GetResource method will be called.
However, when converted to MVC4 ,.NET4.5 this doesn't work anymore, GetResource is not called anymore, it bypasses routing even if I put
routes.RouteExistingFiles = true;
For a request DefaultMvcScript/test (without extension), routing is not ignored (I can see GetResource being called).
Can I have the old behaviour back, so that even if I specify an extension, routing is honoured.
I think you're just missing the last step - you need to configure your app so that the handler pipeline pays attention to requests for static files.
In they system.webserver section of the web config you need to add a handler for the static files you want to serve. You need to use the TransferRequestHandler
<add name="staticHandler" path="*.js" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersion4.0"/>
See Jon Galloway's article for a complete description
http://weblogs.asp.net/jongalloway/asp-net-mvc-routing-intercepting-file-requests-like-index-html-and-what-it-teaches-about-how-routing-works
Apparently, adding this to the web.config restores previous behaviour:
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>
The preCondition="" seems to be the trick.
Source: http://www.britishdeveloper.co.uk/2010/06/dont-use-modules-runallmanagedmodulesfo.html

"The Role Manager feature has not been enabled" - Accessing SimpleMembership from external web service

Hoping you may be able to help with a peculiar issue I'm facing with my SimpleMembershipProvider.
I have an MVC4 application that uses the SimpleMembership feature to store user and role information. This all works perfectly from the front end MVC4 application.
We also have a web service which will call the same SimpleMembershipProvider to validate the user credentials from a mobile app using the standard ValidateUser() method.
However, before I get to my ValidateUser() method I need to initialise my WebSecurity object using the WebSecurity.InitializeDatabaseConnection method. This is causing the below error:
"The Role Manager feature has not been enabled."
I'm initialising the WebSecurity object within the services startup, using the same code pulled from my Portal:
if (!WebSecurity.Initialized)
{
WebSecurity.InitializeDatabaseConnection("PortalContext", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
I've checked that my web.config of my web service contains the appSettings key
<add key="enableSimpleMembership" value="true" />
I've also included the rolemanager and membership details within my system.web section of my web.config.
<roleManager enabled="true" defaultProvider="SimpleRoleProvider">
<providers>
<clear />
<add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
</providers>
</roleManager>
<membership defaultProvider="SimpleMembershipProvider">
<providers>
<clear />
<add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
</providers>
</membership>
I'm now completely at a loss and have spent all morning googling for a possible solution.
Can anyone think of a reason why this might be occurring?
If you have multiple projects in the same solution and are using migrations, make the as the startup project the one containing the migrations (in Solution Explorer, Right click Project name > "Set as startup project") before running database-update.

SessionAuthenticationModule Cookie Handler not creating HttpOnly secure cookie

I am using System.IdentityModel to authenticate users in an ASP.NET MVC4 web application using forms auth with a claims principal. (code based on this article: http://brockallen.com/2013/01/26/replacing-forms-authentication-with-wifs-session-authentication-module-sam-to-enable-claims-aware-identity/)
My ClaimsBasedAuthenticationService class issues the SAM cookie from the SessionSecurityToken, and all has been well...except that I just now noticed that it is not creating the session cookies as HTTPOnly or requiring them to require SSL. When I debug the code, I can see those properties on the CookieHandler object are set correctly in the debugger, but the final session cookie that is created simply doesn't have the HTTPOnly and Secure flags marked.
I have the web.config lines to set these to true explicitly as such:
<system.web>
<httpCookies httpOnlyCookies="true" requireSSL="true" />
<authentication mode="Forms">
<forms ... requireSSL="true" />
</authentication>
...
</system.web>
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="true" hideFromScript="true" />
</federationConfiguration>
</system.identityModel.services>
Can someone tell me if there's something else I am missing in order for my FedAuth cookies to be hidden from script (HTTPOnly) and require SSL?
I am using the same implementation and do not see your issue using Fiddler2. However maybe the issue is related to your debugging tool? In IE10 debugging tools the secure and http only flags are only displayed when the cookies are first received. If you check using Chrome debugging tools you should see the flags displayed correctly on all requests.
Did you get this working? I've been using basically the same code and it's all fine.
I can't see that the following suggestions have anything to do with anything, but the only things I can suggest, are to set the cookie lifetime
<cookieHandler hideFromScript="true" requireSsl="true" persistentSessionLifetime="30" />
<forms loginUrl="/Whereever" timeout="30" requireSSL="true" />
and
<system.webServer>
<modules>
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
</modules>
</system.webServer>