我使用Spring Security來保護到網站的HTTP請求。主要用於保護頁面,以便在嘗試訪問這些頁面時將用戶重定向到登錄頁面。Spring Security自定義篩選器(更改密碼)
但是,我有進一步的要求。在我的模型中,我可以將用戶的密碼標記爲臨時密碼,以便當它們成功登錄時,它們應該被自動強制更改密碼。一旦密碼被改變,它們應該被轉發到他們最初嘗試訪問的頁面上。
有沒有人爲此使用Spring Security?我是否需要創建自己的自定義過濾器?
感謝,
安德魯
我使用Spring Security來保護到網站的HTTP請求。主要用於保護頁面,以便在嘗試訪問這些頁面時將用戶重定向到登錄頁面。Spring Security自定義篩選器(更改密碼)
但是,我有進一步的要求。在我的模型中,我可以將用戶的密碼標記爲臨時密碼,以便當它們成功登錄時,它們應該被自動強制更改密碼。一旦密碼被改變,它們應該被轉發到他們最初嘗試訪問的頁面上。
有沒有人爲此使用Spring Security?我是否需要創建自己的自定義過濾器?
感謝,
安德魯
在Spring Security 3.0可實現自定義AuthenticationSuccessHandler
。
在此處理程序中,您可以使用臨時密碼將用戶重定向到密碼更改頁面,而不是最初請求的頁面。密碼更改後,您可以使用默認處理程序實現SavedRequestAwareAuthenticationSuccessHandler
將用戶重定向到最初請求的頁面。
public class MyHandler implements AuthenticationSuccessHandler {
private AuthenticationSuccessHandler target = new SavedRequestAwareAuthenticationSuccessHandler();
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication auth) {
if (hasTemporaryPassword(auth)) {
response.sendRedirect("/changePassword");
} else {
target.onAuthenticationSuccess(request, response, auth);
}
}
public void proceed(HttpServletRequest request,
HttpServletResponse response, Authentication auth) {
target.onAuthenticationSuccess(request, response, auth);
}
}
@Controller("/changePassword")
public class ChangePasswordController {
@Autowired
private MyHandler handler;
@RequestMapping(method = POST)
public void changePassword(HttpServletRequest request,
HttpServletResponse response,
@RequestParam(name = "newPassword") String newPassword) {
// handle password change
...
// proceed to the secured page
handler.proceed(request, response, auth);
}
// form display method, etc
...
}
是的,我用過濾器ForceChangePasswordFilter做了這個。因爲如果用戶手動鍵入網址,他們可以繞過更改密碼錶單。通過篩選器,請求總是被攔截。
你會關心分享你的代碼嗎? – Jonathan 2013-07-24 08:52:45
喬納森,那是多年前,我現在無法訪問該代碼。 – rodrigoap 2013-07-24 15:24:10
rodrigoap我明白。我分享同樣的觀點,如果你使用成功處理程序,用戶仍然可以通過直接在地址欄中寫入URL來訪問其他頁面。但基本上,你能分享至少過濾器內的意圖嗎?我試圖在過濾器中有一個重定向,它會導致一個無限的重定向循環,正如這裏所提到的:http://stackoverflow.com/questions/3954930/spring-security-3-0-how-do-i-specify-urls -to-其-A-自定義過濾器適用。將在SO中發佈一個單獨的問題。 – Jonathan 2013-07-25 03:43:06
有點晚了,但希望這可以幫助別人找到這個鏈接。如果您使用自定義的UserDetailsService,則可以將User對象的credentialsNonExpired設置爲false,例如,在該字段設置爲true之前,不允許訪問任何安全內容。
基本上,當你有密碼到期時,你將在你的用戶模型(passwordExpired也許)中設置一個字段,當你的UserDetailsService提取用戶時,你的UserDetailsService將使用該值來設置credentialsNonExpired。
然後,您需要做的就是將一些配置添加到您的applicationContext-security.xml以設置驗證異常映射。這將允許您捕獲過期憑據引發的異常,並強制用戶重置密碼頁面。您還可以使用類似的方法捕獲鎖定和禁用的帳戶。該配置示例如下所示:
的applicationContext-security.xml文件
<beans:bean id="exceptionTranslationFilter" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<beans:property name="exceptionMappings">
<beans:props>
<beans:prop key="org.springframework.security.authentication.BadCredentialsException">/login_error</beans:prop>
<beans:prop key="org.springframework.security.authentication.CredentialsExpiredException">/password_expired</beans:prop>
<beans:prop key="org.springframework.security.authentication.LockedException">/locked</beans:prop>
<beans:prop key="org.springframework.secuirty.authentication.DisabledException">/disabled</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<http use-expressions="true">
<!-- ADD BLACKLIST/WHITELIST URL MAPPING -->
<form-login login-page="/login" default-target-url="/" authentication-failure-handler-ref="exceptionTranslationFilter" />
</http>
然後,只需確保你有你的控制器設置服務與適當的內容這些鏈接。
此解決方案有一個缺點,即在用戶通過身份驗證之前已檢查用戶憑證NonExpired,因此您發現用戶憑證是過期給未經認證的用戶(例如攻擊者)。我想這樣的信息並不那麼重要,但我仍然發現rodrigoap解決方案更好。 – 2014-04-30 08:49:25
非常有用的答案表格jyore,這正是我一直在尋找的。如果您正在使用實現UserDetailsService
的自定義類,則可以在applicationContext.xml
中將上述bean定義與以上bean定義一起使用。一件事是,根據您的CML頭,你可能需要使用<bean ....
或<prop ...
代替<beans:bean ...
或<beans:prop ...
import ......
@Service("userService")
public class UserDetailsServiceImpl implements UserDetailsService {
private static Logger logger = LoggerFactory
.getLogger(UserDetailsServiceImpl.class);
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException , CredentialsExpiredException ,BadCredentialsException ,
LockedException , DisabledException , UsernameNotFoundException
{
User user = userDao.getUserByUsername(username);
System.out.println("User Found");
if(user == null){
// System.out.println("User Not Found");
logger.error("User Not Found");
throw new UsernameNotFoundException(username + " is not found.");
}
if(user.isEnabled() == false){
// System.out.println("User not enabled");
logger.error("User not enabled");
throw new DisabledException("User not enabled");
}
if(user.isLocked() == true){
//System.out.println("User is Locked");
logger.error("User is Locked");
throw new LockedException("User is Locked");
}
if(user.isPasswordExpired() == true){
// System.out.println("Password Expired");
logger.error("Password Expired");
throw new CredentialsExpiredException("Password Expired");
}
return user;
}
}
問題是在檢查密碼之前調用UserDetailsService。 – 2017-05-29 14:55:06
感謝。我可以很容易地完成第一部分,但不確定「將用戶重定向到...使用SavedRequestAwareAuthenticationSuccessHandler」的含義。我如何重定向到一個處理程序? – DrewEaster 2010-07-26 15:35:00
@dewzilla:我添加了它的樣子(使用Spring MVC控制器進行密碼更改,未經測試)。 – axtavt 2010-07-26 16:49:05
事實上,在認證成功處理程序中檢查密碼到期是違反直覺的,不是嗎?如果密碼過期,您應該無法進行身份驗證。檢查@jyore提供的答案。 – Octavian 2013-04-30 10:26:14