How to create feature toggling when spring security is enabled on ff4j? - spring-security

I did the following steps and I don't understand why I did not succeed on the last one :
clone this repository
start spring boot app
browse to http://localhost:5002/ff4j-web-console/features
login with user/user (also tried admin/admin and superuser/superuser)
try to create new feature but got a 403 error message
I want to have the console (+api) protected by a basic authentication but I want to be able to do anything when I'm logged. How can I achieve this ? Am I missing something on how security works between spring and ff4j ?

Using Spring Security with Java configuration, CSRF protection is enabled by default. In this context, if you make an Ajax request to a REST endpoint using POST method, you will get a csrf token missing error.
To fix it, in class SecurityConfig changeconfigure method with the following. The code has been updated in github as well.
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and().formLogin();
}

Related

WebMvcTest: Migrating from WebSecurityConfigurerAdapter to SecurityFilterChain

As described here Spring Security deprecated WebSecurityConfigurerAdapter which I've been using for some time. I used the component based approach and introduced SecurityFilterChain and InMemoryUserDetailsManager beans (see: commit) but then one of my tests, which is using #WithMockUser failed.
Does #WebMvcTest tests work with #WithMockUser when using Spring Security component based approach (SecurityFilterChain)?
Tests: https://github.com/pszemus/spring-security-test/blob/master/src/test/java/com/example/springsecuritytest/TestControllerTest.java
Old security configuration that used WebSecurityConfigurerAdapter (for which all tests pass): https://github.com/pszemus/spring-security-test/blob/c323ce3af77bb067c7eef58fd933689ef97c082c/src/main/java/com/example/springsecuritytest/SecurityConfiguration.java
New security configuration that use component-based approach (givenMockedCredentials_shouldAccessSecuredEndpoint test fails with message: Status expected:<200> but was:<401>): https://github.com/pszemus/spring-security-test/blob/fb9b40194747a3b45678183276b81c582cb004a3/src/main/java/com/example/springsecuritytest/SecurityConfiguration.java
Whole project, with failing test, is located: https://github.com/pszemus/spring-security-test
You should add #Import(YourSecurityConfiguration.class) in your test class. The #WebMvcTest is not picking up the configuration automatically, so you have to tell it explicitly which configuration to use.

SAML2 metadata endpoint in Spring Security 5.4.0-RC1 not enabled by default

I wanted to try the new SAML2 Metadata endpoint in Spring Security 5.4.0-RC1 (with Spring Boot 2.3.2) but accessing /saml2/service-provider-metadata/{registrationId} returns 404.
I had to add the filter myself, like this:
#Bean
public Saml2MetadataFilter saml2MetadataFilter(RelyingPartyRegistrationRepository repository) {
return new Saml2MetadataFilter(new DefaultRelyingPartyRegistrationResolver(repository), new OpenSamlMetadataResolver());
}
Then the metadata endpoint works as expected.
Is this by design or is there a missing configuration on my part or in Spring Security?
I searched for Saml2MetadataFilter in the spring security repository on GitHub but only found it in a test.
Answering my own question: The Spring Security SAML2 documentation is now updated with instructions on how to enable the metadata endpoint.
https://docs.spring.io/spring-security/site/docs/5.4.0/reference/html5/#servlet-saml2login-metadata
This instruction make sure Saml2MetadataFilter is added before the Saml2WebSsoAuthenticationFilter so it's always publicly accessible.

401 Returned when authenticate via HttpClient on WebLogic

I have REST based services deployed in WebLogic Application Server 12 which uses Spring Security for authentication using BASIC Auth. Previously I found out that WebLogic has a bug where it intercept a call if request has Authorization header in it.
I found a very helpful link which solves this issue by disabling <enforce-valid-basic-auth-credentials>false</enforce-valid-basic-auth-credentials> this in config.xml of WebLogic. Now if I access my service via POSTMan it works great and Spring handles the security.
After this I write some automated test which uses Apache Common HttpClient library to call my service, but I am continuously getting 401 Unauthorised from WebLogic. My client code is as follows;
httpClient = new HttpClient();
httpClient.getState().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
new UsernamePasswordCredentials(
getTestUsername(config.getUsername()),
getTestPassword(config.getPassword()))
);
I tried putting auth pref to Basic, adding Authorization header to my request even setting auth to Preemptoive to true everything it still the same.
One thing I am sure is that Weblogic is intercepting my call from Java Standalone client somehow! because in Response Headers i get 'realm: weblogic' which is incorrect as it should be 'realm: Spring Security Application', more strangely I am able to access the same URL from POSTMan with the same security credentials. Am I missing anything?
Yes, I confirm that Weblogic intercepts your call.
You have to enforce the <enforce-valid-basic-auth-credentials> tag to false in your weblogic config.xml file.
Please take a look at Error adding enforce-valid-basic-auth-credentials to config.xml and http://www.dba-oracle.com/t_weblogic_bypass_basic_authentication.htm

