Accessing HttpServletRequest during DaoAuthenticationProvider authenticate in Spring Security - spring

I need to access the HttpServletRequest object from within my DaoAuthenticationProvider in Spring security.
The security component extends the DaoAuthenticationProvider and we override the authenticate method to perform some custom authentication / validation. The additional check is required to validate user's ip-address which comes in the request url as a query string parameter (Ex: http://domain.com/context?ip=192.168.0.1).
The current approach I am trying is to make use of RequestContextHolder thread-local and get the http request in my custom DAOAuthenticationProvider.
Some other solutions that I read here and on spring forums seems to suggest to inject AuthenticationDetailsSource, use of custom-filter and other steps which I don't understand due to being new to spring security.
We would have different web applications which use the same security component to perform authentication.
Can someone please point me in a correct direction or help me with any approaches implemented previously ?

You can use RequestContextHolder and it effectively contains the same request, though Spring Security will usually wrap the incoming request, so you may get a different reference depending on whether you place the RequestContextFilter before or after the Spring Security chain (note that you could easily check this yourself by comparing the value returned from RequestContextHolder with the request in an application controller).
It is also relatively easy to inject a custom AuthenticationDetails as you mentioned:
package com.mycompany;
public class MyWebAuthenticationDetailsSource implements AuthenticationDetailsSource {
public Object buildDetails(Object context) {
return ((HttpServletRequest)context).getParameter("ip");
}
}
Then use
<bean id="ads" class="com.mycompany.MyWebAuthenticationDetailsSource />
<bean id="formLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationDetailsSource" ref="ads" />
<property name="authenticationManager" ref="authenticationmanager" />
</bean>
and add this as a custom filter as described in the reference manual. In 3.1 the namespace supports this directly in the form-login element. Authentication.getDetails() will then return the value of your "ip" parameter.
Note that you probably shouldn't be using 3.0.4, as it has known security vulnerabilities.
Also, can you explain how the "ip" parameter is being set?

You can add Spring's RequestContextFilter in your web.xml. This way, attributes will be saved on current thread on every request. Then, you can get original HtttpServletRequest:
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = attributes.getRequest();

Related

How to handle Privilege Escalation in Spring application

We have an application with 3 different user roles as User, Author & Admin. Each access role is having different set of menus and screens.
Issue is even though Menu item is hidden if we capture the admin URL and past it in user login it is opening the page. All action on the page will not work but still we are planning to restrict the page opening as well.
Only way I could see how we can handle is write a condition in each action to validate the access before opening the page. But with this approach we should touch many files, is there any best way to handle this situation.
Our application is written using Spring MVC framework.
Thanks.
You asked:
But with this approach we should touch many files, is there any best
way to handle this situation.
From Spring MVC HandlerInterceptor javadoc:
"Applications can register any number of existing or custom
interceptors for certain groups of handlers, to add common
preprocessing behavior without needing to modify each handler
implementation."
What you may do:
Write a custom HandlerInterceptor which should extend
HandlerInterceptorAdapter.
Override the boolean preHandle() method. This method is invoked just before the handler is invoked. So you can check access of logged in user (maybe from session). You can write a custom response from within this method.
Register the interceptor in your dispatcher-servlet.xml.
For example:
public class AuthInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String uri = request.getRequestURI();
User user = (User) request.getSession().getAttribute("foo"); //for example
if (...) { //check access to this uri, if access fails
response.sendRedirect("/to/some/url");
return false;
}
return true;
}
}
And register this HandlerInterceptor to dispatcher-servlet.xml:
<mvc:interceptors>
<bean class="your.package.AuthInterceptor"/>
</mvc:interceptors>
You can configure this interceptor to be more url-specific. See Spring Reference and Spring javadoc.

How can I extend the parameters of the OAuth2 authorization endpoint?

