How to set a <context-param> in Spring Boot without web.xml? - spring-boot

I have a Spring Boot application. I basically need to set the following context parameter:
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
But my Spring Boot application doesn't have a web.xml. How can I set it programmatically?

Following other posts, I added a ServletContextInitializer implementation.
#Configuration
public class ConfigureJSFContextParameters implements ServletContextInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.setInitParameter("javax.faces.STATE_SAVING_METHOD", "client");
}
}

Related

Spring security login not showing

I'm adding Spring Security on a Spring MVC app; however, when I run the application, the Spring Security default login does not show up (not even when I browse to a link which is supposed to be "secured").
Configuration class (forgive the indentation):
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConf extends WebSecurityConfigurerAdapter {
#Autowired
private UserService userDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("**/secured/**").authenticated()
.anyRequest().permitAll()
.and()
.formLogin().permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder());
}
private PasswordEncoder getPasswordEncoder() {
return new PasswordEncoder() {
#Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return encode(rawPassword).equals(encodedPassword);
}
#Override
public String encode(CharSequence rawPassword) {
return rawPassword.toString();
}
};
} }
I also tried adding a custom login, but it does not seem to find the page (which is otherwise reachable):
http.authorizeRequests()
.antMatchers("**/secured/**").authenticated()
.anyRequest().permitAll()
.and()
.formLogin().loginPage('/login').permitAll();
Summing up, I need the default Spring Security login page to be displayed first, so I can test the authentication, then I need to be able to add a new login form to be displayed instead. What should I do?
EDIT: I figured out the configuration problem which prevented the Spring login to be displayed. The following tags had to be added in the web.xml file in order to integrate Spring Security with Spring MVC. Now the login is succesfully displayed.
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I figured out the configuration problem which prevented the Spring login to be displayed. The following tags had to be added in the web.xml file in order to integrate Spring Security with Spring MVC. Now the login is succesfully displayed.
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Enabling CORS Spring issue with Spring Security

I need to enable CORS for Spring application that uses Spring Security and it is not working. I am making GET request from http://localhost:3000 (which is node.js server) to http://localhost:8080 (which is Tomcat server).
I tried the following approaches but can not make any of them work:
https://spring.io/blog/2015/06/08/cors-support-in-spring-framework
Spring Data Rest and Cors
https://gist.github.com/zeroows/80bbe076d15cb8a4f0ad
Enabling CORS using Spring Boot 1.3.3-RELEASE
Spring CORS controller annotation not working
Currently I have a #Controller:
#Controller
#RequestMapping("/views")
public class LoginController{
#Autowired
private EventService eventService;
#RequestMapping(value = "/companies", method = RequestMethod.GET, produces = "application/json")
#ResponseBody
public String listCompanies(Model model) {
String companiesList = eventService.getCompanies();
return companiesList;
}
}
And AppConfig file where I have been unsuccessfully trying to allow CORS:
#EnableWebMvc
#Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
I want to somehow get the json from the listCompanies method in my Angular2 app. I am getting No 'Access-Control-Allow-Origin' header is present error, so I suppose it is CORS issue.
I had similar problem and fixed it with custom filter as described in documentation: 27.5 Filter based CORS support
Basically, you need to create filter:
public class MyCorsFilter extends CorsFilter {
public MyCorsFilter() {
super(configurationSource());
}
private static UrlBasedCorsConfigurationSource configurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.addAllowedMethod("*");
config.addAllowedHeader("*");
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}
and then add it in web.xml (or corresponding java based config) before springSecurityFilterChain like this:
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>com.example.configuration.cors.MyCorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>corsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I also have dispatchOptionsRequest (which is not necessary according to the new documentation):
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
...
<!-- "OPTIONS" method support -->
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
...
</servlet>
Did you defined somewhere the allowed origines in spring configuration? http://localhost:8080
#EnableWebMvc
#Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true);
}
}
Look at chapter 27.3 of official docs to enable global CORS configuration :
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html
If you don't need to include cookies on cross-origin request, replace .allowCredentials(true) by .allowCredentials(false)
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* Enabling CORS support - Access-Control-Allow-Origin
*
*
* <code>
<!-- Add this to your web.xml to enable "CORS" -->
<filter>
<filter-name>cors</filter-name>
<filter-class>com.elm.mb.rest.filters.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
* </code>
*/
public class CORSFilter extends OncePerRequestFilter {
private static final Log LOG = LogFactory.getLog(CORSFilter.class);
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*");
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
LOG.trace("Sending Header....");
// CORS "pre-flight" request
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
// response.addHeader("Access-Control-Allow-Headers", "Authorization");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Max-Age", "1");
}
filterChain.doFilter(request, response);
}
}

