DandelionServlet is not being invoked - spring-security

Here is my problem. I'm trying to setup dandelion datatable on my Spring-boot Thymeleaf application. I believe I have everything wired correctly. I can take the javascript file from the AssetCacheManger that's in the logs and manually invoke the DandelionServlet from the URL, but it is not being invoke automatically as in the examples on GitHub. Also note I have Spring Security installed. Before posting I disabled security to make sure that wasn't an issue.
POM
<dependency>
<groupId>com.github.dandelion</groupId>
<artifactId>datatables-thymeleaf</artifactId>
<version>0.10.0</version>
</dependency>
JavaConfig
#Configuration
public class DandelionConfig
{
#Bean
public DandelionDialect dandelionDialect()
{
return new DandelionDialect();
}
#Bean
public DataTablesDialect dataTablesDialect()
{
return new DataTablesDialect();
}
#Bean
public FilterRegistrationBean dandelionFilterRegistrationBean()
{
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
DandelionFilter dandelionFilter = new DandelionFilter();
filterRegistrationBean.setFilter(dandelionFilter);
return filterRegistrationBean;
}
#Bean
public ServletRegistrationBean dandelionServletRegistrationBean()
{
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
DandelionServlet dandelionServlet = new DandelionServlet();
servletRegistrationBean.setServlet(dandelionServlet);
servletRegistrationBean.addUrlMappings("/dandelion-assets/*");
return servletRegistrationBean;
}
}
Here is the log portion that differs from the GitHub examples. No location found for delegate on AssetMapper
2015-06-17 12:57:51,503 Application: LMI [http-apr-8080-exec-7] DEBUG com.github.dandelion.datatables.core.configuration.DatatablesConfigurator - Initializing the Javascript generator...
2015-06-17 12:57:51,508 Application: LMI [http-apr-8080-exec-7] WARN com.github.dandelion.core.asset.AssetMapper - No location found for delegate on AssetStorageUnit [name=dandelion-datatables, version=0.10.0, type=js, dom=null, locations={delegate=dandelion-datatables.js}, attributes=null, attributesOnlyName=[]]
2015-06-17 12:57:51,513 Application: LMI [http-apr-8080-exec-7] DEBUG com.github.dandelion.core.asset.cache.AssetCacheManager - Retrieving asset with the key 591a4c961431b5fb3c6eedecfc5cca1b6ea5b09d/dandelion-datatables-0.10.0.js
2015-06-17 12:57:51,513 Application: LMI [http-apr-8080-exec-7] DEBUG com.github.dandelion.core.asset.cache.AssetCacheManager - Storing asset under the key 591a4c961431b5fb3c6eedecfc5cca1b6ea5b09d/dandelion-datatables-0.10.0.js
2015-06-17 12:57:51,518 Application: LMI [http-apr-8080-exec-7] WARN com.github.dandelion.core.asset.AssetMapper - No location found for delegate on AssetStorageUnit [name=dandelion-datatables, version=0.10.0, type=js, dom=null, locations={delegate=dandelion-datatables.js}, attributes=null, attributesOnlyName=[]]
2015-06-17 12:57:51,518 Application: LMI [http-apr-8080-exec-7] DEBUG com.github.dandelion.core.asset.cache.AssetCacheManager - Retrieving asset with the key 591a4c961431b5fb3c6eedecfc5cca1b6ea5b09d/dandelion-datatables-0.10.0.js
2015-06-17 12:57:51,518 Application: LMI [http-apr-8080-exec-7] DEBUG com.github.dandelion.core.asset.cache.AssetCacheManager - Storing asset under the key 591a4c961431b5fb3c6eedecfc5cca1b6ea5b09d/dandelion-datatables-0.10.0.js
Thanks,

