我对Spring很新。
我正在使用Spring MVC的4.3.9.RELEASE版本,4.2.3.RELEASE的Spring Security。
我使用spring的内置登录和一点定制,这是我的配置
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService myUserService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(myUserService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.rememberMe()
.alwaysRemember(true)
.and()
.logout()
.permitAll();
}
}
为什么用户登录成功后可以访问登录页面?我试着从与我相同的问题中学习,但没有一个与我合作。
此解决方案不适用于我:
<sec:authorize access="isAuthenticated()">
<% response.sendRedirect(request.getContextPath()); %>
</sec:authorize>
我正在使用Apache Tiles,我有is_authenticated.jsp与该部分。这是tiles.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<definition name="base" template="/WEB-INF/layouts/page.jsp">
<put-attribute name="pageHeader" value="/WEB-INF/layouts/page_header.jsp"></put-attribute>
<put-attribute name="pageFooter" value="/WEB-INF/layouts/page_footer.jsp"></put-attribute>
</definition>
<definition name="login" extends="base">
<put-attribute name="isAuthenticated" value="/WEB-INF/views/is_authenticated.jsp"></put-attribute>
<put-attribute name="pageBody" value="/WEB-INF/views/login.jsp"></put-attribute>
</definition>
<definition name="home" extends="base">
<put-attribute name="isAuthenticated" value=""></put-attribute>
<put-attribute name="pageBody" value="/WEB-INF/views/home.jsp"></put-attribute>
...
</tiles-definitions>
这是page.jsp
<!DOCTYPE>
<html>
<head>
<t:insertAttribute name="isAuthenticated"></t:insertAttribute>
...
</head>
<body>
<!-- Page Layout HTML -->
<header id="pageHeader">
<t:insertAttribute name="pageHeader"></t:insertAttribute>
</header>
<main id="pageBody">
<t:insertAttribute name="pageBody"></t:insertAttribute>
</main>
...
</body>
</html>
is_authenticated.jsp包含并呈现但它不起作用,只有当我将块放在page.jsp本身内时才会起作用,如你所见,它看起来不对,但是当它包含在另一个jsp文件中时它不起作用。
另一个解决方案,从登录控制器处理此问题,但这在我的情况下不可用,因为我没有使用任何控制器来处理登录过程。我该怎么办?自定义登录控制器比Spring中的默认登录控制器更安全吗?
UPDATE1
我试图使用spring的默认登录功能:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService myUserService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(myUserService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin();
}
}
但我发现登录成功后,用户仍然可以访问登录页面。所以我猜我需要在LoginController中有一个方法来完成这个。
我想我找到了答案。
由于我将configure
方法配置为:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.rememberMe()
.alwaysRemember(true)
.and()
.logout()
.permitAll();
}
我应该在我的addViewControllers
实施中有WebMvcConfigurerAdapter
。所以我试图删除这个方法,而是创建一个LoginController,它只有login()
方法,用于处理重定向的GET
请求,如果用户通过身份验证。
@Controller
public class LoginController {
@RequestMapping(value="/login", method=GET)
public String login(Principal principal) {
return principal == null ? "login" : "redirect:/";
}
}
我有同样的问题,我通过使用access()
方法解决了它:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/login", "/signup", "/")
.access("hasRole('ANONYMOUS')")
.antMatchers("/test").access("permitAll()")
.antMatchers("/user/**").access("hasRole('ADMIN')")
.anyRequest().authenticated()
.antMatchers()
.access("hasRole('USER')").anyRequest().fullyAuthenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.successHandler(loginSuccessHandler()).permitAll()
.failureHandler(loginFailureHandler())
.and()
.logout()
.permitAll()
.logoutSuccessUrl("/");
}
private AuthenticationSuccessHandler loginSuccessHandler() {
return (request, response, authentication) ->{
response.sendRedirect("/home");
};
}
private AuthenticationFailureHandler loginFailureHandler() {
return (request, response, exception) -> {
response.sendRedirect("/");
};
}