Spring Boot 2.0: how to disable security for a particular endpoint - security

I need to completely bypass security (authentication / authorization) for certain endpoints in my spring boot 2.0 app--endpoints like "/version" and "/robots.txt"--but keep security in place for all other endpoints.
To complicate matters, I'm working in a project that's a part of a much larger project. My company has another group that has supplied a library that makes use of spring security. This is only relevant because it means I cannot simply override a spring security class to make this work--those classes have already been overridden with code I don't control.
Is there a way to configure spring boot 2.0 to bypass authentication for certain endpoints?
In sprint boot 1.5, we could specify this in our application.yml file:
security.ignored: /version
but in spring boot 2.0 this no longer works.

Federico's answer is correct. I added the following class to my Spring Boot 2.0 class:
package com.example.demo;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
public class DemoConfigurer extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception{
http.authorizeRequests().antMatchers("/version").permitAll();
super.configure(http);
}
}
}

Related

Spring Reactive Cassandra, use custom CqlSession

How do we use a custom CqlSession on a Spring Webflux application combined with Spring starter reactive Cassandra please?
I am currently doing the following, which is working perfectly:
public class BaseCassandraConfiguration extends AbstractReactiveCassandraConfiguration {
#Bean
#NonNull
#Override
public CqlSessionFactoryBean cassandraSession() {
final CqlSessionFactoryBean cqlSessionFactoryBean = new CqlSessionFactoryBean();
cqlSessionFactoryBean.setContactPoints(contactPoints);
cqlSessionFactoryBean.setKeyspaceName(keyspace);
cqlSessionFactoryBean.setLocalDatacenter(datacenter);
cqlSessionFactoryBean.setPort(port);
cqlSessionFactoryBean.setUsername(username);
cqlSessionFactoryBean.setPassword(passPhrase);
return cqlSessionFactoryBean;
}
However, I would like to use a custom session, something like:
CqlSession session = CqlSession.builder().build();
How do we tell this configuration to use it?
Thank you
Option 1:
If you are looking to completely override the auto configured CqlSession bean, you can do so by providing your own CqlSesson bean ie.
#Bean
public CqlSession cassandraSession() {
return CqlSession.builder().withClientId(MyClientId).build();
}
The downside of override the entire bean is that you will lose the ability to configure this session via application properties and you will lose the defaults spring boot ships with.
Option 2:
If you want to leave the default values provided by spring boot and have the ability to configure the session via application properties you can use CqlSessionBuilderCustomizer to provide specific custom configurations to the CqlSession. This can be achieved by defining a bean of that type ie:
#Bean
public CqlSessionBuilderCustomizer myCustomiser() {
return cqlSessionBuilder -> cqlSessionBuilder.withClientId(MyClientId);;
}
My personal preference is option 2 as it maintains the functionality provided by spring boot which in my opinion results in an easier to maintain application over time.

I have to integrate ServiceStack together with Kephas. How do I make them both play together with Dependency Injection?

ServiceStack uses a dialect of Funq (no support for metadata), where Kephas uses one of MEF/Autofac (requires metadata support). My question has two parts:
How to make ServiceStack and Kephas use one DI container, if this is possible?
Depending on the answer above: how to make ServiceStack services (like IClientCache) available to Kephas components, knowing that such services may not be annotated with [AppServiceContract]?
You can make ASP.NET and Kephas use one container by choosing to work with Autofac. However, as #mythz pointed out, you will need to provide the Autofac IoC Adapter to the ServiceStack. I don't think you will have any problems with ASP.NET in doing so, as Autofac is the first recommendation of the ASP.NET Core team.
For ASP.NET Core, reference the Kephas.AspNetCore package and inherit from the StartupBase class if you need to be all setup. However, if you need to be in control, have a look at https://github.com/kephas-software/kephas/blob/master/src/Kephas.AspNetCore/StartupBase.cs and write your own Startup class. Another resource that you might find useful is the Kephas.ServiceStack integration package.
Then, additionally to annotating service contracts and service implementations, Kephas allows you to provide service definitions by implementing the IAppServiceInfoProvider interface. These classes are automatically discovered, so this is pretty much everything you have to do.
public class ServiceStackAppServiceInfoProvider : IAppServiceInfoProvider
{
public IEnumerable<(Type contractType, IAppServiceInfo appServiceInfo)> GetAppServiceInfos(IList<Type> candidateTypes, ICompositionRegistrationContext registrationContext)
{
yield return (typeof(IUserAuthRepository),
new AppServiceInfo(
typeof(IUserAuthRepository),
AppServiceLifetime.Singleton));
yield return (typeof(ICacheClient),
new AppServiceInfo(
typeof(ICacheClient),
ctx => new MemoryCacheClient(),
AppServiceLifetime.Singleton));
}
}
Note in the above example that for IUserAuthRepository there is no implementation provided. This indicates Kephas to auto-discover the implementation in the types registered for composition. Alternatively, feel free to use an instance or a factory in the registration, if you need to be deterministic.
I've never heard of Kephas before, but if you're referring to this Kephas Framework on GitHub it says it uses ASP.NET Core in which case it's best if you get them to both use ASP.NET Core's IOC which you can do by either registering your dependencies in ConfigureServices in your App's Startup:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//...
}
}
Or alternatively in ServiceStack's latest v5.6 release for Modular Startup change your ASP.NET Core Startup class to inherit from ModularStartup, e.g:
public class Startup : ModularStartup
{
public Startup(IConfiguration configuration) : base(configuration){}
public new void ConfigureServices(IServiceCollection services)
{
//...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
}
}
In which case you'll be able to Register ASP.NET Core dependencies in AppHost by registering them in your AppHost's Configure(IServiceCollection) where they can be resolved through both ASP.NET Core's IOC + ServiceStack's IOC, e.g:
public class AppHost : AppHostBase
{
public override void Configure(IServiceCollection services)
{
services.AddSingleton<IRedisClientsManager>(
new RedisManagerPool(Configuration.GetConnectionString("redis")));
}
public override void Configure(Container container)
{
var redisManager = container.Resolve<IRedisClientsManager>();
//...
}
}

