Helpex - Trao đổi & giúp đỡ Đăng nhập

Spring Security trong MVC 4 Sử dụng Spring Boot

Vâng, sau một thời gian khá dài, gần một năm, tôi đã sẵn sàng để xuất bản bài viết tiếp theo của tôi ở đây. Đây là một bài đăng đã quá hạn lâu và được yêu cầu cao. Tôi sẽ viết về cách bảo mật ứng dụng web Spring MVC 4 bằng Spring Security. Tôi sẽ sử dụng Spring Boot để xây dựng một ứng dụng nhanh chóng và không cần cấu hình. Tôi đã viết chi tiết về cách sử dụng Spring Boot trong ứng dụng Spring Data Rest tại đây .

Spring Boot có thể được sử dụng với các công cụ xây dựng như Maven hoặc Gradle. Các công cụ xây dựng này giúp bạn chia sẻ các bình giữa các ứng dụng khác nhau, xây dựng ứng dụng của bạn và tạo báo cáo. Tôi sẽ sử dụng cùng một ứng dụng được cung cấp trong hướng dẫn bắt đầu bảo mật mùa xuân  nhưng với JSP để xem.

TẢI XUỐNG

Thiết lập dự án với Spring Boot

1. Đi tới New -> Maven Project trong Eclipse,

Spring Security trong MVC 4 Sử dụng Spring Boot

2. Nhấp vào Tiếp theo -> Kiểm tra Tạo một dự án đơn giản -> Cung cấp vị trí không gian làm việc

Spring Security trong MVC 4 Sử dụng Spring Boot

3. Nhấp vào Tiếp theo -> Trong lựa chọn kiểu mẫu, chọn maven-archetype-webapp

Spring Security trong MVC 4 Sử dụng Spring Boot

và sau đó cung cấp chi tiết nhỏ về dự án trong màn hình tiếp theo,
Spring Security trong MVC 4 Sử dụng Spring Boot
Khi chúng tôi thực hiện xong dự án ở cuối hướng dẫn này, cấu trúc dự án sẽ trông như thế này,
Spring Security trong MVC 4 Sử dụng Spring Boot

4. Hãy để chúng tôi tạo một ứng dụng mvc mùa xuân rất đơn giản và bảo mật nó bằng cách sử dụng bảo mật mùa xuân. Viết lại tệp pom.xml của bạn để khớp với những gì được cung cấp bên dưới.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.programmingfree</groupId>
    <artifactId>pf-securing-web</artifactId>
    <version>0.1.0</version>
 <packaging>war</packaging>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.5.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <scope>provided</scope>
  </dependency>
  <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
  </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>

</project>


 - Nếu bạn nhận thấy trong pom.xml ở trên, chúng tôi đang thêm hai phụ thuộc được đưa ra bên dưới vì chúng tôi đang sử dụng JSP cho các khung nhìn.

<sự phụ thuộc>

    <groupId> org.apache.tomcat.embed </groupId>

    <artifactId> tomcat-nhúng-jasper </artifactId>

    <scope> được cung cấp </scope>

</dependency>

<sự phụ thuộc>

    <groupId> javax.servlet </groupId>

    <artifactId> jstl </artifactId>

</dependency>


- Mặc dù chúng tôi sử dụng "chiến tranh" để đóng gói, chúng tôi vẫn có thể thực hiện nó. Điều này được thực hiện bởi 'spring-boot-maven-plugin'.

- Chúng tôi có 'spring-boot-starter-security' là một trong những phần phụ thuộc và điều này sẽ khởi động mọi thứ liên quan đến bảo mật cho chúng tôi.

5. Tạo từng khung nhìn bên trong WEB-INF \ jsp.

src \ main \ webapp \ WEB-INF \ jsp \ home.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
    <head>
        <title>Spring Security Example - ProgrammingFree</title>
    </head>
    <body>
        <h1>Welcome!</h1>

        <p>Click <a href="<spring:url value='/hello' />">here</a> to see a greeting.</p>
    </body>
</html>

Đây là một trang chào mừng đơn giản và nó sẽ không được bảo mật. Trang này có liên kết đến trang chào mừng (hello.jsp) chỉ có thể được truy cập sau khi được xác thực.

src \ main \ webapp \ WEB-INF \ jsp \ hello.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        <h1>Hello <b><c:out value="${pageContext.request.remoteUser}"/></b> </h1>
        <form action="/logout" method="post">
            <input type="submit" value="Sign Out"/>
            <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
        </form>
    </body>
</html>

Trang này hiển thị thông báo chào mừng với tên của người dùng đã đăng nhập và chỉ những người dùng đã xác thực mới có thể truy cập được.