Registering WebAPI routes and its order - why it matters

I was playing around with ASP MVC and WebAPI and in Global.asax I've called a few pieces of code in following order:
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
WebApiConfig.Register(System.Web.Http.GlobalConfiguration.Configuration);
What these methods do is self-explanatory. But when I did registration in this order, I could not access Web API. However when I changed it to:
WebApiConfig.Register(System.Web.Http.GlobalConfiguration.Configuration);
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
then Web API started to work. So I assume that order of registration is important. But why?
When you call RegisterRoutes(RouteTable.Routes); before
WebApiConfig.Register(System.Web.Http.GlobalConfiguration.Configuration);
the default route for MVC is taking precedence and nothing ever makes it to the WebApi routes.
I did some refactoring of my Global.asax to group MVC config and WebApi config together and just so happened to choose to do WebAPI config second.
Suddenly I started getting this kind of error for all of my API routes:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /api/values
This issue was caused by the scenario that the original poster outlined.
Always register your API routes first.

Errors are logged twice when using Elmah with WebApi

I'm trying to log exceptions from my asp.net web api project using elmah. I am having an issue where each error is logged twice.
I am using Elmah.Contrib.Web-Api and my Application class is as follows:
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configuration.Filters.Add(new ElmahHandleErrorApiAttribute());
RouteTable.Routes.MapHubs();
RouteConfig.RegisterRoutes(RouteTable.Routes);
#if DEBUG
EntityFrameworkProfiler.Initialize();
#endif
GlobalConfig.CustomizeConfig(GlobalConfiguration.Configuration);
}
}
If I commment out the following line then I get no messages at all:
GlobalConfiguration.Configuration.Filters.Add(new ElmahHandleErrorApiAttribute());
And I can confirm that I am only throwing one error and the call which generates the error is only been called once and I've not manually decorated my controllers or methods with the Elmah Attribute.
To try and resolve this I removed The Contrib Package and added followed the instructions found here http://www.tugberkugurlu.com/archive/asp-net-web-api-and-elmah-integration
This did not solve the issue and it still logs twice. It did allow me to put a break point into the Attribute class and confirm that for each error it is being called twice.
How can I solve this?
What ELMAH-related entries are in your web.config?
I had a similar issue in an MVC application - handled exceptions were being logged twice. In the application I use a custom exception filter to log handled exceptions to ELMAH using error signalling, while the HTTP module takes care of unhandled exceptions.
It turned out that I needed to set:
<add key="elmah.mvc.disableHandleErrorFilter" value="true" />
in web.config in order to disable the built-in exception filter within the ELMAH.MVC NuGet package.
The source code for the built-in filter shows that it logs handled exceptions:
https://github.com/alexanderbeletsky/elmah-mvc/blob/master/src/Elmah.Mvc/HandleErrorAttribute.cs
I'd check your FilterConfig.cs class, it's possible that the default HandleErrorAttribute is being added there and is re-throwing your exception?
For what it's worth, I was having the same problem of ELMAH logging each exception twice in my Web API application (using Elmah.Contrib.WebApi).
Comparing my ELMAH emails against my source history, I was able to identify that the problem started happening after the Ninject.Web.WebApi 3.0.2-unstable-9016 package was installed via nuget.
Sure enough, uninstalling the package and commenting out the single dependency binding that was using it solved the double exception logging problem. Reinstalling the package and leaving the dependency binding commented out caused the problem to start again, so it wasn't the binding itself.
Installing the previous version (Ninject.Web.WebApi 3.0.2-unstable-8) did not cause the problem to happen, but my dependency binding no longer worked.
I'm choosing to live with the problem for the time being.
Have you seen this post ? The author uses an ExceptionFilter to handle logging exceptions
For other folks with the logging twice issue (I don't think this helps the OP?) - this happened to me and the reason was because I had applied the filter globally
GlobalConfiguration.Configuration.Filters.Add(new ElmahErrorAttribute()); //log web api errors
but also applied the attribute to the class (doh!)
[ElmahError]
public class TestController : ApiController
So of course it logged twice.
I had this problem occur only on HTTP 401 responses. The issue turned out to be that Windows Authentication was enabled which was causing the browser to make a second negotiation request.
In my case, I was just able to disable Windows Authentication in the web.config:
<security>
<authentication>
<windowsAuthentication enabled="false" />
</authentication>
</security>
Note: If you don't have the config section unlocked, you can just disable Windows Authentication in IIS.

Resources