Use SAP Cloud SDK to integrate with a custom backend service (oData) based on VDM Generator

I followed Alexander Duemont's blog, trying to implement a Java Spring Boot application that consumes Cloud Foundry Destination. The Destination has a custom OData V2 behind it, coming from an On-Premise ERP system. For local dev, when I perform the Maven build, the Integration-Tests module registers failure due to dependency injection
This is part of my Controller
#RestController
#RequestMapping("/resources")
public class ClassificationsController {
private static final Logger logger = CloudLoggerFactory.getLogger(ClassificationsController.class);
private final ClassificationService service;
public ClassificationsController(#Nonnull final ClassificationService service) {
this.service = service;
}
…..
}
The #Nonnull final ClassificationService Service causes org.springframework.beans.factory.UnsatisfiedDependencyException
I cannot use Spring stereotype annotations on generated Service classes (Fluent) to create Beans!
This question is more likely related to Spring Boot configuration.
I'm assuming ClassificationService is an interface and the implementing class exists in the same package.
Please make sure...
... to add the implementing class of ClassificationService to your component scan / test runtime. Feel free to share the integration test code to setup the test environment. Maybe the additional class reference is missing.
... to correctly annotate the respective Application class of your Spring Boot project. For example, assuming your ClassificationService resides in org.example.services.classification, while the rest of your application uses org.example.app. Your basic Application class would look like this, when following the Cloud SDK guide:
#SpringBootApplication
#ComponentScan({"com.sap.cloud.sdk", "org.example.services.classification", "org.example.app"})
#ServletComponentScan({"com.sap.cloud.sdk", "org.example.app"})
public class Application extends SpringBootServletInitializer
{
#Override
protected SpringApplicationBuilder configure( final SpringApplicationBuilder application )
{
return application.sources(Application.class);
}
public static void main( final String[] args )
{
SpringApplication.run(Application.class, args);
}
}
... to annotate the implementing class of ClassificationService with javax.inject.Named. In case you have multiple implementations of the same interface, make sure to give the not-used class a custom (unique) value for the #Named annotation.
... to look for exceptions (Class not found) in the application log during startup.

