简体   繁体   中英

Accessing spring user in service layer and controllers - any update for Spring 3.2?

I want to access the current logged in user I am doing it like this (from a static method)

public static User getCurrentUser() {

final Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof User) {
  return (User) principal;
  }
}

or injecting and casting like this :

@RequestMapping(value = "/Foo/{id}", method = RequestMethod.GET)
public ModelAndView getFoo(@PathVariable Long id, Principal principal) {
        User user = (User) ((Authentication) principal).getPrincipal();
..

Where user implements userdetails, both seem a bit lame is there a better way in Spring 3.2 ?

I don't think that it has something new in spring 3.2 for that purpose. Have you thought about using a custom annotation?

Something like this :

The controller with the custom annotation :

@Controller
public class FooController {

    @RequestMapping(value="/foo/bar", method=RequestMethod.GET)
    public String fooAction(@LoggedUser User user) {
        System.out.print.println(user.getName());
        return "foo";
    }
}

The LoggedUser annotation :

@Target(ElementType.PARAMETER)
@Retention(RententionPolicy.RUNTIME)
@Documented
public @interface LoggedUser {}

The WebArgumentResolver :

public class LoggedUserWebArgumentResolver implements WebArgumentResolver {

    public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) {
        Annotation[] annotations = methodParameter.getParameterAnnotations();

        if (methodParameter.getParameterType().equals(User.class)) {
            for (Annotation annotation : annotations) {
                if (LoggedUser.class.isInstance(annotation)) {
                    Principal principal = webRequest.getUserPrincipal();
                    return (User)((Authentication) principal).getPrincipal();
                }
            }
        }
        return WebArgumentResolver.UNRESOLVED;
    }
}

Beans configuration :

<bean id="loggedUserResolver" class="com.package.LoggedUserWebArgumentResolver" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="customArgumentResolver" ref="loggedUserResolver" />
</bean>

I created a method much like your static, but put it in a new spring bean and inject that bean into the controllers (or objects at other layers) in which I need to get information about the user. That way I avoid the difficulties in testing code that depends on a static and all the code messing with the SecurityContext is nicely encapsulated into my bean (as you have in your static)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM