Passing a password for methods for Spring MVC Controller - AOP or Spring Security?
I have been using Spr开发者_StackOverflow中文版ing MVC for a short while now with annotated controllers for JSP pages. I have a class similar to this:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
public class AdminController {
@RequestMapping(value = "/doStuff1.htm", method = RequestMethod.POST)
public void doStuff1(@RequestParam("password")String password) {
// do some stuff
}
@RequestMapping(value = "/doStuff2.htm", method = RequestMethod.POST)
public void doStuff2(
@RequestParam("password")String password,
@RequestParam("foo")String foo{
// do some stuff
}
}
As you can see, every call will have a password param passed in. The password is read from a dialog and passed into every call that is submitted.
I would like to get rid of the password parameter from the method calls to have 'cleaner' code.
I had a quick look at Spring security for this purpose but it seemed a bit heavyweight. Maybe AOP can be used?
Is there an obvious solution I'm missing?
Many thanks, - Scott
As you can see, every call will have a password param passed in. The password is read from a dialog and passed into every call that is submitted.
a) This is an awful practice. It means that anybody with a network sniffer will be able to see your password all over the place. It might be ok to submit the password once (although it would be better to use a secure way to transmit the password), but then the session should contain the authentication token
b) Password only? Never use a password without a username! With a brute force attack, any standalone-password will eventually be hacked, but username / password combinations are much more difficult to crack.
c) Your controller methods should not know or care about passwords. It's not their concern. They have work to do, dealing with passwords /security is a cross-cutting concern and should not be implemented on the controller level. Which leads us to the Question:
What to use: AOP or Spring Security?
AOP is a very powerful way of implementing cross-cutting functionality, but it has some drawbacks:
- if you use Spring AOP, advising controllers will only work if you either use interface-backed proxies (and defining interfaces for code that's never called via Java is a bit awkward) or use CGLib-based subclasses through
proxy-target-class="true"
(in XML config). The latter has funny side effects like double execution of constructors. Many use it, but I would advise against it. Which means Spring AOP is not a good choice. - if you use static AspectJ compilation however, you are hardwiring your security concerns into the application code. Security settings should be configurable without recompiling classes, so I'd say we have a no-go here as well.
So my suggestion is:
Use Spring Security
Spring Security is a custom solution for doing exactly what you want: securing Spring based sites (using Spring MVC or another web framework). While Spring Security can be a huge monster, in most cases, the configuration needed is minimal:
<http auto-config='true'>
<!-- restrict all URLs to role ROLE_USER -->
<intercept-url pattern="/**" access="ROLE_USER" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<!-- define two users, jimi and bob -->
<user name="jimi" password="jimispassword"
authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="bobspassword"
authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
(Taken from the section A Minimal <http>
Configuration)
As mentioned in the previous post its better to submit the login data only once per session and store an authententication token inside the user session.
For checking the token you can implement the HandlerInterceptor
interface from the springframework.
For example
public class MyHandlerInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//check authentication
}
}
and the configuration:
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<bean id="myInterceptor" class="...MyInterceptor"/>
</list>
</property>
精彩评论