How to init Weld 3.0 cid setParameterName on Tomcat 8.5/Servlet 3.1

I'm trying to upgrade an old web app from JSF 2.1.1-FCS to 2.2.14 running in the Tomcat 8.5 Servlet 3.1 container.
The Mojarra JSF minimum requirements (for the latest version I guess, the page doesn't seem clear) says among other things that CDI 1.2 is required with 2.0 recommended.
I added cd-api-2.0 and weld-servlet-shaded-3.0.0.Final along with the other dependencies. Things seem to work until I test some URLs we've been using a long time. Our application has been using a cid parameter. Weld uses the same parameter to track conversations. As a result we get the WELD-000321: No conversation found to restore for id error.
I would like to call the org.jboss.weld.context.http.HttpConversationContext.setParameterName(String cid) as early as possible to modify the value for this web application.
What is the best way to change this value in a Servlet 3.1 Container Context like the one provided by Tomcat 8.5?
Initialize WELD_CONTEXT_ID_KEY in web.xml
Using the web.xml context-param WELD_CONTEXT_ID_KEY allowed me to override the Weld CDI conversation parameter key name from cid to a value of my choosing so I could preserve the legacy usage of cid in my upgraded application and avoid the WELD-000321 error.
<context-param>
<param-name>WELD_CONTEXT_ID_KEY</param-name>
<param-value>customValue</param-value>
</context-param>
This was the simplest solution, but I didn't make the association between that context parameter name and the conversation parameter key or error WELD-000321 when first reading the Weld documentation.
Or set programmatically
I was also able to override the parameter name / context id key programmatically from a custom ServletContextListener.contextInitialized method based on the SO example for getting rid of the NonexistentConversationException. Since I'm on Tomcat 8.5 (Servlet 3.1) I was able to use either #WebListener or the listener element in web.xml. It didn't seem to matter if my web.xml web-app version was the old 2.5 or if I updated it to 3.1.
package ssce;
import java.util.UUID;
import javax.inject.Inject;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.jboss.weld.context.http.HttpConversationContext;
#WebListener
public class MyServletContextListener implements ServletContextListener {
#Inject
private HttpConversationContext conversationContext;
#Override
public void contextInitialized(ServletContextEvent sce) {
hideConversationScope();
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
/**
* "Hide" conversation scope by replacing its default "cid" parameter name
* by something unpredictable.
*/
private void hideConversationScope() {
conversationContext.setParameterName(UUID.randomUUID().toString());
}
}

Weblogic Authenticate.authenticate equivalent in JBOSS 7

What is the equivalent code in JBOSS 7 for Weblogic's login security module code Authenticate.authenticate()
I recommend you toroughfully read JBOSS excellent migration guide .
WebLogic provides a proprietary ServletAuthentication class to perform programmatic login. In JBoss AS 7, you can use the standard Java EE6 Servlet 3.0 HttpServletRequest.login() method to perform programmatic login or you can define a element in the web.xml file.
To enable programmatic login, you must replace the WebLogic proprietary code with one of the following:
You can add the following annotations to the Servlet class that performs the authentication.
// Imports for annotations
import javax.annotation.security.DeclareRoles;
import javax.servlet.annotation.WebServlet;
import javax.servlet.annotation.HttpConstraint;
import javax.servlet.annotation.ServletSecurity;
#WebServlet("/securedUrlPattern")
#ServletSecurity(#HttpConstraint(rolesAllowed = { "myRole" }))
#DeclareRoles("myRole")
public class SecuredServlet extends HttpServlet {
//Rest of code
}
If you prefer not to use the standard servlet, you can instead add a element containing a dummy URL pattern to the web.xml file. This notifies JBoss to create a default Authenticator. Failure to create a element in the web.xml file may result in the error message "No authenticator available for programmatic login".
Another reason we should choose JBOSS over Weblogic

Resources