Кастомизация spring security для spring-MVC
От: Sash_net  
Дата: 15.01.13 23:14
Оценка:
Приветствую

Нужно настроить спринг секюрити в проекте таким образом чтобы можно было получать респонс-результат аутентификации либо в виде страницы, либо в виде json-a. Идеально было бы чтобы поддерживалось обращение к spring security по 2м разным линкам: сабмит формы с креденшелсами на 1й из них предполагает ответ в виде страницы, сабмит на 2й — ответ в виде json-a.

Часть (не полностью рабочего) конфига security-context.xml которая может помочь понять что я хочу сделать:

    <http auto-config="true" use-expressions="true" access-denied-page="/accessDenied.jsp" >
        <form-login 
            login-processing-url="/j_spring_security_check"
            login-page="/login"
            default-target-url="/loginsuccess"
            authentication-failure-url="/loginfailed"/> 
            
        <form-login 
            login-processing-url="/j_spring_security_check_json"
            always-use-default-target="true"
            default-target-url="/loginsuccess_json"
            authentication-failure-url="/loginfailed_json"/> 

        <logout logout-url="/j_spring_security_logout" logout-success-url="/homepage"/>


Соответствующие обработчики в классе-контроллере:

    @RequestMapping(value="/loginfailed", method = RequestMethod.GET)
    public String loginError(ModelMap model) {
        model.addAttribute("error", "true");
        return "login";
    }
    
    @RequestMapping(value="/loginsuccess", method = RequestMethod.GET)
    public String loginSuccess() {
        return "homepage";
    }
    
    @RequestMapping(value="/loginfailed_json")
    public @ResponseBody IResult<Object> loginErrorJson() {
        return new Result<Object>(ResultCode.LOGIN_CREDENTIALS_IS_INCORRECT);
    }
    
    @RequestMapping(value="/loginsuccess_json")
    public @ResponseBody IResult<Object> loginSuccessJson() {
        return new Result<Object>();
    }



2й форм-логин конфиг естественно не работает, выдает 404 ошибку при переходе на соотв. урл. Если убрать 1й формлогин а login-processing-url второго заменить на дефолтовый — получение ответа в виде json работает.

Можно ли и как можно такое реализовать? А именно: сконфигурировать так чтобы поддерживалась отправка формы с логином/паролем на оба урла, как на дефолтовый /j_spring_security_check так и на 2й /j_spring_security_check_json. Результат обработки формы на стороне сервера должен быть корректным и отличатся только тем какие пары обработчиков контроллера вызываются в зависимости от результата аутентификации и что в итоге возвращается клиенту — html или json.

Спасибо.
Re: Кастомизация spring security для spring-MVC
От: Sash_net  
Дата: 17.01.13 12:41
Оценка:
Задача реализована написанием своего обработчика в классе-контроллере:

    @Resource (name= "authenticationManager")
    private AuthenticationManager authenticationManager;

    @RequestMapping(value="/security_check_json")
    public @ResponseBody IResult<Object> loginJson(
            @RequestParam(required=true, value="j_username") String email, 
            @RequestParam(required=true, value="j_password") String password,
            @RequestParam(required=false) String rememberMe,
            HttpServletRequest request) {
        
        IUser user = userService.getUserByEmail(email);
        if(null != user) {
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(email, password, user.getAuthorities());
            token.setDetails(new WebAuthenticationDetails(request));
            Authentication authenticatedUser;
            try {
                authenticatedUser = authenticationManager.authenticate(token);
            } catch (AuthenticationException e) {
                return new Result<Object>(ResultCode.LOGIN_CREDENTIALS_IS_INCORRECT);
            }
            SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
            if("on".equalsIgnoreCase(rememberMe)) {
                //TODO: remember
            }
        } else {
            return new Result<Object>(ResultCode.LOGIN_CREDENTIALS_IS_INCORRECT);
        }
        return new Result<Object>(ResultCode.SUCCESS);
    }


С реализацией rememberMe разбираюсь, по статье здесь.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.