With reference to this answer
Spring Boot + Thymeleaf + Dandelion configuration not working
Can you use this config instead
#Configuration
public class DandelionConfig {
#Bean
public DandelionDialect dandelionDialect() {
return new DandelionDialect();
}
#Bean
public DataTablesDialect dataTablesDialect(){
return new DataTablesDialect();
}
#Bean
public Filter dandelionFilter() {
return new DandelionFilter();
}
#Bean
public ServletRegistrationBean dandelionServletRegistrationBean() {
return new ServletRegistrationBean(new DandelionServlet(), "/dandelion-assets/*");
}
}
along with these dependencies
<dependency>
<groupId>com.github.dandelion</groupId>
<artifactId>datatables-thymeleaf</artifactId>
<version>0.10.1</version>
</dependency>
<dependency>
<groupId>com.github.dandelion</groupId>
<artifactId>datatables-spring3</artifactId>
<version>0.10.1</version>
</dependency>

I created a simple Spring Boot application using Thymeleaf and Dandelion-datatables.
You can get the code here https://github.com/ohiocowboy/datatable-thymeleaf-spring-boot-starter

Related

How to whitelisting Ip Address in spring security 6 [duplicate]

I've read in Spring Security Reference that AuthorizationFilter supersedes FilterSecurityInterceptor. So I'm trying to migrate my application to this newer method.
I have something like
http.authorizeRequests()
.mvcMatchers("/")
.hasIpAddress("127.0.0.1")
According to the linked page I should be able to write something like
http.authorizeHttpRequests()
.mvcMatchers("/")
.access("hasIpAddress('127.0.0.1')")
but there's no access(String) method. I even tried to paste verbatim code from the documentation:
#Bean
SecurityFilterChain web(HttpSecurity http) throws Exception {
http
// ...
.authorizeHttpRequests(authorize -> authorize
.mvcMatchers("/resources/**", "/signup", "/about").permitAll()
.mvcMatchers("/admin/**").hasRole("ADMIN")
.mvcMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().denyAll()
);
return http.build();
}
which does not compile for the same reason.
Here's compilation error:
Application.java:103:55
java: incompatible types: java.lang.String cannot be converted to org.springframework.security.authorization.AuthorizationManager<org.springframework.security.web.access.intercept.RequestAuthorizationContext>
How do I use authorizeHttpRequests with IP addresses or string expression? Is it issue with documentation?
I'm using Spring Boot 2.7.0 and Spring Security 5.7.1
This does appear to be an issue with the docs. There is not currently a built-in implementation providing the hasIpAddress(String) access check, but you can use the IpAddressMatcher class to implement an AuthorizationManager capable of performing it.
Here's an example configuration:
#EnableWebSecurity
public class SecurityConfiguration {
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorizeRequests) -> authorizeRequests
.mvcMatchers("/").access(hasIpAddress("127.0.0.1"))
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.httpBasic(Customizer.withDefaults());
return http.build();
}
private static AuthorizationManager<RequestAuthorizationContext> hasIpAddress(String ipAddress) {
IpAddressMatcher ipAddressMatcher = new IpAddressMatcher(ipAddress);
return (authentication, context) -> {
HttpServletRequest request = context.getRequest();
return new AuthorizationDecision(ipAddressMatcher.matches(request));
};
}
}

JMX in SpringBoot Application. Not able to get MBean for classes that implement an Interface

