2017-09-24 56 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拯救我的一天!

    相關問題