我刚开始使用Spring Security进行身份验证的项目,该项目使用Java配置而不是XML。这是我的类SecurityConfig.java:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("kleber")
.password("123")
.roles("USER");
}
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/css/**", "/fonts/**", "/image/**", "/js/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/spring/index").permitAll()
.loginProcessingUrl("/spring/login").permitAll()
.usernameParameter("login")
.passwordParameter("senha")
.defaultSuccessUrl("/spring/home")
.failureUrl("/spring/erro-login")
.and()
.logout()
.logoutUrl("/spring/logout")
.logoutSuccessUrl("/spring/index").permitAll();
}
}
使用此配置,我可以访问登录页面,但在我通知我的证件(用户名和密码)后,系统返回到同一个登录页面,尽管通知的用户名和密码是正确的。
在SecurityConfig类中通知的所有URL都映射到此控制器中:
@Controller
@RequestMapping(value="spring")
public class SpringController {
@RequestMapping(value="index")
public ModelAndView index() {
ModelAndView mav = new ModelAndView();
mav.setViewName("index");
return mav;
}
@RequestMapping(value="home")
public ModelAndView home() {
ModelAndView mav = new ModelAndView();
mav.setViewName("home");
return mav;
}
@RequestMapping(value="doLogin", method=RequestMethod.POST)
public void doLogin(HttpServletRequest request, HttpServletResponse response) {
//
}
@RequestMapping(value="logout")
public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
request.getSession().invalidate();
response.sendRedirect(request.getContextPath());
}
}
我做错了什么?
- >仍与上述主题相关:
我需要实现这个' loginProcessingUrl',它以这种方式映射到我的控制器中:
@RequestMapping(value="doLogin", method=RequestMethod.POST)
public void doLogin(HttpServletRequest request, HttpServletResponse response) {
//
}
我已经在我的应用程序中有两个类,根据我读过的文章,这个过程是必要的,但我可能错了,也许我需要另一种方法:
SampleAuthenticationManager
public class SampleAuthenticationManager implements AuthenticationManager {
static final List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();
static
{
AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_USER"));
}
public Authentication authenticate(Authentication auth) throws AuthenticationException
{
if (auth.getName().equals(auth.getCredentials()))
{
return new UsernamePasswordAuthenticationToken(auth.getName(), auth.getCredentials(), AUTHORITIES);
}
throw new BadCredentialsException("Bad Credentials");
}
}
DefaultAuthenticationProcessingFilter
public class DefaultAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {
private static final String INTERCEPTOR_PROCESS_URL = "/spring/doLogin";
private static AuthenticationManager am = new SampleAuthenticationManager();
protected DefaultAuthenticationProcessingFilter() {
super(INTERCEPTOR_PROCESS_URL);
// TODO Auto-generated constructor stub
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
// TODO Auto-generated method stub
String login = request.getParameter("login");
String senha = request.getParameter("senha");
Authentication input = new UsernamePasswordAuthenticationToken(login, senha);
Authentication output = null;
try {
output = am.authenticate(input);
SecurityContextHolder.getContext().setAuthentication(output);
getSuccessHandler().onAuthenticationSuccess(request, response, output);
} catch (AuthenticationException failed) {
getFailureHandler().onAuthenticationFailure(request, response, failed);
}
return output;
}
}
在这种情况下,我应该如何从我的控制器实现doLogin方法?请注意,此时我正在使用inMemory身份验证,以便稍后扩展我的项目以使用数据库。
答案 0 :(得分:2)
好的,我设法解决了我的问题;它发生了我在SecurityConfig中通知的Url和我的观点中的Url's。我将来需要记住:在课堂上,总是使用//。在视图中,始终使用。
就我而言,观点是这样写的:
index.jsp - &gt;登录页面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:url value="/spring/login" var="loginUrl"/>
<form method="post" action="${loginUrl}">
usuário: <input type="text" name="login" size=20> <br/>
senha: <input type="password" name="senha" size=20> <br/>
<input type="submit" value="entrar"> <br/>
</form>
</body>
</html>
home.jsp - &gt; “命运”页面(仪表板):仅用于此项目状态的测试目的
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>
<c:out value="${pageContext.request.remoteUser}"/>
<a href="<c:out value="${pageContext.request.contextPath}/spring/logout"/>">Logout</a>
</h2>
</body>
</html>
SecurityConfig.java类的最终代码
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("kleber")
.password("123")
.roles("USER");
}
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/css/**", "/fonts/**", "/image/**", "/js/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/spring/index").permitAll()
.loginProcessingUrl("/spring/login").permitAll()
.usernameParameter("login")
.passwordParameter("senha")
.successHandler(new CustomAuthenticationSuccessHandler())
.failureHandler(new CustomAuthenticationFailureHandler())
.and()
.logout()
.logoutUrl("/spring/logout")
.logoutSuccessUrl("/spring/index").permitAll();
}
}