I Have a SpringBoot application . I have used the Java config in the entire application and it is working fine.
Now I have a reqirement to configure JMX for the same.
After going through some tutorials I found that I need to give the following configuration in my spring boot to have the JMX enabled.
#Bean
public MetadataNamingStrategy getNamingStrategy() {
MetadataNamingStrategy strategy = new MetadataNamingStrategy();
strategy.setAttributeSource(new AnnotationJmxAttributeSource());
return strategy;
}
#Bean
public MetadataMBeanInfoAssembler getMbeanInfoAssembler() {
return new MetadataMBeanInfoAssembler(new AnnotationJmxAttributeSource());
}
#Bean
public MBeanExporter getExporter() {
MBeanExporter exporter = new MBeanExporter();
exporter.setAutodetect(true);
exporter.setNamingStrategy(getNamingStrategy());
exporter.setAssembler(getMbeanInfoAssembler());
return exporter;
}
After doing this , I am able to see the classes (and their attributes, and operations) in JMX console (on HCP).
But for the classes that implement an interface ,I am not able to see them on JMX console.
Example:
I have an interface TestInterface2.
package com.test.example;
public interface TestInterface2 {
public String simpleTest2();
}
The implementation of the interface goes below.
#Component("testInterfaceImpl2")
#ManagedResource(objectName = "com.test.example:type=TestInterfaceImpl2", description = "TestInterface2 Desc")
public class TestInterfaceImpl2 implements TestInterface2 {
#Override
public String simpleTest2() {
return "Simple Test";
}
}
I tried this. It is not working.
But the following am able see in JMX console
#Component
#ManagedResource(
objectName = "com.test.example:type=FormHandler",
description = "Form Handler implementation")
public class FormHandler {
#implementation details here
}
Can someone suggest the best approach for doing this or why am i not able to get the interface implementations as MBean .

HttpsUrlConnectionMessageSender

We are using spring-ws-core-2.2.3.RELEASE.jar for spring web service connections. In order to bypass/override invalid host (source and sender are not the same) for testing purposes, I am trying to do this:
public void setWebServicesTemplate(WebServicesTemplate template) {
HostnameVerifier verifier = new NullHostnameVerifier();
HttpsUrlConnectionMessageSender sender = new HttpsUrlConnectionMessageSender();
sender.setHostnameVerifier(verifier);
template.setMessageSender(sender);
this.template = template;
}
public class NullHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
I am not able to find this class in my version of spring-ws-core-2.2.3.RELEASE.jar, however I am able to see it in the previous and higher versions of the .jar.
You have to add the following dependency as this class is part of spring-ws-support:
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-support</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>

mdui metadata extension with spring-saml

i need to configure an SP with Spring SAML Extension, this time with a new idp admin request.
He ask me to send him metadata with mdui values like this:
<md:SPSSODescriptor> <Extensions> <mdui:UIInfo>
<mdui:DisplayName xml:lang="it">desc</mdui:DisplayName>
<mdui:InformationURL xml:lang="it">http://xxxx</mdui:InformationURL>
</Extensions>
....
</SPSSODescriptor>
I think i can do this operation with a non signed metadata with values added by hand.
It is the only way or can i obtain the same result with configuration options ?
thanks in advance.
Alessandro
Checkout the MetadataGenerator class of spring-security-saml. It has a buildExtensions method that is populating OpenSAML's Extensions object with the DiscoveryResponse extension if configured. You could possibly extend MetadataGenerator and hook in your configuration.
This is an excerpt of the buildExtensions method:
protected Extensions buildExtensions(String entityBaseURL, String entityAlias) {
boolean include = false;
Extensions extensions = new ExtensionsBuilder().buildObject();
// Add discovery
if (isIncludeDiscoveryExtension()) {
DiscoveryResponse discoveryService = getDiscoveryService(entityBaseURL, entityAlias);
extensions.getUnknownXMLObjects().add(discoveryService);
include = true;
}
if (include) {
return extensions;
} else {
return null;
}
}
If you're using Spring Boot you can use this library to configure SAML and provide the custom MetadataGenerator: spring-boot-security-saml
The configuration would look something like:
#Configuration
public static class MyServiceProviderConfig extends ServiceProviderConfigurerAdapter {
#Override
public void configure(ServiceProviderSecurityBuilder serviceProvider) throws Exception {
serviceProvider
.metadataGenerator(customGenerator);
}
}

How to secure reactor netServer with spring security?