src \ main \ webapp \ WEB-INF \ jsp \ login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
    <head>
        <title>Spring Security Example </title>
    </head>
    <body>
    <c:if test="${param.error ne null}">
        <div>
            Invalid username and password.
        </div>
     </c:if>
         <c:if test="${param.logout ne null}">
        <div>
            You have been logged out.
        </div>
      </c:if>
                <form action="/login" method="post">
            <div><label> User Name : <input type="text" name="username"/> </label></div>
            <div><label> Password: <input type="password" name="password"/> </label></div>
            <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
            <div><input type="submit" value="Sign In"/></div>
        </form>
    </body>
</html>


Như tên của chính nó, trang này chứa biểu mẫu đăng nhập để người dùng gửi thông tin đăng nhập của họ.

6. Tạo ba lớp java bên trong một gói có tên là 'hello' với mã được đưa ra bên dưới.

src \ main \ java \ hello \ MvcConfig.java

package hello;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/home").setViewName("home");
        registry.addViewController("/").setViewName("home");
        registry.addViewController("/hello").setViewName("hello");
        registry.addViewController("/login").setViewName("login");
    }

    @Bean
 public InternalResourceViewResolver viewResolver() {
  InternalResourceViewResolver resolver = new InternalResourceViewResolver();
  resolver.setPrefix("/WEB-INF/jsp/");
  resolver.setSuffix(".jsp");
  return resolver;
 }

}

src \ main \ java \ hello \ WebSecurityConfig.java

package hello;

import org.springframework.beans.factory.annotation.Autowired;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }
}

src \ main \ java \ hello \ Application.java


package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) throws Throwable {
        SpringApplication.run(Application.class, args);
    }
}

Đó là tất cả! Bây giờ để chạy ứng dụng, nhấp chuột phải vào dự án, chạy dưới dạng Maven Build với mục tiêu, cài đặt sạch Spring-boot: run


Thao tác này sẽ cài đặt dự án với tất cả các phụ thuộc cần thiết, tạo tệp chiến tranh trong thư mục đích và khởi động máy chủ tomcat nhúng được cung cấp bởi khởi động mùa xuân. Mở trình duyệt và nhấn http: // localhost: 8080 / để xem trang chủ,
Spring Security trong MVC 4 Sử dụng Spring Boot

Khi nhấp vào liên kết cho tin nhắn chào mừng, người dùng sẽ được chuyển hướng đến trang đăng nhập như hình dưới đây,
Spring Security trong MVC 4 Sử dụng Spring Boot
Như bạn có thể thấy, trang đăng nhập cung cấp một biểu mẫu đơn giản ghi lại tên người dùng và mật khẩu và đăng chúng lên "/ login". Như đã định cấu hình, Spring Security cung cấp một bộ lọc chặn yêu cầu đó và xác thực người dùng. Nếu người dùng không xác thực được, trang sẽ được chuyển hướng đến "/ login? Error" và trang của chúng tôi hiển thị thông báo lỗi thích hợp. Sau khi đăng xuất thành công, ứng dụng của chúng tôi được gửi đến "/ login? Logout" và trang của chúng tôi hiển thị thông báo thành công thích hợp.
Spring Security trong MVC 4 Sử dụng Spring Boot
Người dùng được chuyển hướng đến trang đăng nhập sau khi đăng xuất, với thông báo đăng xuất,
Spring Security trong MVC 4 Sử dụng Spring Boot
Nếu thông tin đăng nhập sai, người dùng được chuyển hướng đến trang đăng nhập với thông báo lỗi,
Spring Security trong MVC 4 Sử dụng Spring Boot
Để biết cách chạy trực tiếp dự án đã tải xuống, hãy xem video này,



Làm thế nào nó hoạt động

Trước tiên, hãy để tôi bắt đầu với thiết lập ứng dụng. Trong suốt quá trình thực hiện, chúng tôi không viết bất kỳ cấu hình xml nào và thậm chí cả web.xml cũng bị loại bỏ khi sử dụng Spring Boot. Hãy để tôi đi từng bước về cách Spring Boot thiết lập ứng dụng cho chúng ta,

1. Sau khi maven tải tất cả các thư viện cần thiết vào classpath (WEB-INF \ lib), Spring Boot sẽ xem xét classpath và đưa ra các giả định hợp lý về những gì bạn đang thiếu và thêm nó.

2. Spring Boot khởi chạy ứng dụng từ một lớp được chú thích bằng @SpringBootApplication, vì vậy trong ví dụ của chúng tôi, nó bắt đầu bằng 'Application.java'

