如何在Spring Security中强制重新验证凭据?

时间:2014-06-16 23:18:46

标签: java authentication spring-security

我想在允许在我的Web应用程序中执行特别敏感的操作之前强制重新验证凭据,例如向一组数据添加签名。

场景是用户已经登录,点击以在数据上添加签名,并获得输入其凭据的字段,然后将其传递到服务器进行身份验证。失败不会影响登录状态,只是拒绝操作。

我正在使用Grails spring-security插件并对LDAP进行身份验证(spring-security-ldap),但我假设解决方案将独立于这些确切的细节。

我在服务器端(控制器/ servlet)上有用户名和密码值,如何验证这些新凭证?

1 个答案:

答案 0 :(得分:5)

您可以在控制器中重复使用您的用户凭据和Spring Security基础结构,而无需操作当前的身份验证。 基本上,您的应用程序通过简单的表单用户名和密码请求,并使用authenticationManager进行验证。根据结果​​,您可以继续使用应用程序逻辑或执行其他操作。

此示例显示authenticationManager控制器内Spring MVC的使用情况。 不幸的是,我不是Grails用户。为了给你一个可行的例子,这个例子是使用Java和Spring MVC。 为简洁起见,省略了JSP。

可以找到一个完整的示例here(在“审批”页面下)。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.Map;

@Controller
@RequestMapping("approval")
public class ApprovalController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @RequestMapping(value="confirm.do", method = RequestMethod.GET)
    public String get() {
        return "approval/confirm";
    }

    @RequestMapping(value="confirm.do", method = RequestMethod.POST)
    public String post(@ModelAttribute ApprovalRequestForm form, Map<String, Object> model, Authentication authentication) {
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(form.getUsername(), form.getPassword());
        Authentication authenticate = authenticationManager.authenticate(token);

        if(authenticate.isAuthenticated() && isCurrentUser(authentication, authenticate)) {
            //do your business
            return "approval/success";
        }

        model.put("reason", "credentials doesn't belong to current user");
        return "approval/denied";
    }

    private boolean isCurrentUser(Authentication left, Authentication right) {
        return left.getPrincipal().equals(right.getPrincipal());
    }

    @ExceptionHandler(Exception.class)
    public ModelAndView handleException(Exception exception) {
        ModelAndView model = new ModelAndView("approval/denied");
        model.addObject("reason", exception.getMessage());
        return model;
    }

    public static class ApprovalRequestForm {
        private String username;
        private String password;

        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }
}