2014-06-16 105 views
4

我想在我的web應用程序中允許執行特別敏感的操作之前強制對證書進行重新身份驗證,例如將簽名添加到一組數據中。如何在Spring Security中強制重新驗證憑據?

這種情況是,用戶已經登錄,單擊以在數據上添加他們的簽名,並獲得字段輸入其憑據,然後傳遞到服務器進行身份驗證。失敗不會影響登錄狀態,只是拒絕該操作。

我正在使用Grails spring-security插件和LDAP(spring-security-ldap)進行身份驗證,但我假設一個解決方案將獨立於這些確切的細節。

我有服務器端(控制器/ servlet)上的用戶名和密碼值,我如何驗證這些新的憑據?

回答

5

您可以在控制器中重新使用您的用戶憑證和Spring Security基礎架構,而無需操縱當前身份驗證。 基本上,您的應用程序通過一個簡單的表單用戶名和密碼請求,並使用authenticationManager進行驗證。根據結果​​,您可以繼續使用您的應用程序邏輯或執行其他操作。

該示例顯示Spring MVC控制器內authenticationManager的用法。 不幸的是,我不是Grails用戶。給你一個例子,這個例子使用Java和Spring MVC。爲簡潔起見,省略了JSP。

可以找到一個完整的示例here(在Approval頁面下)。

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; } 
    } 
} 
+0

我可以在我的Grails控制器中使用這種確切的方法,只需包括自動裝配的AuthenticationManager,然後根據傳入的參數驗證新的令牌。我覺得這很簡單,我只是不知道我在做什麼......謝謝! – MarquisDeMizzle

+0

很高興聽到這個消息。 –

+0

我遇到的這個解決方案的一個問題是:'authenticationManager.authenticate(token);'會拋出一個RunTime異常:'AuthenticationException',如果我傳遞給它的憑據不正確,這意味着我的後續代碼永遠不會執行,並且用戶會登出。爲了解決這個問題,我不得不確保我在try/catch中明確地處理了任何'AuthenticationException'。 –

相關問題