@SpringBootApplication là một chú thích tiện lợi bổ sung tất cả những điều sau:

             - @Configuration gắn thẻ lớp như một nguồn định nghĩa bean cho ngữ cảnh ứng dụng.

             - @EnableAutoConfiguration yêu cầu Spring Boot bắt đầu thêm các bean dựa trên cài đặt classpath, các bean khác và các cài đặt thuộc tính khác nhau.

            - Thông thường, bạn sẽ thêm @EnableWebMvc cho ứng dụng Spring MVC, nhưng Spring Boot sẽ tự động thêm nó khi thấy spring-webmvc trên classpath. Thao tác này gắn cờ ứng dụng là một ứng dụng web và kích hoạt các hành vi chính như thiết lập DispatcherServlet.

           - @ComponentScan yêu cầu Spring tìm kiếm các thành phần, cấu hình và dịch vụ khác bên trong cùng một gói với nó. Trong trường hợp này, nó tìm kiếm tất cả các lớp bên trong gói 'hello'.

3. Trong khi gói 'hello' được quét, nó sẽ đi qua tất cả các lớp có @Configuration và sẽ đăng ký tất cả các cấu hình hiện có. Trong ví dụ của chúng tôi, chúng tôi có MvcConfig và WebSecurityConfig được chú thích bằng @Configuration
4. Lớp MvcConfig đăng ký các chế độ xem với các url và do đó hiển thị các ánh xạ url này đến các chế độ xem tương ứng. 

An ninh mùa xuân

Khi Spring-security xuất hiện trong classpath, Spring sẽ tự động bảo mật tất cả các điểm cuối HTTP bằng xác thực cơ bản. Để tùy chỉnh thêm cài đặt bảo mật, chẳng hạn như xác thực người dùng dựa trên các chi tiết được lưu trữ trong cơ sở dữ liệu hoặc chỉ xác thực các điểm cuối http cụ thể chứ không phải tất cả, v.v. bạn nên thiết lập cấu hình bảo mật. Trong ví dụ của chúng tôi, chúng tôi cung cấp xác thực trong bộ nhớ đơn giản cho tất cả các trang ngoại trừ trang chủ (home.jsp) và điều này được định cấu hình trong lớp WebSecurityConfig.

Lớp WebSecurityConfig được chú thích bằng @EnableWebMvcSecurity để kích hoạt hỗ trợ bảo mật web của Spring Security và cung cấp tích hợp Spring MVC. Nó cũng mở rộng WebSecurityConfigurerAdapter và ghi đè một số phương pháp của nó để thiết lập một số chi tiết cụ thể của cấu hình bảo mật web. Phương thức config (HttpSecurity) xác định đường dẫn URL nào nên được bảo mật và đường dẫn nào không nên. Cụ thể, các đường dẫn "/" và "/ home" được định cấu hình để không yêu cầu bất kỳ xác thực nào. Tất cả các đường dẫn khác phải được xác thực.

Khi người dùng đăng nhập thành công, họ sẽ được chuyển đến trang yêu cầu trước đó cần xác thực. Có một trang "/ đăng nhập" tùy chỉnh được chỉ định bởi loginPage () và mọi người đều được phép xem nó. Đối với phương thức config (AuthenticationManagerBuilder), nó thiết lập một kho lưu trữ người dùng trong bộ nhớ với một người dùng duy nhất. Người dùng đó được cấp tên người dùng là "người dùng", mật khẩu là "mật khẩu" và vai trò của "NGƯỜI DÙNG".

Cuối cùng, chúng tôi cần cung cấp cho người dùng một cách để hiển thị tên người dùng hiện tại và Đăng xuất. Cập nhật hello.html để chào người dùng hiện tại và chứa biểu mẫu "Đăng xuất" như được hiển thị bên dưới

Tấn công CSRF

Bạn có thể nhận thấy rằng tôi đã đặt loại đầu vào ẩn với name = "$ {_ csrf.parameterName}" và value = "$ {_ csrf.token}" trong trang đăng nhập và trang mà người dùng đăng xuất. Điều này là để bảo vệ ứng dụng khỏi các cuộc tấn công truy vấn yêu cầu chéo trang web (CSRF) .

Bảo vệ CSRF được bật theo mặc định với Cấu hình Java. Bạn cũng có thể vô hiệu hóa nó. Nếu bạn đang sử dụng thẻ Spring MVC <form: form>, CsrfToken sẽ tự động được đưa vào. Vì chúng tôi không sử dụng thẻ biểu mẫu Spring, tôi đã sử dụng đầu vào ẩn để gửi mã thông báo csrf đến máy chủ. Giải thích chi tiết và rất rõ ràng về hỗ trợ CSRF trong Spring MVC được cung cấp trong bài viết này .

BẢN GIỚI THIỆU

TẢI XUỐNG

Lưu ý: Tôi đã thêm tài nguyên tĩnh trong dự án demo để tạo kiểu và tôi đã loại trừ tài nguyên đó trong hướng dẫn vì mục đích đơn giản. Tôi sẽ viết về cách sử dụng tài nguyên tĩnh như javascript hoặc css, trong khi sử dụng Spring Security và Spring Boot trong một bài viết riêng.

10 hữu ích 0 bình luận 82k xem chia sẻ

Có thể bạn quan tâm

loading