I try to develop an "hybrid" server using spring boot webApplication with embedded tomcat and a netServer from reactor to scale-up my Rest Api.
There are no Spring controller, all the incoming request are handled by the netServer.
Never the less i'd like to have a login page using spring security remember me facilities to authenticate the user and use this authentication to secure incoming request on the reactor netServer.
I start to implements the netServer, according to this tutorial reactor thumbmailer
here is my netServer :
NetServer<FullHttpRequest, FullHttpResponse> server = new TcpServerSpec<FullHttpRequest, FullHttpResponse>(NettyTcpServer.class)
.env(env)
.dispatcher("sync")
.listen(8080)
.options(opts)
.consume(ch -> {
// attach an error handler
ch.when(Throwable.class, UserController.errorHandler(ch));
// filter requests by URI
Stream<FullHttpRequest> in = ch.in();
// serve image thumbnail to browser
in.filter((FullHttpRequest req) -> req.getUri().startsWith(UserController.GET_USER_PROFILE))
.consume(UserController.getUserProfile(ch));
})
.get();
So when a user try to load his profile, the incoming request is handled by the userController :
public static Consumer<FullHttpRequest> getUserProfile(NetChannel<FullHttpRequest, FullHttpResponse> channel) {
UserService userService = StaticContextAccessor.getBean(UserService.class);
return req -> {
try {
LoginDTO login = RestApiUtils.parseJson(LoginDTO.class, RestApiUtils.getJsonContent(req));
DefaultFullHttpResponse resp = new DefaultFullHttpResponse(HTTP_1_1, OK);
String result = userService.loadUserProfile(login);
resp.headers().set(CONTENT_TYPE, "application/json");
resp.headers().set(CONTENT_LENGTH, result.length());
resp.content().writeBytes(result.getBytes());
channel.send(resp);
} catch (Exception e) {
channel.send(badRequest(e.getMessage()));
}
};
}
Here is the hack : getUserProfile is a static methode, so i can't use GlobalMethodSecurity to secure it.
i then inject a userService in this controller using a StaticContextAccessor :
#Component
public class StaticContextAccessor {
private static StaticContextAccessor instance;
#Autowired
private ApplicationContext applicationContext;
#PostConstruct
public void registerInstance() {
instance = this;
}
public static <T> T getBean(Class<T> clazz) {
return instance.applicationContext.getBean(clazz);
}
}
UserService :
#Service
#PreAuthorize("true")
public class UserServiceImpl implements UserService{
public String loadUserProfile(LoginDTO login){
//TODO load profile in mongo
return new GsonBuilder().create().toJson(login);
}
}
the service is managed by spring so i guess i could use spring GlobalMethodSecurity on it (i m still developping this part, but i'm not sure this is the best way to secure my netServer)
Is there a easier way to use Spring security on reactor netServer ???
My first web site version was developped with nodeJS to handle many concurent users, and i try to refactor it using a JVM nio solution.
So is spring / reactor / netty a good solution to have a highly scalable server, or should i use something like play! or vertx.io ?
Thank you so much
Have you tried bootstrapping your NetServer from within a JavaConfig #Bean method? Something like:
#Configuration
#EnableReactor
class AppConfig {
public Function<NetChannel, UserController> users() {
return new UserControllerFactory();
}
#Bean
public NetServer netServer(Environment env, Function<NetChannel, UserController> users) {
return new TcpServerSpec(NettyTcpServer.class)
.env(env)
.dispatcher("sync")
.listen(8080)
.options(opts)
.consume(ch -> {
// attach an error handler
ch.when(Throwable.class, UserController.errorHandler(ch));
// filter requests by URI
Stream<FullHttpRequest> in = ch.in();
// serve image thumbnail to browser
in.filter((FullHttpRequest req) -> req.getUri().startsWith(UserController.GET_USER_PROFILE))
.consume(users.apply(ch));
})
.get();
}
}
This should preserve your Spring Security support and enable you to share handlers as beans rather than as return values from static methods. In general, just about everything you need to do in a Reactor TCP app can be done using beans and injection and by returing the NetServer as a bean itself.

Resources