Spring web security 4 not working on the existing spring project with java based config

I developing spring 4 web project and angularjs app on front-end. I use java based spring security configuration. Now I try implement the Spring web security 4 for the user authorization. I created SecurityConfig class :
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
...
and added import annotation to main spring config class:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.gepick.*")
#EnableTransactionManagement
#Import({ SecurityConfig.class })
public class WebAppConfig extends WebMvcConfigurerAdapter{
...
If I understand well, now when open project on browser spring should redirect me to default spring security login form for authorization (.anyRequest().authenticated()), but in my situation not redirecting, but open web app without authorization form. Why?
Have you added the springSecurityFilterChain in your web.xml?
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

How to set order for SessionRepositoryFilter?

I am evaluating spring-session with my web application. During the very first request to the web app, multiple httpsession is being created for a single client. After debugging I found that the problem is, the response is committed earlier in the filter chain by ShallowEtagHeaderFilter before reaching SessionRepositoryFilter, so the cookie added to the response is not sent to the client. so, every further ajax request creates a new session, but the session id is not set in the cookie.
I'm trying to move SessionRepositoryFilter after ShallowEtagHeaderFilter. is there a way to do it?
filter config:
#Bean
public SessionRepositoryFilter sessionFilter(RedisOperationsSessionRepository sessionRepository) {
HttpSessionStrategy cookieStrategy = new CookieHttpSessionStrategy();
((CookieHttpSessionStrategy) cookieStrategy).setCookieName("JSESSIONID");
SessionRepositoryFilter sessionRepositoryFilter = new SessionRepositoryFilter(sessionRepository);
sessionRepositoryFilter.setHttpSessionStrategy(cookieStrategy);
return sessionRepositoryFilter;
}
filter is registered by:
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addFilter("sessionFilter", DelegatingFilterProxy.class)
.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
}
As you mentioned in the comment, you can register a filter for any url-pattern using web.xml:
<filter>
<filter-name>sessionFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Or in a spring way you can do it in the application configuration class, like this:
#Configuration
public class WebAppConfig implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) {
servletContext
.addFilter("sessionFilter", DelegatingFilterProxy.class)
.addMappingForUrlPatterns(null, false, "/*");
}
}

how to configure my application with spring security?

I am new with spring security I tried to read and there is alot of information and I don't know if I am in the right direction.
I have html file that the html element create with JS
lets assume that I have two input fields with ID ( html input fields )
emailInput and passwordInput
and button with ID ( html button )
loginLabel
I added the configuration to pring-security-config
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
</beans>
I added to web.xml
filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
I created Servlet Filer
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.authentication.builders.*;
import org.springframework.security.config.annotation.web.configuration.*;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
How i connect between the fields in the input ( the element are not from tag ) to the SecurityConfig ?
Do I need to create from element or I can do it without it ?
Do I need to create JSP file or is it ok to use html files ?
Step 1: Enable HTTP security.
Step 2: Turn on form login.
Step 3: Set the names of the username and password parameters expected in the login request.
Sample below:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.usernameParameter("emailInput")
.passwordParameter("passwordInput");
}
}

Resources