I'm having some trouble regarding the authorization endpoint of my Spring based OAuth2 provider. I need more information from the client than there is currently possible. This is what I want to achieve:
I need the custom parameter in the authentication process later on. Is there any simple way to extend the default parameters with my custom one or do I need to implement a certain class myself?
Did some research on how the authentication endpoint works in the current Spring code. I found that the Authorization Endpoint uses a method named authorize that takes all the parameter that are being set and converts then into an AuthorizationRequest. While looking further into the AuthorizationRequest class I found that it holds a map with extensions that is being filled throughout the authorization process. But it does not seem to get filled with my custom parameter (as shown above). This is in fact by only looking at the code, so I might be wrong.
Would it be a good idea to extend the AuthorizationEndpoint with my custom implementation or is there a better and cleaner way to do this?
Update #1 (07-10-2015)
The place where I'd like to use the custom parameter is in my own implementation of the AuthenticationProvider. I need to information to be available inside the authenticate method of this class.
Update #2 (07-10-2015)
It seems that the AuthorizationProvider gets called before the AuthorizationEndpoint. This means that the custom parameter is obtained after the class where I need it (so that's too late).
Maybe I can get the referral Url by either extending part of the Spring security classes or by obtaining it in the HTML through JavaScript. Is this a good idea or should I use another approach?
So I managed to fix the problem myself by searching some more on Google.
What you need to do is speak to the HttpSessionRequestCache to get the referral URL. This is how I solved it in my own implementation of the AuthenticationProvider
#Component
public class CustomProvider implements AuthenticationProvider {
#Autowired
private HttpServletRequest httpRequest;
#Autowired
private HttpServletResponse httpResponse;
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
SavedRequest savedRequest = new HttpSessionRequestCache().getRequest(httpRequest, httpResponse);
logger.info("Referral URL: " + savedRequest.getRedirectUrl());
logger.info("Parameters: " + savedRequest.getParameterMap().keySet().toString());
}
}
This will print out the URL of the request that was called before heading to the login page of spring security. The second log method prints out the parameters that where found in this URL. This question and answer helped me in creating a solution for my problem.

Spring Security: how to make listener for opening any page by user?

I need to handle user's request any time when he trying to load some page. At this listener i need to make some special checks, and, in result, close or not close user's session. How i should implement this? Looks like a common task, but i'm pretty new to spring and spring security.
I think of a listener as something that observes behaviour but doesn't affect behaviour. Since you mention closing the user's session, this is definitely affecting the user. Therefore, I think you are talking about an interceptor/filter rather than listener.
Spring provides a good interceptor framework for something like this.
However, since you are talking about sessions, this is the domain of spring security. Looks like there is another way to handle session management here: Is it possible to invalidate a spring security session?
Like Lithium said, a filter would supposedly be appropiate to handle the given task. Spring Security uses it's own filter chain (link points to 3.1.x docs), to which you can add your own filters - be careful about the positioning of your filter in the chain, here are some notes on ordering.
Depending on your requirements, such a filter could for example redirect the user to another page than the requested one one stop executing the filter chain - again: positioning in the filter chain is vital.
I think you should try interceptor. Little more details:
Create HandlerInterceptor class
public class RequestInitializeInterceptor implements HandlerInterceptor {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//Code to perform database checks
}
}
Define interceptor in servlet-context.xml (ApplicationContext for Servlet) file
<mvc:interceptors>
<mvc:interceptor>
<!-- Update path as per you requirement --!>
<mvc:mapping path="/**"/>
<bean class="com.abc.web.support.RequestInitializeInterceptor" />
</mvc:interceptor>
</mvc:interceptors>

Managing custom Acccept header in Spring MVC

I have a RESTful web service developed using Spring MVC and without any configuration I can return objects from my #ResponseBody annotated controller methods that get serialized to JSON. This works as soon as the Accept header in the request is not set or is application/json.
As I'm getting inspired by the GitHub API specification, I wanted to implement custom mime type for my API as GitHub does, for example: application/vnd.myservice+json. But then I need to tell Spring MVC that my controllers can provide this mime type and that it should be serialized by Json (i.e org.springframework.web.servlet.view.json.MappingJacksonJsonView class).
Any idea how to do it?
You can probably do exactly what is being done with org.springframework.http.converter.json.MappingJacksonHttpMessageConverter. Since it is not a final class, you can derive your converter from this one this way:
class MyCustomVndConverter extends MappingJacksonHttpMessageConverter{
public MyCustomVndConverter (){
super(MediaType.valueOf("application/vnd.myservice+json"));
}
}
then register your converter this way:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="MyCustomVndConverter "/>
</mvc:message-converters>
</mvc:annotation-driven>
It should just work with these changes

How to set content-length after a view is resolved using spring mvc?

We're using Spring MVC (3.0.5) for an API we are building. However, we have discovered that the application does not always return a content-length in the response header. Why I haven't figured out as yet. We can not manually set the content-length in the controller (request.setContentLength(x)) because we only use a subset of the data we get with the controller in our Freemarker view. So basically what we need is to calculate and set the content-length after a view has been resolved/compiled and just before it is actually sent to client.
Are there any common ("good praxis") ways to do this? Or even "ugly" ways?
Intercept your requests by implementing the HandlerInterceptor interface. The afterCompletion method runs after the view is resolved, so you should be able to set the value there, as that method's signature passes the HttpServletResponse. Configure thusly:
<!-- Configures Handler Interceptors -->
<mvc:interceptors>
<bean class="com.myapp.web.interceptor.MyInterceptor" />
</mvc:interceptors>
Here's some basic code:
#Component
public class MyInterceptor implements HandlerInterceptor {
}

Resources