【发布时间】:2016-03-21 01:04:21
【问题描述】:
我最近切换到 Spring Security 来处理我的 Web 应用程序的登录、注销和基于角色的访问。我使用闪存消息来获取信息和错误消息,并希望在成功登录和注销后显示这样的消息。
在 JSP 文件中,这些消息使用以下代码显示:
<c:if test = "${not empty flashmessage_error}" >
<div class="alert alert-danger"><c:out value="${flashmessage_error}" />
</div>
</c:if>
<c:if test="${not empty flashmessage_info}" >
<div class="alert alert-info"><c:out value="${flashmessage_info}" />
</div>
</c:if>
为了在成功登录后显示一个 flash 消息,我定义了一个 custom LoginSuccessHandler,它将消息放入 FlashMap 并将重定向页面设置为主页:
public class FlashMessageAuthSuccessHandler extends
SavedRequestAwareAuthenticationSuccessHandler {
private String flashMessage = "Logged in!";
public void setFlashMessage(String flashMessage) {
this.flashMessage = flashMessage;
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws ServletException, IOException {
FlashMapManager flashMapManager = new SessionFlashMapManager();
FlashMap fm = new FlashMap();
fm.put(KeyConstants.FLASH_INFO_KEY, flashMessage);
flashMapManager.saveOutputFlashMap(fm, request, response);
setDefaultTargetUrl("/");
super.onAuthenticationSuccess(request, response, authentication);
}
}
我的 SecurityConfig 类如下所示:
@Configuration
@EnableWebSecurity(debug = false)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private MessageSource messageSource;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
/*
* HttpSecurity allows configuring web based security for specific HTTP requests
* By default it will be applies to all request, but can be restricted
* using requestMatcher
* @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//super.configure(http);
http
.authorizeRequests()
.antMatchers("/", "/css/**", "/js/**", "/images/**", "/about", "/error").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.usernameParameter("j_username")
.passwordParameter("j_password")
.loginPage("/login")
.loginProcessingUrl("/ssprocesslogin") //post request
// .defaultSuccessUrl("/") //cannot possibly used in combination with successHandler?
.successHandler(loginSuccesHandler())
.failureUrl("/login?" + KeyConstants.FLASH_ERROR_KEY + "=Verkeerde login message aanpassen") //default is /login?error
.permitAll()
.and()
.rememberMe()
.tokenValiditySeconds(2592000) //one month
.rememberMeParameter("j_rememberme")
.key("wIllekEUrigeSleutteL")
.userDetailsService(userDetailsService)
.and()
.logout()
.logoutUrl("/logout") //default is /logout
// .logoutSuccessUrl("/") //default is /login?logout
.logoutSuccessHandler(new FlashMessageLogoutSuccessHandler())
.invalidateHttpSession(true) //true is the default
;
}
@Bean
public FlashMessageAuthSuccessHandler loginSuccesHandler() {
FlashMessageAuthSuccessHandler handler = new FlashMessageAuthSuccessHandler();
//THIS DOES NOT WORK!!!!!
String loginSuccessMessage = messageSource.getMessage("flashmessage.loginsuccesful", null, "not found", null);
handler.setFlashMessage(loginSuccessMessage);
return handler;
}
@Bean
public AuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider dap = new DaoAuthenticationProvider();
dap.setUserDetailsService(userDetailsService);
dap.setPasswordEncoder(passwordEncoder());
return dap;
}
@Bean
public ShaPasswordEncoder passwordEncoder() {
return new ShaPasswordEncoder(256);
}
}
但没有显示来自 messages.properties 文件的正确消息。相反,字符串“未找到”在登录后显示为闪存消息。 在下面的行中,我尝试使用注入的 MessageSource 通过消息键查找消息,但显然没有找到,并且显示了回退消息:
String loginSuccessMessage = messageSource.getMessage("flashmessage.loginsuccesful", null, "not found", null);
messageSource bean 在 MvcConfig 文件中定义,如下所示,当用于在 JSP 文件中显示消息时工作正常,但它似乎无法在 Spring Security 配置文件中自动装配以获得所需的 Flash 消息。
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
有什么想法可以做到这一点吗?
【问题讨论】:
标签: spring-mvc spring-security