2017-09-24 57 views
0

我已经开发出一种应用(SpringBootWebSecurity)与ThymeLeafGradle。用户可以使用thymeleaf表单登录。为什么用户无法在春季启动应用程序登录?

然后,我开发了另一种新的应用程序(SpringBootJSP)维持先前的结构(SpringBootWebSecurity),但这个时候,我只是改变了构建工具(maven)和视图(jsp)以适当的依赖关系。两个应用程序的数据库和其他凭证保持不变。 (多个)用户是/是无法与jsp应用登录。

结构

![application structures][1] 

LoginCtroller.java

package com.maxpro.controller; 

import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 


@Controller 
public class LoginController { 

    private final String BASE_PATH = "/login"; 
    private final String LOGIN_PAGE = BASE_PATH + "/login"; 

    @RequestMapping("/login") 
    public String login() { 
     return LOGIN_PAGE; 
    } 

} 

视图

login.html

<!DOCTYPE html> 
<html lang="en" 
     xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" 
     xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3" 
> 
<head> 
    <title>Login</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
    <meta name="viewport" content="width=device-width, initial-scale=1"/> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 
    <link th:href="@{/css/admin/admin.css}" rel="stylesheet"/> 

</head> 

<body> 
<div class="container"> 

    <div class="alert alert-danger" th:if="${param.error}"> 
     <strong>Invalid username or password or both.</strong> 
    </div> 

    <form class="form-signin" th:action="@{/login}" method="post"> 
     <h2 class="form-signin-heading text-center">sign in</h2> 
     <input type="text" id="inputName" name="username" class="form-control" placeholder="Username" 
       required="required" autofocus="autofocus"/> 
     <input type="password" id="inputPassword" name="password" class="form-control" placeholder="Password" 
       required="required"/> 
     <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> 
    </form> 

</div> <!-- /container --> 
</body> 
</html> 

login.jsp

<!DOCTYPE html> 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 

<html lang="en"> 
<head> 
    <title>Login</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
    <meta name="viewport" content="width=device-width, initial-scale=1"/> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 

    <!-- home.css --> 
    <link rel="stylesheet" href="<c:url value = "/css/admin/admin.css"/>"/> 
    <!-- /home.css --> 

</head> 

<body> 
<div class="container"> 

    <c:if test="${param.error}"> 
     <div class="alert alert-danger"> 
      <strong>Invalid username or password or both.</strong> 
     </div> 
    </c:if> 

    <form class="form-signin" action="<c:url value="/login"/>" method="post"> 
     <h2 class="form-signin-heading text-center">sign in</h2> 
     <input type="text" id="inputName" name="username" class="form-control" placeholder="Username" 
       required="required" autofocus="autofocus"/> 
     <input type="password" id="inputPassword" name="password" class="form-control" placeholder="Password" 
       required="required"/> 
     <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> 
    </form> 

</div> <!-- /container --> 
</body> 
</html> 

WebSecurityConfigurer.java & WebUserDetailsS​​ervice.java(这些类用于propcess用户登录)

WebSecurityConfigurer.java

package com.maxpro.configuration.security; 

import com.maxpro.repository.UserRepository; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 
import org.springframework.security.crypto.password.PasswordEncoder; 
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 


@Configuration 
@EnableWebSecurity 
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private UserRepository userRepository; 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userDetailsServiceBean()).passwordEncoder(passwordEncoder()); 
    } 

    @Override 
    public UserDetailsService userDetailsServiceBean() throws Exception { 
     return new WebUserDetailsService(userRepository); 
    } 

    @Bean 
    public PasswordEncoder passwordEncoder() { 
     return new BCryptPasswordEncoder(); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
       .authorizeRequests() 
        .antMatchers("/css/**", "/img/**", "/js/**").permitAll() 
        .antMatchers("/", "/home").permitAll() 
        .antMatchers("/admin/**").hasAuthority("ROLE_ADMIN") 
        .antMatchers("/user/**").hasAuthority("ROLE_USER") 
        .anyRequest().authenticated() 
       .and() 
        .formLogin() 
         .loginPage("/login") 
          .usernameParameter("username").passwordParameter("password").permitAll() 
       .and() 
        .logout() 
         .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) 
         .logoutSuccessUrl("/") 
       .and() 
        .exceptionHandling().accessDeniedPage("/access-denied") 
       .and() 
        .sessionManagement() 
//    .and() 
//     .csrf(); 
     ; 
    } 

} 

WebUserDetailsService.java

package com.maxpro.configuration.security; 

import com.maxpro.entity.Role; 
import com.maxpro.entity.User; 
import com.maxpro.repository.UserRepository; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.security.core.GrantedAuthority; 
import org.springframework.security.core.authority.SimpleGrantedAuthority; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 

import javax.transaction.Transactional; 
import java.util.HashSet; 
import java.util.Set; 


@Transactional 
public class WebUserDetailsService implements UserDetailsService { 

    @Autowired 
    private UserRepository userRepository; 

    public WebUserDetailsService(UserRepository userRepository) { 
     this.userRepository = userRepository; 
    } 

    @Override 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
     try { 
      User user = userRepository.findByUserName(username); 
      if (user == null) { 
       return null; 
      } 
      return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(), getAuthorities(user)); 
     } catch (Exception e) { 
      throw new UsernameNotFoundException("User not found"); 
     } 
    } 

    private Set<GrantedAuthority> getAuthorities(User user) { 
     Set<GrantedAuthority> authorities = new HashSet<>(); 
     for (Role role : user.getRoles()) { 
      GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getName()); 
      authorities.add(grantedAuthority); 
     } 
     return authorities; 
    } 

} 

application.properties

SpringBootWebSecurity应用:

#configurations 
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect 
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext 

#initializations 
spring.jpa.hibernate.ddl-auto=update 
spring.jpa.show-sql=false 

#credentials 
spring.datasource.driver-class-name=com.mysql.jdbc.Driver 
spring.datasource.url=jdbc:mysql://localhost:3306/spring_boot_security 
spring.datasource.username=root 
spring.datasource.password=ENC(fwPDBYsbkbHVwxDGEsutsQ==) 
spring.datasource.schema=classpath:/data/schema.sql 

SpringBootJSP应用下面的行的情况下加入:

spring.mvc.view.prefix: /WEB-INF/jsp 
spring.mvc.view.suffix: .jsp 

application.message: Hello World!! 

. 
. 
. 

## following line commented 
#spring.datasource.schema=classpath:/data/schema.sql 

观测

在上WebUserDetailsService.javaSpringBootWebSecurity命中登录表单的情况下。在另一方面,SpringBootJSP不能这样做。

问题

这究竟是为什么在SpringBootJSP情况?

项目位置

  1. https://github.com/engrjislam/SpringBootWebSecurity
  2. https://github.com/engrjislam/SpringBootJSP

回答

0

其实csrf是登录/注销一个UESR到网站的事实。我要么 -

  1. 禁用csrf

...或...

  • 添加csrf令牌来登录表单如下

    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 
    
  • Here的想法是共享的。感谢@Ken Bekov和@agthumoe拯救我的一天!

    相关问题