【发布时间】:2019-07-27 14:14:44
【问题描述】:
我正在尝试将 thymeleaf、spring security 和 spring boot 一起运行,但我不确定如何将它们集成在一起,因为我在 spring security 阻止静态的 href 等方面遇到了一些问题。
问题是提交登录后它没有通过安全配置的成功处理程序,所以我认为视图没有正确映射。
SecurityConfig 如下所示:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LogManager.getLogger(SecurityConfig.class);
@Autowired
private LoggingAccessDeniedHandler accessDeniedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(
"/",
"/js/**",
"/css/**",
"/img/**",
"/webjars/**").permitAll()
.antMatchers("/user/**").hasRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.successHandler(myAuthenticationSuccessHandler())
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler);
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**","/vendor/**","/fonts/**");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
logger.info("configuring");
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("manager").password("password").roles("MANAGER");
}
@Bean
public AuthenticationSuccessHandler myAuthenticationSuccessHandler(){
logger.info("GOt into the thingie");
return new MySimpleUrlAuthenticationSuccessHandler();
}
}
class MySimpleUrlAuthenticationSuccessHandler
implements AuthenticationSuccessHandler {
private static final Logger logger = LogManager.getLogger(SecurityConfig.class);
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication)
throws IOException {
handle(request, response, authentication);
clearAuthenticationAttributes(request);
}
protected void handle(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException {
logger.info("got here");
String targetUrl = determineTargetUrl(authentication);
if (response.isCommitted()) {
logger.info(
"Response has already been committed. Unable to redirect to " + targetUrl);
return;
}
redirectStrategy.sendRedirect(request, response, targetUrl);
}
protected String determineTargetUrl(Authentication authentication) {
logger.info("got here in target");
boolean isUser = false;
boolean isAdmin = false;
Collection<? extends GrantedAuthority> authorities
= authentication.getAuthorities();
for (GrantedAuthority grantedAuthority : authorities) {
if (grantedAuthority.getAuthority().equals("ROLE_USER")) {
isUser = true;
break;
} else if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) {
isAdmin = true;
break;
}
}
if (isUser) {
return "/homepage.html";
} else if (isAdmin) {
return "/console.html";
} else {
throw new IllegalStateException();
}
}
protected void clearAuthenticationAttributes(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return;
}
session.removeAttribute
(WebAttributes.AUTHENTICATION_EXCEPTION);
}
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
}
控制器如下所示:
@RequestMapping(value = "/", method= RequestMethod.GET)
public String login(Model model){
return "login";
}
@RequestMapping(value = "/login", method= RequestMethod.GET)
public String loginSucc(Model model){
return "predictions";
}
在 src/main/resources/templates 下是:
从上图中可以看出,我在模板下拥有所有必需的 html 页面。 ** Predictions.html 是否也存在,只是未包含在屏幕截图中。 最后 login.html 看起来像这样:
<!-- Login Form -->
<form th:action="@{/login}" method="post">
<input type="text" id="login" class="fadeIn second" name="login" placeholder="login">
<input type="text" id="password" class="fadeIn third" name="login" placeholder="password">
<input type="submit" class="fadeIn fourth" value="Log In">
</form>
在获取登录页面并输入任何用户名和密码后,它会重定向到预测页面。它显然没有进行身份验证,因为没有检查用户名/密码,并且在预测页面中我打印出刚刚没有出现的用户名(空白)。我已根据下面的评论添加了 sn-p。但这并没有什么区别。
从“login.html”重定向后的预测页面: enter image description here
【问题讨论】:
-
POST 时到底发生了什么?
-
编辑了帖子以显示究竟发生了什么并添加了一张图片。它重定向到预测页面,但它没有通过身份验证,因为它显示登录?错误,但我可以看到预测页面。
标签: java rest spring-boot spring-security thymeleaf