First of all I'm saving a user in SessionStorage in React.
The problem is that I'm trying to make a filter that validates some data in the user saved in SessionStorage.
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String urlRequest = String.valueOf(httpServletRequest.getRequestURL());
HttpSession sesion = ((HttpServletRequest) request).getSession();
System.out.println(sesion.getAttribute("id")); // This is null
filterchain.doFilter(request, response);
}
The thing is that the session always returns null
Related
I am using Spring Boot 2.2.4.RELEASE with Spring Cloud Hoxton.SR1 and without Spring Security, In that GET method is working fine but POST & PUT methods are not working.
#Configuration
#Order(value = Integer.MAX_VALUE)
public class WebConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:5500")
.allowedHeaders("*")
.allowedMethods("POST", "PUT", "DELETE", "HEAD");
}
}
#Component
public class SimpleCORSFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
chain.doFilter(req, response);
}
#Override
public void init(FilterConfig filterConfig) {
}
#Override
public void destroy() {
}
}
AngularJS Code
$http({
method: 'POST',
url: 'http://b28c-103-85-11-107.ngrok.io/game/brand-styles',
data: {
"fontColour": "FFFFFF",
"backgroundColour": "006400",
"displayType": 1,
"buttonColour": "FFC314"
}
})
.then(function (response) { $scope.data = data; })
.catch(function (err) { console.log(err) });
I have tried multiple ways to solve the issue as suggested on same platform in different questions but no one worked for me.
Access to XMLHttpRequest at
'http://b28c-103-85-11-107.ngrok.io/game/brand-styles' from origin
'http://localhost:5500' has been blocked by CORS policy: Response to
preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
POST http://b28c-103-85-11-107.ngrok.io/game/brand-styles
net::ERR_FAILED
The possible reason behind the issue in your case would be due to the following statement that you've mentioned in the SimpleCORSFilter class.
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
Looks like Origin header is dropped before reaching to your local server or may be dropped by the local server itself. You can try with the following change to verify your case.
response.setHeader("Access-Control-Allow-Origin", "http://localhost:5500");
Controller.java
In Controller class,I have defined url and while accessing from browser its working fine.
But when accessing the same url request from Ionic program, getting CORS error.Due to this error i have added necessary content in doFilter method too.But still left helpless.
#RestController
#RequestMapping("/service")
public class Controller implements Filter {
#RequestMapping(value = "/name", method = RequestMethod.POST,
headers = "content-type=application/x-www-form-urlencoded",produces="application/json")
public String reg(#ModelAttribute Farmer farmer) {
System.out.println("Getting request from Mobile client...!!" + farmer);//farmer.firstName is null
String result = "Hello..!";
System.out.println("Request processed");
return result;
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
System.out.println("External request start..!!");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT,GET,DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, resp);
System.out.println("External request end..!!");
}
#Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
Farmer.java
public class Farmer {
private String firstName;
private String lastName;
//getters and setters
}
I have edited my question.Please do check it.
Thank you.
If you use chrome you must start it with the flag --disable-web-security or install the extension Allow-Control-Allow-Origin: *.
It's not a code problem, when you build your app with cordova or phonegap build the error message will not be throw.
Here is how I would do it, add this to a class annotated with component or configuration:
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/service/**").allowedOrigins("*").allowedMethods("GET", "POST","PUT", "DELETE");
}
};
}
After going with lot of trials and referring examples.Finally fixed this issue.So just thought of adding here.If in case anyone might need it.
This fixes just by adding
#CrossOrigin,#RestController,consumes="application/json" in your
controller method.
#CrossOrigin
#RestController
#RequestMapping("/service")
public class Controller implements Filter {
#RequestMapping(value = "/name", method = RequestMethod.POST,
headers = "content-type=application/x-www-form-urlencoded",consumes="application/json")
public String reg(#ModelAttribute Farmer farmer) {
System.out.println("Getting request from Mobile client...!!" + farmer);//farmer.firstName is null
String result = "Hello..!";
System.out.println("Request processed");
return result;
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
System.out.println("External request start..!!");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT,GET,DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, resp);
System.out.println("External request end..!!");
}
#Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
Thank you
Currently I'm developing Spring OAuth2 security project with Angularjs. I'm taking a token with oauth server and I'm parsing to headers but when I try to redirect to home page I'm thrown by "Full authentication is required to access this resource" but I loged in and client server gives an anonymousUser and access denied.
#Configuration
#EnableWebSecurity
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/login.html")
.antMatchers("/js/**")
.antMatchers("/css/**")
.antMatchers("/metronic/css/**")
.antMatchers("/metronic/js/**")
.antMatchers("/metronic/image/**")
.antMatchers("/image/**")
.antMatchers("/language/**")
.antMatchers("/404.html")
.antMatchers("/logout")
.antMatchers("/kilitEkrani.html")
.antMatchers("/metronic/css/fonts/**")
.antMatchers("/metronic/fonts/**");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/css/**", "/metronic/css/**").permitAll()
.and().authorizeRequests().antMatchers("/metronic/image/**", "/image/**", "/metronic/css/fonts/**", "/metronic/fonts/**").permitAll()
.and().authorizeRequests().antMatchers("/js/**", "/metronic/js/**").permitAll()
.and().httpBasic().and().authorizeRequests()
.antMatchers("/login.html", "/language/**", "/api/kullanici/user", "/logout", "/kilitEkrani.html", "/404.html").permitAll()
.anyRequest().authenticated().and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class).csrf().csrfTokenRepository(csrfTokenRepository()).and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login.html")
.permitAll().and().csrf().disable();
}
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
#Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}
This is my security config. Am I missing something? Help please...
I think the problem is that you make use of basic authentication in the auth server. You can try to disable the basic authentication and use form authentication instead.
I found that while accessing ReST services from single-page applications that in order to properly allow access to ReST endpoints I had to register a CORS filter before my authentication filter. Is this less secure or a poor security practice?
My security configuration now looks like
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Inject
public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/health","/metrics", "/v1/users/register", "/swagger-ui/**", "/v2/api-docs").permitAll()
.antMatchers("/mappings", "/v1/**", "/backend-service/**").authenticated()
.and()
.httpBasic()
.realmName("serviceGateway")
.and()
.csrf()
.disable()
.headers()
.frameOptions().disable()
.and().addFilterBefore(new SimpleCORSFilter(), ChannelProcessingFilter.class);
}
}
And my SimpleCORSFilter looks like
public class SimpleCORSFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* This method adds specific headers to the HTTP request to enable CORS
* requests
* #param request
* #param response
* #param chain
* #throws IOException
* #throws ServletException
*/
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
res.setHeader("Access-Control-Max-Age", "3600");
res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control");
chain.doFilter(request, res);
}
#Override
public void destroy() {
}
}
I access the code with a simple $http call in Angular
$scope.login = function() {
$http({
method: 'GET',
url: 'https://myservice.mydomain.com:8095/v1/users/login',
headers: {
'Authorization': 'Basic ' + btoa("username:password")
}
})
.then(successCallback);
};
I am thinking that putting the CORS filter before security only means that the CORS headers will be added to every request, which doesn't seem like much of a security hole since I send no sensitive data in headers, excepting the Authorization header.
Am I thinking right here or is there something I am not seeing?
I think this is perfectly fine. In fact when your JavaScript code posts to a resource in another origin, the browser will issue a pre-flight request (OPTIONS verb) without the authorization header.
If your authentication code runs before the CORS handler, it has to make an exception for this request, to avoid returning 401 Unauthorized on the pre-flight.
Is it possible to access/create the HttpSession in the preProcess method of a PreProcessInterceptor?
(RestEasy 2.3.4)
You can access the HttpSession by injecting the HttpServletRequest using the #Context annotation and then getting the session from the request like so:
#Context
private HttpServletRequest servletRequest;
#Override
public ServerResponse preProcess(HttpRequest request, ResourceMethod method)
throws Failure, WebApplicationException
{
HttpSession session = servletRequest.getSession();
//Do something with the session here...
}