Spring security auto authorization for a given IP - java

Is it possible in the Spring Security to (well it is Java, of course possible, so quesiton is - is it possible in some relatively painless way) automatically authorize all requests from local host (OK, some given IP) as a request that belongs to a given test user.
For instance in some filter - take all requests, check IP and if it comes from local host say something like spring.authorizeAs("user")

This answer for the similar question may help you. Based on your requirements you build principal and set it manually to Security Context.

In my case answer is following
#Component
public class LocalAuthFilter implements Filter {
#Autowired
private UserDetailsService mng;
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
if (("127.0.0.1".equals(req.getRemoteAddr())) &&
("anonymousUser".equals(SecurityContextHolder.getContext().getAuthentication().getPrincipal()))) {
UserDetails userDetails = mng.loadUserByUsername("user"); //my test user
Authentication auth = new UsernamePasswordAuthenticationToken(
userDetails.getUsername(),
userDetails.getPassword(),
userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(req, resp);
}
#Override
public void destroy() {
}
}

Related

Spring Boot Controller to handle all requests for preprocessing before forwarding to appropriate Controller

I have a series of Rest API Controllers in my Spring boot application with Request Mappings that match certain URLs.
I need to change my implementation to always make sure that a specific custom header is in place for all requests. If header is not there I want to fail the request. If it is I want to forward to the appropriate controller which would be the same as my current implementation.
Is there a way to do this in Spring Boot without modifying my existing controllers at all? Could I try to use something like Spring Security, even though my header is not related to security at all?
Thank you.
Web MVC defines an abstraction called "HandlerInterceptor" and its no-op implementation HandlerInterceptorAdapter
So you can register the bean that looks like this:
#Component
public class RequestProcessingTimeInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// check the headers, extract them from request, whatever
return true; // if you want to proceed to controller
return false;// otherwise :)
}
}
This will instruct spring mvc to call the method before the flow gets to the controller.
You can configure a Filter as a #Service.
#Service
#NoArgsConstructor #Log4j2
public class FilterImpl implements Filter {
#Override
public void init(FilterConfig config) throws ServletException { }
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (request.getHeader("required-header-name") != null) {
chain.doFilter(request, response);
} else {
log.info("Rejected {}", request);
}
}
#Override
public void destroy() {
}
}

get client ip address in spring boot security

This is my first question here, I'm sorry if there is something wrong, please correct me).
I am working on a spring boot application with spring boot security.
I use RestController for the creation of my API.
I need to log the IP address of all clients who try to access my API, even if they are not authenticated.
I can get the client's IP after authentication or when the client accesses to the public API by this (get from HttpServletRequest):
#GetMapping("/api/public/getDeviceList")
public List<Device> getDeviceList(HttpServletRequest httpServletRequest) {
System.out.println(httpServletRequest.getRemoteHost());
}
But when the client accesses a private API with wrong credentials, I don't get these IP addresses.
How can I retrieve this information?
The method getRemoteHost() returns the name of the client system as a string.
The method getRemoteAddr() returns the client's IP address that's accessing your Java web application
Try with this on your method controller
System.out.println(httpServletRequest.getRemoteAddr());
If your server is local it will return you 0:0:0:0:0:0:0:1 but if you test on another computer on your local network, the correct ip should be shown, for example 192.168.1.4
I get solution in adding custom filter in security chain. In this filter i can log all information i need. Create filter:
public class CustomSecurityFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
System.out.println("Enter custom filter");
System.out.println("method:"+request.getMethod() + "\nurl:"+request.getRequestURI()+"\nip address:"+request.getRemoteAddr());
filterChain.doFilter(servletRequest, servletResponse);
}
}
then add this filter in WebSecurityConfigurerAdapter in configure(HttpSecurity http) method
#Configuration
#EnableWebSecurity
public class RestSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors();
http.csrf().disable().authorizeRequests()
.antMatchers("/api/private/**").authenticated()
.and().httpBasic()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// -----Add new filter in chain-----
http.addFilterBefore(new CustomSecurityFilter(),
SecurityContextPersistenceFilter.class);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/public/**");
}
}

How to rewrite URLs according to DB records in Java EE

I am developing a JAX-RS multi-domain application. This application is supposed to be addressed by different domain names and shall handle these domains differently. Each domain is a record in DB and maps the domain name to UUID. Records of all domains are set to the same server IP. UUIDs are used internally as a path parameter (for example: https://{IP}/{uuid}).
I would like to achieve the following state:
https://domain1.com/{someResource} --> https://{serverIP}/domain/123e4567-e89b-12d3-a456-426655440000/{someResouce}
The illustration case:
The user accesses the resource on the URL https://my-domain.com/rest/v1/details and the server serves the details about the current domain (and similarly in other requests).
My idea was to implement a ContainerRequestFilter which would add information about requested URL (and hostname) like it works in authentication filters. The second approach was to use the Ocpsoft Rewrite library but I failed in setting it up and the documentation is not very rich in this topic.
Hi achieved it by using javax.servlet.Filter
Check it out:
#ApplicationScoped
#WebFilter(filterName = "MyAwesomeFilter", urlPatterns = {"/*"})
public class MyAwesomeFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
final String s = request.getRequestURI() + "/addedSomething"
request.getRequestDispatcher(s).forward(request, servletResponse);
}
#Override
public void destroy() {
}
}

any way to route all the requests to a method before they are redirected to the correct ones in servlet?

I'm trying to see if there's a way to pre-check all the requests before they are routed to the correct method?
all of my requests would have version# in param. it would be really helpful to check that at first place and decide whether the client needs to upgrade or not. it is a bit painful to check in all the methods, so I was wondering if there's a way to 'filter' the request at first. Thanks!
What you want is called a Filter.
See The Essentials of Filters
Example
#WebFilter( urlPatterns = "/*" ) // Filter all URLs
public class VersionFilter implements Filter {
#Override
public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException {
// TODO Do your filtering here
}
#Override
public void init( FilterConfig filterConfig ) throws ServletException { ... }
#Override
public void destroy() { ... }
}

Register filter in Java spring

I am trying to create filter that should be invoked on every request and check if user is authorizated. My implementation is text-book like.
#WebFilter("/*")
public class MiddleWareAuth implements Filter {
#Override
public void destroy() {
// ...
}
#Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("hi");
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
String xHeader = ((HttpServletRequest)request).getHeader("Authorization");
System.out.println("I am here");
System.out.println(xHeader);
}
}
However what troubles me is that i am not sure where i should register the filter, to let spring know that it should put every request through it.
I read that i should use <filter> tag in web.xml file , however my project does not have such file.
I am running my project on intelij 2017.
Where should i let spring know to register my filter?
Thanks for help!.

Categories