我使用Spring Security的应用程序不会超出登录页面

时间:2014-03-30 00:25:16

标签: java spring spring-mvc spring-security

我刚开始使用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身份验证,以便稍后扩展我的项目以使用数据库。

1 个答案:

答案 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&aacute;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();
    }

}